Completed
Push — master ( fdfefe...605692 )
by cam
01:07
created
ecrire/maj/2021.php 1 patch
Indentation   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -19,15 +19,15 @@
 block discarded – undo
19 19
  * @package SPIP\Core\SQL\Upgrade
20 20
  **/
21 21
 if (!defined('_ECRIRE_INC_VERSION')) {
22
-	return;
22
+    return;
23 23
 }
24 24
 
25 25
 $GLOBALS['maj'][2021_02_18_00] = [
26
-	['sql_alter', "TABLE spip_auteurs CHANGE imessage imessage VARCHAR(3) DEFAULT '' NOT NULL" ],
27
-	['sql_updateq', 'spip_auteurs', ['imessage' => 'oui'], "imessage != 'non' OR imessage IS NULL" ],
26
+    ['sql_alter', "TABLE spip_auteurs CHANGE imessage imessage VARCHAR(3) DEFAULT '' NOT NULL" ],
27
+    ['sql_updateq', 'spip_auteurs', ['imessage' => 'oui'], "imessage != 'non' OR imessage IS NULL" ],
28 28
 ];
29 29
 
30 30
 $GLOBALS['maj'][2022_02_23_02] = [
31
-	['sql_alter', "TABLE spip_auteurs ADD backup_cles mediumtext DEFAULT '' NOT NULL" ],
32
-	['sql_delete', 'spip_meta', "nom='secret_du_site'" ],
31
+    ['sql_alter', "TABLE spip_auteurs ADD backup_cles mediumtext DEFAULT '' NOT NULL" ],
32
+    ['sql_delete', 'spip_meta', "nom='secret_du_site'" ],
33 33
 ];
Please login to merge, or discard this patch.
ecrire/action/inscrire_auteur.php 1 patch
Indentation   +238 added lines, -238 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
 
22 22
 
23 23
 if (!defined('_ECRIRE_INC_VERSION')) {
24
-	return;
24
+    return;
25 25
 }
26 26
 
27 27
 
@@ -44,70 +44,70 @@  discard block
 block discarded – undo
44 44
  * @return array|string
45 45
  */
46 46
 function action_inscrire_auteur_dist($statut, $mail_complet, $nom, $options = []) {
47
-	if (!is_array($options)) {
48
-		$options = ['id' => $options];
49
-	}
50
-
51
-	if (function_exists('test_inscription')) {
52
-		$f = 'test_inscription';
53
-	} else {
54
-		$f = 'test_inscription_dist';
55
-	}
56
-	$desc = $f($statut, $mail_complet, $nom, $options);
57
-
58
-	// erreur ?
59
-	if (!is_array($desc)) {
60
-		return _T($desc);
61
-	}
62
-
63
-	include_spip('base/abstract_sql');
64
-	$res = sql_select('statut, id_auteur, login, email, nom', 'spip_auteurs', 'email=' . sql_quote($desc['email']));
65
-	// erreur ?
66
-	if (!$res) {
67
-		return _T('titre_probleme_technique');
68
-	}
69
-
70
-	$row = sql_fetch($res);
71
-	sql_free($res);
72
-	if ($row) {
73
-		if (isset($options['force_nouveau']) and $options['force_nouveau'] == true) {
74
-			$desc['id_auteur'] = $row['id_auteur'];
75
-			$desc = inscription_nouveau($desc);
76
-		} else {
77
-			$desc = $row;
78
-		}
79
-	} else // s'il n'existe pas deja, creer les identifiants
80
-	{
81
-		$desc = inscription_nouveau($desc);
82
-	}
83
-
84
-	// erreur ?
85
-	if (!is_array($desc)) {
86
-		return $desc;
87
-	}
88
-
89
-
90
-	// generer le mot de passe (ou le refaire si compte inutilise)
91
-	$desc['pass'] = creer_pass_pour_auteur($desc['id_auteur']);
92
-
93
-	// attribuer un jeton pour confirmation par clic sur un lien
94
-	$desc['jeton'] = auteur_attribuer_jeton($desc['id_auteur']);
95
-
96
-	// charger de suite cette fonction, pour ses utilitaires
97
-	$envoyer_inscription = charger_fonction('envoyer_inscription', '');
98
-	[$sujet, $msg, $from, $head] = $envoyer_inscription($desc, $nom, $statut, $options);
99
-
100
-	$notifications = charger_fonction('notifications', 'inc');
101
-	notifications_envoyer_mails($mail_complet, $msg, $sujet, $from, $head);
102
-
103
-	// Notifications
104
-	$notifications(
105
-		'inscription',
106
-		$desc['id_auteur'],
107
-		['nom' => $desc['nom'], 'email' => $desc['email']]
108
-	);
109
-
110
-	return $desc;
47
+    if (!is_array($options)) {
48
+        $options = ['id' => $options];
49
+    }
50
+
51
+    if (function_exists('test_inscription')) {
52
+        $f = 'test_inscription';
53
+    } else {
54
+        $f = 'test_inscription_dist';
55
+    }
56
+    $desc = $f($statut, $mail_complet, $nom, $options);
57
+
58
+    // erreur ?
59
+    if (!is_array($desc)) {
60
+        return _T($desc);
61
+    }
62
+
63
+    include_spip('base/abstract_sql');
64
+    $res = sql_select('statut, id_auteur, login, email, nom', 'spip_auteurs', 'email=' . sql_quote($desc['email']));
65
+    // erreur ?
66
+    if (!$res) {
67
+        return _T('titre_probleme_technique');
68
+    }
69
+
70
+    $row = sql_fetch($res);
71
+    sql_free($res);
72
+    if ($row) {
73
+        if (isset($options['force_nouveau']) and $options['force_nouveau'] == true) {
74
+            $desc['id_auteur'] = $row['id_auteur'];
75
+            $desc = inscription_nouveau($desc);
76
+        } else {
77
+            $desc = $row;
78
+        }
79
+    } else // s'il n'existe pas deja, creer les identifiants
80
+    {
81
+        $desc = inscription_nouveau($desc);
82
+    }
83
+
84
+    // erreur ?
85
+    if (!is_array($desc)) {
86
+        return $desc;
87
+    }
88
+
89
+
90
+    // generer le mot de passe (ou le refaire si compte inutilise)
91
+    $desc['pass'] = creer_pass_pour_auteur($desc['id_auteur']);
92
+
93
+    // attribuer un jeton pour confirmation par clic sur un lien
94
+    $desc['jeton'] = auteur_attribuer_jeton($desc['id_auteur']);
95
+
96
+    // charger de suite cette fonction, pour ses utilitaires
97
+    $envoyer_inscription = charger_fonction('envoyer_inscription', '');
98
+    [$sujet, $msg, $from, $head] = $envoyer_inscription($desc, $nom, $statut, $options);
99
+
100
+    $notifications = charger_fonction('notifications', 'inc');
101
+    notifications_envoyer_mails($mail_complet, $msg, $sujet, $from, $head);
102
+
103
+    // Notifications
104
+    $notifications(
105
+        'inscription',
106
+        $desc['id_auteur'],
107
+        ['nom' => $desc['nom'], 'email' => $desc['email']]
108
+    );
109
+
110
+    return $desc;
111 111
 }
112 112
 
113 113
 
@@ -130,23 +130,23 @@  discard block
 block discarded – undo
130 130
  *
131 131
  */
132 132
 function test_inscription_dist($statut, $mail, $nom, $options) {
133
-	include_spip('inc/filtres');
134
-	if (!$r = email_valide($mail)) {
135
-		return 'info_email_invalide';
136
-	}
137
-	$nom = trim(corriger_caracteres($nom));
138
-	$res = ['email' => $r, 'nom' => $nom, 'prefs' => $statut];
139
-	if (isset($options['login'])) {
140
-		$login = trim(corriger_caracteres($options['login']));
141
-		if ((strlen($login) >= _LOGIN_TROP_COURT) and (strlen($nom) <= 64)) {
142
-			$res['login'] = $login;
143
-		}
144
-	}
145
-	if (!isset($res['login']) and ((strlen($nom) < _LOGIN_TROP_COURT) or (strlen($nom) > 64))) {
146
-		return 'ecrire:info_login_trop_court';
147
-	}
148
-
149
-	return $res;
133
+    include_spip('inc/filtres');
134
+    if (!$r = email_valide($mail)) {
135
+        return 'info_email_invalide';
136
+    }
137
+    $nom = trim(corriger_caracteres($nom));
138
+    $res = ['email' => $r, 'nom' => $nom, 'prefs' => $statut];
139
+    if (isset($options['login'])) {
140
+        $login = trim(corriger_caracteres($options['login']));
141
+        if ((strlen($login) >= _LOGIN_TROP_COURT) and (strlen($nom) <= 64)) {
142
+            $res['login'] = $login;
143
+        }
144
+    }
145
+    if (!isset($res['login']) and ((strlen($nom) < _LOGIN_TROP_COURT) or (strlen($nom) > 64))) {
146
+        return 'ecrire:info_login_trop_court';
147
+    }
148
+
149
+    return $res;
150 150
 }
151 151
 
152 152
 
@@ -159,33 +159,33 @@  discard block
 block discarded – undo
159 159
  * @return mixed|string
160 160
  */
161 161
 function inscription_nouveau($desc) {
162
-	if (!isset($desc['login']) or !strlen($desc['login'])) {
163
-		$desc['login'] = test_login($desc['nom'], $desc['email']);
164
-	}
162
+    if (!isset($desc['login']) or !strlen($desc['login'])) {
163
+        $desc['login'] = test_login($desc['nom'], $desc['email']);
164
+    }
165 165
 
166
-	$desc['statut'] = 'nouveau';
167
-	include_spip('action/editer_auteur');
168
-	if (isset($desc['id_auteur'])) {
169
-		$id_auteur = $desc['id_auteur'];
170
-	} else {
171
-		$id_auteur = auteur_inserer();
172
-	}
166
+    $desc['statut'] = 'nouveau';
167
+    include_spip('action/editer_auteur');
168
+    if (isset($desc['id_auteur'])) {
169
+        $id_auteur = $desc['id_auteur'];
170
+    } else {
171
+        $id_auteur = auteur_inserer();
172
+    }
173 173
 
174
-	if (!$id_auteur) {
175
-		return _T('titre_probleme_technique');
176
-	}
174
+    if (!$id_auteur) {
175
+        return _T('titre_probleme_technique');
176
+    }
177 177
 
178
-	$desc['lang'] = $GLOBALS['spip_lang'];
178
+    $desc['lang'] = $GLOBALS['spip_lang'];
179 179
 
180
-	include_spip('inc/autoriser');
181
-	// lever l'autorisation pour pouvoir modifier le statut
182
-	autoriser_exception('modifier', 'auteur', $id_auteur);
183
-	auteur_modifier($id_auteur, $desc);
184
-	autoriser_exception('modifier', 'auteur', $id_auteur, false);
180
+    include_spip('inc/autoriser');
181
+    // lever l'autorisation pour pouvoir modifier le statut
182
+    autoriser_exception('modifier', 'auteur', $id_auteur);
183
+    auteur_modifier($id_auteur, $desc);
184
+    autoriser_exception('modifier', 'auteur', $id_auteur, false);
185 185
 
186
-	$desc['id_auteur'] = $id_auteur;
186
+    $desc['id_auteur'] = $id_auteur;
187 187
 
188
-	return $desc;
188
+    return $desc;
189 189
 }
190 190
 
191 191
 
@@ -202,27 +202,27 @@  discard block
 block discarded – undo
202 202
  * @return string
203 203
  */
204 204
 function test_login($nom, $mail) {
205
-	include_spip('inc/charsets');
206
-	$nom = strtolower(translitteration($nom));
207
-	$login_base = preg_replace('/[^\w\d_]/', '_', $nom);
208
-
209
-	// il faut eviter que le login soit vraiment trop court
210
-	if (strlen($login_base) < 3) {
211
-		$mail = strtolower(translitteration(preg_replace('/@.*/', '', $mail)));
212
-		$login_base = preg_replace('/[^\w\d]/', '_', $mail);
213
-	}
214
-	if (strlen($login_base) < 3) {
215
-		$login_base = 'user';
216
-	}
217
-
218
-	$login = $login_base;
219
-
220
-	for ($i = 1;; $i++) {
221
-		if (!sql_countsel('spip_auteurs', "login='$login'")) {
222
-			return $login;
223
-		}
224
-		$login = $login_base . $i;
225
-	}
205
+    include_spip('inc/charsets');
206
+    $nom = strtolower(translitteration($nom));
207
+    $login_base = preg_replace('/[^\w\d_]/', '_', $nom);
208
+
209
+    // il faut eviter que le login soit vraiment trop court
210
+    if (strlen($login_base) < 3) {
211
+        $mail = strtolower(translitteration(preg_replace('/@.*/', '', $mail)));
212
+        $login_base = preg_replace('/[^\w\d]/', '_', $mail);
213
+    }
214
+    if (strlen($login_base) < 3) {
215
+        $login_base = 'user';
216
+    }
217
+
218
+    $login = $login_base;
219
+
220
+    for ($i = 1;; $i++) {
221
+        if (!sql_countsel('spip_auteurs', "login='$login'")) {
222
+            return $login;
223
+        }
224
+        $login = $login_base . $i;
225
+    }
226 226
 }
227 227
 
228 228
 
@@ -240,26 +240,26 @@  discard block
 block discarded – undo
240 240
  */
241 241
 function envoyer_inscription_dist($desc, $nom, $mode, $options = []) {
242 242
 
243
-	$contexte = array_merge($desc, $options);
244
-	$contexte['nom'] = $nom;
245
-	$contexte['mode'] = $mode;
246
-	$contexte['url_confirm'] = generer_url_action('confirmer_inscription', '', true, true);
247
-	$contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'email', $desc['email']);
248
-	$contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'jeton', $desc['jeton']);
249
-	// S'il y a l'option redirect, on l'ajoute directement ici
250
-	if (isset($options['redirect'])) {
251
-		$contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'redirect', $options['redirect']);
252
-	}
253
-
254
-	$modele_mail = 'modeles/mail_inscription';
255
-	if (isset($options['modele_mail']) and $options['modele_mail']) {
256
-		$modele_mail = $options['modele_mail'];
257
-	}
258
-	$message = recuperer_fond($modele_mail, $contexte);
259
-	$from = ($options['from'] ?? null);
260
-	$head = null;
261
-
262
-	return ['', $message, $from, $head];
243
+    $contexte = array_merge($desc, $options);
244
+    $contexte['nom'] = $nom;
245
+    $contexte['mode'] = $mode;
246
+    $contexte['url_confirm'] = generer_url_action('confirmer_inscription', '', true, true);
247
+    $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'email', $desc['email']);
248
+    $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'jeton', $desc['jeton']);
249
+    // S'il y a l'option redirect, on l'ajoute directement ici
250
+    if (isset($options['redirect'])) {
251
+        $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'redirect', $options['redirect']);
252
+    }
253
+
254
+    $modele_mail = 'modeles/mail_inscription';
255
+    if (isset($options['modele_mail']) and $options['modele_mail']) {
256
+        $modele_mail = $options['modele_mail'];
257
+    }
258
+    $message = recuperer_fond($modele_mail, $contexte);
259
+    $from = ($options['from'] ?? null);
260
+    $head = null;
261
+
262
+    return ['', $message, $from, $head];
263 263
 }
264 264
 
265 265
 
@@ -270,12 +270,12 @@  discard block
 block discarded – undo
270 270
  * @return string
271 271
  */
272 272
 function creer_pass_pour_auteur($id_auteur) {
273
-	include_spip('inc/acces');
274
-	$pass = creer_pass_aleatoire(max(_PASS_LONGUEUR_MINI, 16), $id_auteur);
275
-	include_spip('action/editer_auteur');
276
-	auteur_instituer($id_auteur, ['pass' => $pass]);
273
+    include_spip('inc/acces');
274
+    $pass = creer_pass_aleatoire(max(_PASS_LONGUEUR_MINI, 16), $id_auteur);
275
+    include_spip('action/editer_auteur');
276
+    auteur_instituer($id_auteur, ['pass' => $pass]);
277 277
 
278
-	return $pass;
278
+    return $pass;
279 279
 }
280 280
 
281 281
 /**
@@ -288,17 +288,17 @@  discard block
 block discarded – undo
288 288
  * @return string
289 289
  */
290 290
 function tester_statut_inscription($statut_tmp, $id) {
291
-	include_spip('inc/autoriser');
292
-	if ($statut_tmp) {
293
-		return autoriser('inscrireauteur', $statut_tmp, $id) ? $statut_tmp : '';
294
-	} elseif (
295
-		autoriser('inscrireauteur', $statut_tmp = '1comite', $id)
296
-		or autoriser('inscrireauteur', $statut_tmp = '6forum', $id)
297
-	) {
298
-		return $statut_tmp;
299
-	}
300
-
301
-	return '';
291
+    include_spip('inc/autoriser');
292
+    if ($statut_tmp) {
293
+        return autoriser('inscrireauteur', $statut_tmp, $id) ? $statut_tmp : '';
294
+    } elseif (
295
+        autoriser('inscrireauteur', $statut_tmp = '1comite', $id)
296
+        or autoriser('inscrireauteur', $statut_tmp = '6forum', $id)
297
+    ) {
298
+        return $statut_tmp;
299
+    }
300
+
301
+    return '';
302 302
 }
303 303
 
304 304
 
@@ -312,35 +312,35 @@  discard block
 block discarded – undo
312 312
  * @return array
313 313
  */
314 314
 function confirmer_statut_inscription($auteur) {
315
-	// securite
316
-	if ($auteur['statut'] != 'nouveau') {
317
-		return $auteur;
318
-	}
319
-
320
-	$s = $auteur['prefs'];
321
-	// securite, au cas ou prefs aurait ete corrompu (ou deja ecrase par un tableau serialize)
322
-	if (!preg_match(',^\w+$,', $s)) {
323
-		$s = '6forum';
324
-	}
325
-	include_spip('inc/autoriser');
326
-	if (!autoriser('inscrireauteur', $s)) {
327
-		return $auteur;
328
-	}
329
-
330
-	include_spip('inc/autoriser');
331
-	// accorder l'autorisation de modif du statut auteur
332
-	autoriser_exception('modifier', 'auteur', $auteur['id_auteur']);
333
-	include_spip('action/editer_auteur');
334
-	// changer le statut
335
-	auteur_modifier($auteur['id_auteur'], ['statut' => $s]);
336
-	unset($_COOKIE['spip_session']); // forcer la maj de la session
337
-	// lever l'autorisation de modif du statut auteur
338
-	autoriser_exception('modifier', 'auteur', $auteur['id_auteur'], false);
339
-
340
-	// mettre a jour le statut
341
-	$auteur['statut'] = $s;
342
-
343
-	return $auteur;
315
+    // securite
316
+    if ($auteur['statut'] != 'nouveau') {
317
+        return $auteur;
318
+    }
319
+
320
+    $s = $auteur['prefs'];
321
+    // securite, au cas ou prefs aurait ete corrompu (ou deja ecrase par un tableau serialize)
322
+    if (!preg_match(',^\w+$,', $s)) {
323
+        $s = '6forum';
324
+    }
325
+    include_spip('inc/autoriser');
326
+    if (!autoriser('inscrireauteur', $s)) {
327
+        return $auteur;
328
+    }
329
+
330
+    include_spip('inc/autoriser');
331
+    // accorder l'autorisation de modif du statut auteur
332
+    autoriser_exception('modifier', 'auteur', $auteur['id_auteur']);
333
+    include_spip('action/editer_auteur');
334
+    // changer le statut
335
+    auteur_modifier($auteur['id_auteur'], ['statut' => $s]);
336
+    unset($_COOKIE['spip_session']); // forcer la maj de la session
337
+    // lever l'autorisation de modif du statut auteur
338
+    autoriser_exception('modifier', 'auteur', $auteur['id_auteur'], false);
339
+
340
+    // mettre a jour le statut
341
+    $auteur['statut'] = $s;
342
+
343
+    return $auteur;
344 344
 }
345 345
 
346 346
 
@@ -354,20 +354,20 @@  discard block
 block discarded – undo
354 354
  * @return string
355 355
  */
356 356
 function auteur_attribuer_jeton($id_auteur): string {
357
-	include_spip('base/abstract_sql');
358
-	include_spip('inc/acces');
359
-	include_spip('inc/chiffrer');
360
-	// s'assurer de l'unicite du jeton pour le couple (email,cookie)
361
-	do {
362
-		// Un morceau du jeton est lisible en bdd pour éviter de devoir déchiffrer
363
-		// tous les jetons connus pour vérifier le jeton d’un auteur.
364
-		$public = substr(creer_uniqid(), 0, 7) . '.';
365
-		$jeton = $public . creer_uniqid();
366
-		$jeton_chiffre_prefixe = $public . Chiffrement::chiffrer($jeton, SpipCles::secret_du_site());
367
-		sql_updateq('spip_auteurs', ['cookie_oubli' => $jeton_chiffre_prefixe], 'id_auteur=' . intval($id_auteur));
368
-	} while (sql_countsel('spip_auteurs', 'cookie_oubli=' . sql_quote($jeton_chiffre_prefixe, '', 'string')) > 1);
369
-
370
-	return $jeton;
357
+    include_spip('base/abstract_sql');
358
+    include_spip('inc/acces');
359
+    include_spip('inc/chiffrer');
360
+    // s'assurer de l'unicite du jeton pour le couple (email,cookie)
361
+    do {
362
+        // Un morceau du jeton est lisible en bdd pour éviter de devoir déchiffrer
363
+        // tous les jetons connus pour vérifier le jeton d’un auteur.
364
+        $public = substr(creer_uniqid(), 0, 7) . '.';
365
+        $jeton = $public . creer_uniqid();
366
+        $jeton_chiffre_prefixe = $public . Chiffrement::chiffrer($jeton, SpipCles::secret_du_site());
367
+        sql_updateq('spip_auteurs', ['cookie_oubli' => $jeton_chiffre_prefixe], 'id_auteur=' . intval($id_auteur));
368
+    } while (sql_countsel('spip_auteurs', 'cookie_oubli=' . sql_quote($jeton_chiffre_prefixe, '', 'string')) > 1);
369
+
370
+    return $jeton;
371 371
 }
372 372
 
373 373
 /**
@@ -381,20 +381,20 @@  discard block
 block discarded – undo
381 381
  * @return string|null
382 382
  */
383 383
 function auteur_lire_jeton(int $id_auteur, bool $autoInit = false): ?string {
384
-	include_spip('base/abstract_sql');
385
-	$jeton_chiffre_prefixe = sql_getfetsel('cookie_oubli', 'spip_auteurs', 'id_auteur=' . $id_auteur);
386
-	if ($jeton_chiffre_prefixe) {
387
-		include_spip('inc/chiffrer');
388
-		$jeton_chiffre = substr($jeton_chiffre_prefixe, 8);
389
-		$jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
390
-		if ($jeton) {
391
-			return $jeton;
392
-		}
393
-	}
394
-	if ($autoInit) {
395
-		return auteur_attribuer_jeton($id_auteur);
396
-	}
397
-	return null;
384
+    include_spip('base/abstract_sql');
385
+    $jeton_chiffre_prefixe = sql_getfetsel('cookie_oubli', 'spip_auteurs', 'id_auteur=' . $id_auteur);
386
+    if ($jeton_chiffre_prefixe) {
387
+        include_spip('inc/chiffrer');
388
+        $jeton_chiffre = substr($jeton_chiffre_prefixe, 8);
389
+        $jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
390
+        if ($jeton) {
391
+            return $jeton;
392
+        }
393
+    }
394
+    if ($autoInit) {
395
+        return auteur_attribuer_jeton($id_auteur);
396
+    }
397
+    return null;
398 398
 }
399 399
 
400 400
 /**
@@ -404,25 +404,25 @@  discard block
 block discarded – undo
404 404
  * @return array|bool
405 405
  */
406 406
 function auteur_verifier_jeton($jeton) {
407
-	// refuser un jeton corrompu
408
-	if (preg_match(',[^0-9a-f.],i', $jeton)) {
409
-		return false;
410
-	}
411
-
412
-	include_spip('base/abstract_sql');
413
-	include_spip('inc/chiffrer');
414
-	$public = substr($jeton, 0, 8);
415
-
416
-	// Les auteurs qui ont un jetons ressemblant
417
-	$auteurs = sql_allfetsel('*', 'spip_auteurs', 'cookie_oubli LIKE ' . sql_quote($public . '%'));
418
-	foreach ($auteurs as $auteur) {
419
-		$jeton_chiffre = substr($auteur['cookie_oubli'], 8);
420
-		$_jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
421
-		if ($_jeton and hash_equals($jeton, $_jeton)) {
422
-			return $auteur;
423
-		}
424
-	}
425
-	return false;
407
+    // refuser un jeton corrompu
408
+    if (preg_match(',[^0-9a-f.],i', $jeton)) {
409
+        return false;
410
+    }
411
+
412
+    include_spip('base/abstract_sql');
413
+    include_spip('inc/chiffrer');
414
+    $public = substr($jeton, 0, 8);
415
+
416
+    // Les auteurs qui ont un jetons ressemblant
417
+    $auteurs = sql_allfetsel('*', 'spip_auteurs', 'cookie_oubli LIKE ' . sql_quote($public . '%'));
418
+    foreach ($auteurs as $auteur) {
419
+        $jeton_chiffre = substr($auteur['cookie_oubli'], 8);
420
+        $_jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site());
421
+        if ($_jeton and hash_equals($jeton, $_jeton)) {
422
+            return $auteur;
423
+        }
424
+    }
425
+    return false;
426 426
 }
427 427
 
428 428
 /**
@@ -432,6 +432,6 @@  discard block
 block discarded – undo
432 432
  * @return bool
433 433
  */
434 434
 function auteur_effacer_jeton($id_auteur) {
435
-	include_spip('base/abstract_sql');
436
-	return sql_updateq('spip_auteurs', ['cookie_oubli' => ''], 'id_auteur=' . intval($id_auteur));
435
+    include_spip('base/abstract_sql');
436
+    return sql_updateq('spip_auteurs', ['cookie_oubli' => ''], 'id_auteur=' . intval($id_auteur));
437 437
 }
Please login to merge, or discard this patch.
ecrire/public/criteres.php 1 patch
Indentation   +1715 added lines, -1715 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  **/
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 /**
@@ -43,12 +43,12 @@  discard block
 block discarded – undo
43 43
  **/
44 44
 function critere_racine_dist($idb, &$boucles, $crit) {
45 45
 
46
-	$not = $crit->not;
47
-	$boucle = &$boucles[$idb];
48
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
46
+    $not = $crit->not;
47
+    $boucle = &$boucles[$idb];
48
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
49 49
 
50
-	$c = ["'='", "'$boucle->id_table." . "$id_parent'", 0];
51
-	$boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
50
+    $c = ["'='", "'$boucle->id_table." . "$id_parent'", 0];
51
+    $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
52 52
 }
53 53
 
54 54
 
@@ -65,15 +65,15 @@  discard block
 block discarded – undo
65 65
  * @return void|array
66 66
  **/
67 67
 function critere_exclus_dist($idb, &$boucles, $crit) {
68
-	$not = $crit->not;
69
-	$boucle = &$boucles[$idb];
70
-	$id = $boucle->primary;
71
-
72
-	if ($not or !$id) {
73
-		return ['zbug_critere_inconnu', ['critere' => $not . $crit->op]];
74
-	}
75
-	$arg = kwote(calculer_argument_precedent($idb, $id, $boucles));
76
-	$boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg];
68
+    $not = $crit->not;
69
+    $boucle = &$boucles[$idb];
70
+    $id = $boucle->primary;
71
+
72
+    if ($not or !$id) {
73
+        return ['zbug_critere_inconnu', ['critere' => $not . $crit->op]];
74
+    }
75
+    $arg = kwote(calculer_argument_precedent($idb, $id, $boucles));
76
+    $boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg];
77 77
 }
78 78
 
79 79
 
@@ -93,73 +93,73 @@  discard block
 block discarded – undo
93 93
  * @return void|array
94 94
  **/
95 95
 function critere_doublons_dist($idb, &$boucles, $crit) {
96
-	$boucle = &$boucles[$idb];
97
-	$primary = $boucle->primary;
98
-
99
-	// la table nécessite une clé primaire, non composée
100
-	if (!$primary or strpos($primary, ',')) {
101
-		return ['zbug_doublon_sur_table_sans_cle_primaire'];
102
-	}
103
-
104
-	$not = ($crit->not ? '' : 'NOT');
105
-
106
-	// le doublon s'applique sur un type de boucle (article)
107
-	$nom = "'" . $boucle->type_requete . "'";
108
-
109
-	// compléter le nom avec un nom précisé {doublons nom}
110
-	// on obtient $nom = "'article' . 'nom'"
111
-	if (isset($crit->param[0])) {
112
-		$nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
113
-	}
114
-
115
-	// code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP)
116
-	$init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n";
117
-	$init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n";
118
-
119
-	// on crée un sql_in avec la clé primaire de la table
120
-	// et la collection des doublons déjà emmagasinés dans le tableau
121
-	// $doublons et son index, ici $nom
122
-
123
-	// debut du code "sql_in('articles.id_article', "
124
-	$debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', ";
125
-	// lecture des données du doublon "$doublons[$doublon_index[] = "
126
-	// Attention : boucle->doublons désigne une variable qu'on affecte
127
-	$debut_doub = '$doublons[' . (!$not ? '' : ($boucle->doublons . '[]= '));
128
-
129
-	// le debut complet du code des doublons
130
-	$debut_doub = $debut_in . $debut_doub;
131
-
132
-	// nom du doublon "('article' . 'nom')]"
133
-	$fin_doub = "($nom)]";
134
-
135
-	// si on trouve un autre critère doublon,
136
-	// on fusionne pour avoir un seul IN, et on s'en va !
137
-	foreach ($boucle->where as $k => $w) {
138
-		if (strpos($w[0], $debut_doub) === 0) {
139
-			// fusionner le sql_in (du where)
140
-			$boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr($w[0], strlen($debut_in));
141
-			// fusionner l'initialisation (du hash) pour faire plus joli
142
-			$x = strpos($boucle->hash, $init_comment);
143
-			$len = strlen($init_comment);
144
-			$boucle->hash =
145
-				substr($boucle->hash, 0, $x + $len) . $init_code . substr($boucle->hash, $x + $len);
146
-
147
-			return;
148
-		}
149
-	}
150
-
151
-	// mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante
152
-	$boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"];
153
-
154
-	// déclarer le doublon s'il n'existe pas encore
155
-	$boucle->hash .= $init_comment . $init_code;
156
-
157
-
158
-	# la ligne suivante avait l'intention d'eviter une collecte deja faite
159
-	# mais elle fait planter une boucle a 2 critere doublons:
160
-	# {!doublons A}{doublons B}
161
-	# (de http://article.gmane.org/gmane.comp.web.spip.devel/31034)
162
-	#	if ($crit->not) $boucle->doublons = "";
96
+    $boucle = &$boucles[$idb];
97
+    $primary = $boucle->primary;
98
+
99
+    // la table nécessite une clé primaire, non composée
100
+    if (!$primary or strpos($primary, ',')) {
101
+        return ['zbug_doublon_sur_table_sans_cle_primaire'];
102
+    }
103
+
104
+    $not = ($crit->not ? '' : 'NOT');
105
+
106
+    // le doublon s'applique sur un type de boucle (article)
107
+    $nom = "'" . $boucle->type_requete . "'";
108
+
109
+    // compléter le nom avec un nom précisé {doublons nom}
110
+    // on obtient $nom = "'article' . 'nom'"
111
+    if (isset($crit->param[0])) {
112
+        $nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
113
+    }
114
+
115
+    // code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP)
116
+    $init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n";
117
+    $init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n";
118
+
119
+    // on crée un sql_in avec la clé primaire de la table
120
+    // et la collection des doublons déjà emmagasinés dans le tableau
121
+    // $doublons et son index, ici $nom
122
+
123
+    // debut du code "sql_in('articles.id_article', "
124
+    $debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', ";
125
+    // lecture des données du doublon "$doublons[$doublon_index[] = "
126
+    // Attention : boucle->doublons désigne une variable qu'on affecte
127
+    $debut_doub = '$doublons[' . (!$not ? '' : ($boucle->doublons . '[]= '));
128
+
129
+    // le debut complet du code des doublons
130
+    $debut_doub = $debut_in . $debut_doub;
131
+
132
+    // nom du doublon "('article' . 'nom')]"
133
+    $fin_doub = "($nom)]";
134
+
135
+    // si on trouve un autre critère doublon,
136
+    // on fusionne pour avoir un seul IN, et on s'en va !
137
+    foreach ($boucle->where as $k => $w) {
138
+        if (strpos($w[0], $debut_doub) === 0) {
139
+            // fusionner le sql_in (du where)
140
+            $boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr($w[0], strlen($debut_in));
141
+            // fusionner l'initialisation (du hash) pour faire plus joli
142
+            $x = strpos($boucle->hash, $init_comment);
143
+            $len = strlen($init_comment);
144
+            $boucle->hash =
145
+                substr($boucle->hash, 0, $x + $len) . $init_code . substr($boucle->hash, $x + $len);
146
+
147
+            return;
148
+        }
149
+    }
150
+
151
+    // mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante
152
+    $boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"];
153
+
154
+    // déclarer le doublon s'il n'existe pas encore
155
+    $boucle->hash .= $init_comment . $init_code;
156
+
157
+
158
+    # la ligne suivante avait l'intention d'eviter une collecte deja faite
159
+    # mais elle fait planter une boucle a 2 critere doublons:
160
+    # {!doublons A}{doublons B}
161
+    # (de http://article.gmane.org/gmane.comp.web.spip.devel/31034)
162
+    #	if ($crit->not) $boucle->doublons = "";
163 163
 }
164 164
 
165 165
 
@@ -180,14 +180,14 @@  discard block
 block discarded – undo
180 180
  * @return void
181 181
  **/
182 182
 function critere_lang_select_dist($idb, &$boucles, $crit) {
183
-	if (!isset($crit->param[1][0]) or !($param = $crit->param[1][0]->texte)) {
184
-		$param = 'oui';
185
-	}
186
-	if ($crit->not) {
187
-		$param = ($param == 'oui') ? 'non' : 'oui';
188
-	}
189
-	$boucle = &$boucles[$idb];
190
-	$boucle->lang_select = $param;
183
+    if (!isset($crit->param[1][0]) or !($param = $crit->param[1][0]->texte)) {
184
+        $param = 'oui';
185
+    }
186
+    if ($crit->not) {
187
+        $param = ($param == 'oui') ? 'non' : 'oui';
188
+    }
189
+    $boucle = &$boucles[$idb];
190
+    $boucle->lang_select = $param;
191 191
 }
192 192
 
193 193
 
@@ -209,15 +209,15 @@  discard block
 block discarded – undo
209 209
  * @return void
210 210
  **/
211 211
 function critere_debut_dist($idb, &$boucles, $crit) {
212
-	[$un, $deux] = $crit->param;
213
-	$un = $un[0]->texte;
214
-	$deux = $deux[0]->texte;
215
-	if ($deux) {
216
-		$boucles[$idb]->limit =
217
-			'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"';
218
-	} else {
219
-		calculer_critere_DEFAUT_dist($idb, $boucles, $crit);
220
-	}
212
+    [$un, $deux] = $crit->param;
213
+    $un = $un[0]->texte;
214
+    $deux = $deux[0]->texte;
215
+    if ($deux) {
216
+        $boucles[$idb]->limit =
217
+            'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"';
218
+    } else {
219
+        calculer_critere_DEFAUT_dist($idb, $boucles, $crit);
220
+    }
221 221
 }
222 222
 
223 223
 
@@ -251,58 +251,58 @@  discard block
 block discarded – undo
251 251
  **/
252 252
 function critere_pagination_dist($idb, &$boucles, $crit) {
253 253
 
254
-	$boucle = &$boucles[$idb];
255
-	// definition de la taille de la page
256
-	$pas = !isset($crit->param[0][0]) ? "''"
257
-		: calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent);
258
-
259
-	if (!preg_match(_CODE_QUOTE, $pas, $r)) {
260
-		$pas = "((\$a = intval($pas)) ? \$a : 10)";
261
-	} else {
262
-		$r = intval($r[2]);
263
-		$pas = strval($r ?: 10);
264
-	}
265
-
266
-	// Calcul du nommage de la pagination si il existe.
267
-	// La nouvelle syntaxe {pagination 20, nom} est prise en compte et privilégiée mais on reste
268
-	// compatible avec l'ancienne car certains cas fonctionnent correctement
269
-	$type = "'$idb'";
270
-	// Calcul d'un nommage spécifique de la pagination si précisé.
271
-	// Syntaxe {pagination 20, nom}
272
-	if (isset($crit->param[0][1])) {
273
-		$type = calculer_liste([$crit->param[0][1]], $idb, $boucles, $boucle->id_parent);
274
-	} // Ancienne syntaxe {pagination 20 nom} pour compatibilité
275
-	elseif (isset($crit->param[1][0])) {
276
-		$type = calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
277
-	}
278
-
279
-	$debut = ($type[0] !== "'") ? "'debut'.$type" : ("'debut" . substr($type, 1));
280
-	$boucle->modificateur['debut_nom'] = $type;
281
-	$partie =
282
-		// tester si le numero de page demande est de la forme '@yyy'
283
-		'isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : _request(' . $debut . ");\n"
284
-		. "\tif (\$debut_boucle && \$debut_boucle[0] === '@') {\n"
285
-		. "\t\t" . '$debut_boucle = $Pile[0][' . $debut . '] = quete_debut_pagination(\'' . $boucle->primary . '\',$Pile[0][\'@' . $boucle->primary . '\'] = substr($debut_boucle,1),' . $pas . ',$iter);' . "\n"
286
-		. "\t\t" . '$iter->seek(0);' . "\n"
287
-		. "\t}\n"
288
-		. "\t" . '$debut_boucle = intval($debut_boucle)';
289
-
290
-	$boucle->hash .= '
254
+    $boucle = &$boucles[$idb];
255
+    // definition de la taille de la page
256
+    $pas = !isset($crit->param[0][0]) ? "''"
257
+        : calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent);
258
+
259
+    if (!preg_match(_CODE_QUOTE, $pas, $r)) {
260
+        $pas = "((\$a = intval($pas)) ? \$a : 10)";
261
+    } else {
262
+        $r = intval($r[2]);
263
+        $pas = strval($r ?: 10);
264
+    }
265
+
266
+    // Calcul du nommage de la pagination si il existe.
267
+    // La nouvelle syntaxe {pagination 20, nom} est prise en compte et privilégiée mais on reste
268
+    // compatible avec l'ancienne car certains cas fonctionnent correctement
269
+    $type = "'$idb'";
270
+    // Calcul d'un nommage spécifique de la pagination si précisé.
271
+    // Syntaxe {pagination 20, nom}
272
+    if (isset($crit->param[0][1])) {
273
+        $type = calculer_liste([$crit->param[0][1]], $idb, $boucles, $boucle->id_parent);
274
+    } // Ancienne syntaxe {pagination 20 nom} pour compatibilité
275
+    elseif (isset($crit->param[1][0])) {
276
+        $type = calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
277
+    }
278
+
279
+    $debut = ($type[0] !== "'") ? "'debut'.$type" : ("'debut" . substr($type, 1));
280
+    $boucle->modificateur['debut_nom'] = $type;
281
+    $partie =
282
+        // tester si le numero de page demande est de la forme '@yyy'
283
+        'isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : _request(' . $debut . ");\n"
284
+        . "\tif (\$debut_boucle && \$debut_boucle[0] === '@') {\n"
285
+        . "\t\t" . '$debut_boucle = $Pile[0][' . $debut . '] = quete_debut_pagination(\'' . $boucle->primary . '\',$Pile[0][\'@' . $boucle->primary . '\'] = substr($debut_boucle,1),' . $pas . ',$iter);' . "\n"
286
+        . "\t\t" . '$iter->seek(0);' . "\n"
287
+        . "\t}\n"
288
+        . "\t" . '$debut_boucle = intval($debut_boucle)';
289
+
290
+    $boucle->hash .= '
291 291
 	$command[\'pagination\'] = array((isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : null), ' . $pas . ');';
292 292
 
293
-	$boucle->total_parties = $pas;
294
-	calculer_parties($boucles, $idb, $partie, 'p+');
295
-	// ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id
296
-	// sauf si pas de primaire, ou si primaire composee
297
-	// dans ce cas, on ne sait pas gerer une pagination indirecte
298
-	$t = $boucle->id_table . '.' . $boucle->primary;
299
-	if (
300
-		$boucle->primary
301
-		and !preg_match('/[,\s]/', $boucle->primary)
302
-		and !in_array($t, $boucle->select)
303
-	) {
304
-		$boucle->select[] = $t;
305
-	}
293
+    $boucle->total_parties = $pas;
294
+    calculer_parties($boucles, $idb, $partie, 'p+');
295
+    // ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id
296
+    // sauf si pas de primaire, ou si primaire composee
297
+    // dans ce cas, on ne sait pas gerer une pagination indirecte
298
+    $t = $boucle->id_table . '.' . $boucle->primary;
299
+    if (
300
+        $boucle->primary
301
+        and !preg_match('/[,\s]/', $boucle->primary)
302
+        and !in_array($t, $boucle->select)
303
+    ) {
304
+        $boucle->select[] = $t;
305
+    }
306 306
 }
307 307
 
308 308
 
@@ -324,24 +324,24 @@  discard block
 block discarded – undo
324 324
  **/
325 325
 function critere_recherche_dist($idb, &$boucles, $crit) {
326 326
 
327
-	$boucle = &$boucles[$idb];
327
+    $boucle = &$boucles[$idb];
328 328
 
329
-	if (!$boucle->primary or strpos($boucle->primary, ',')) {
330
-		erreur_squelette(_T('zbug_critere_sur_table_sans_cle_primaire', ['critere' => 'recherche']), $boucle);
329
+    if (!$boucle->primary or strpos($boucle->primary, ',')) {
330
+        erreur_squelette(_T('zbug_critere_sur_table_sans_cle_primaire', ['critere' => 'recherche']), $boucle);
331 331
 
332
-		return;
333
-	}
332
+        return;
333
+    }
334 334
 
335
-	if (isset($crit->param[0])) {
336
-		$quoi = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
337
-	} else {
338
-		$quoi = '(isset($Pile[0]["recherche"])?$Pile[0]["recherche"]:(isset($GLOBALS["recherche"])?$GLOBALS["recherche"]:""))';
339
-	}
335
+    if (isset($crit->param[0])) {
336
+        $quoi = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
337
+    } else {
338
+        $quoi = '(isset($Pile[0]["recherche"])?$Pile[0]["recherche"]:(isset($GLOBALS["recherche"])?$GLOBALS["recherche"]:""))';
339
+    }
340 340
 
341
-	$_modificateur = var_export($boucle->modificateur, true);
342
-	$boucle->hash .= '
341
+    $_modificateur = var_export($boucle->modificateur, true);
342
+    $boucle->hash .= '
343 343
 	// RECHERCHE'
344
-		. ($crit->cond ? '
344
+        . ($crit->cond ? '
345 345
 	if (!strlen(' . $quoi . ')){
346 346
 		list($rech_select, $rech_where) = array("0 as points","");
347 347
 	} else' : '') . '
@@ -352,21 +352,21 @@  discard block
 block discarded – undo
352 352
 	';
353 353
 
354 354
 
355
-	$t = $boucle->id_table . '.' . $boucle->primary;
356
-	if (!in_array($t, $boucles[$idb]->select)) {
357
-		$boucle->select[] = $t;
358
-	} # pour postgres, neuneu ici
359
-	// jointure uniquement sur le serveur principal
360
-	// (on ne peut joindre une table d'un serveur distant avec la table des resultats du serveur principal)
361
-	if (!$boucle->sql_serveur) {
362
-		$boucle->join['resultats'] = ["'" . $boucle->id_table . "'", "'id'", "'" . $boucle->primary . "'"];
363
-		$boucle->from['resultats'] = 'spip_resultats';
364
-	}
365
-	$boucle->select[] = '$rech_select';
366
-	//$boucle->where[]= "\$rech_where?'resultats.id=".$boucle->id_table.".".$boucle->primary."':''";
367
-
368
-	// et la recherche trouve
369
-	$boucle->where[] = '$rech_where?$rech_where:\'\'';
355
+    $t = $boucle->id_table . '.' . $boucle->primary;
356
+    if (!in_array($t, $boucles[$idb]->select)) {
357
+        $boucle->select[] = $t;
358
+    } # pour postgres, neuneu ici
359
+    // jointure uniquement sur le serveur principal
360
+    // (on ne peut joindre une table d'un serveur distant avec la table des resultats du serveur principal)
361
+    if (!$boucle->sql_serveur) {
362
+        $boucle->join['resultats'] = ["'" . $boucle->id_table . "'", "'id'", "'" . $boucle->primary . "'"];
363
+        $boucle->from['resultats'] = 'spip_resultats';
364
+    }
365
+    $boucle->select[] = '$rech_select';
366
+    //$boucle->where[]= "\$rech_where?'resultats.id=".$boucle->id_table.".".$boucle->primary."':''";
367
+
368
+    // et la recherche trouve
369
+    $boucle->where[] = '$rech_where?$rech_where:\'\'';
370 370
 }
371 371
 
372 372
 /**
@@ -383,25 +383,25 @@  discard block
 block discarded – undo
383 383
  * @return void
384 384
  **/
385 385
 function critere_traduction_dist($idb, &$boucles, $crit) {
386
-	$boucle = &$boucles[$idb];
387
-	$prim = $boucle->primary;
388
-	$table = $boucle->id_table;
389
-	$arg = kwote(calculer_argument_precedent($idb, 'id_trad', $boucles));
390
-	$dprim = kwote(calculer_argument_precedent($idb, $prim, $boucles));
391
-	$boucle->where[] =
392
-		[
393
-			"'OR'",
394
-			[
395
-				"'AND'",
396
-				["'='", "'$table.id_trad'", 0],
397
-				["'='", "'$table.$prim'", $dprim]
398
-			],
399
-			[
400
-				"'AND'",
401
-				["'>'", "'$table.id_trad'", 0],
402
-				["'='", "'$table.id_trad'", $arg]
403
-			]
404
-		];
386
+    $boucle = &$boucles[$idb];
387
+    $prim = $boucle->primary;
388
+    $table = $boucle->id_table;
389
+    $arg = kwote(calculer_argument_precedent($idb, 'id_trad', $boucles));
390
+    $dprim = kwote(calculer_argument_precedent($idb, $prim, $boucles));
391
+    $boucle->where[] =
392
+        [
393
+            "'OR'",
394
+            [
395
+                "'AND'",
396
+                ["'='", "'$table.id_trad'", 0],
397
+                ["'='", "'$table.$prim'", $dprim]
398
+            ],
399
+            [
400
+                "'AND'",
401
+                ["'>'", "'$table.id_trad'", 0],
402
+                ["'='", "'$table.id_trad'", $arg]
403
+            ]
404
+        ];
405 405
 }
406 406
 
407 407
 
@@ -419,17 +419,17 @@  discard block
 block discarded – undo
419 419
  * @return void
420 420
  **/
421 421
 function critere_origine_traduction_dist($idb, &$boucles, $crit) {
422
-	$boucle = &$boucles[$idb];
423
-	$prim = $boucle->primary;
424
-	$table = $boucle->id_table;
425
-
426
-	$c =
427
-		[
428
-			"'OR'",
429
-			["'='", "'$table." . "id_trad'", "'$table.$prim'"],
430
-			["'='", "'$table.id_trad'", "'0'"]
431
-		];
432
-	$boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
422
+    $boucle = &$boucles[$idb];
423
+    $prim = $boucle->primary;
424
+    $table = $boucle->id_table;
425
+
426
+    $c =
427
+        [
428
+            "'OR'",
429
+            ["'='", "'$table." . "id_trad'", "'$table.$prim'"],
430
+            ["'='", "'$table.id_trad'", "'0'"]
431
+        ];
432
+    $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
433 433
 }
434 434
 
435 435
 
@@ -446,17 +446,17 @@  discard block
 block discarded – undo
446 446
  **/
447 447
 function critere_meme_parent_dist($idb, &$boucles, $crit) {
448 448
 
449
-	$boucle = &$boucles[$idb];
450
-	$arg = kwote(calculer_argument_precedent($idb, 'id_parent', $boucles));
451
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
452
-	$mparent = $boucle->id_table . '.' . $id_parent;
453
-
454
-	if ($boucle->type_requete == 'rubriques' or isset($GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'])) {
455
-		$boucle->where[] = ["'='", "'$mparent'", $arg];
456
-	} // le cas FORUMS est gere dans le plugin forum, dans la fonction critere_FORUMS_meme_parent_dist()
457
-	else {
458
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $boucle->type_requete]];
459
-	}
449
+    $boucle = &$boucles[$idb];
450
+    $arg = kwote(calculer_argument_precedent($idb, 'id_parent', $boucles));
451
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
452
+    $mparent = $boucle->id_table . '.' . $id_parent;
453
+
454
+    if ($boucle->type_requete == 'rubriques' or isset($GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'])) {
455
+        $boucle->where[] = ["'='", "'$mparent'", $arg];
456
+    } // le cas FORUMS est gere dans le plugin forum, dans la fonction critere_FORUMS_meme_parent_dist()
457
+    else {
458
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $boucle->type_requete]];
459
+    }
460 460
 }
461 461
 
462 462
 
@@ -487,37 +487,37 @@  discard block
 block discarded – undo
487 487
  **/
488 488
 function critere_branche_dist($idb, &$boucles, $crit) {
489 489
 
490
-	$not = $crit->not;
491
-	$boucle = &$boucles[$idb];
492
-	// prendre en priorite un identifiant en parametre {branche XX}
493
-	if (isset($crit->param[0])) {
494
-		$arg = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
495
-		// sinon on le prend chez une boucle parente
496
-	} else {
497
-		$arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles), $boucle->sql_serveur, 'int NOT NULL');
498
-	}
499
-
500
-	//Trouver une jointure
501
-	$champ = 'id_rubrique';
502
-	$desc = $boucle->show;
503
-	//Seulement si necessaire
504
-	if (!array_key_exists($champ, $desc['field'])) {
505
-		$cle = trouver_jointure_champ($champ, $boucle);
506
-		$trouver_table = charger_fonction('trouver_table', 'base');
507
-		$desc = $trouver_table($boucle->from[$cle]);
508
-		if (count(trouver_champs_decomposes($champ, $desc)) > 1) {
509
-			$decompose = decompose_champ_id_objet($champ);
510
-			$champ = array_shift($decompose);
511
-			$boucle->where[] = ["'='", _q($cle . '.' . reset($decompose)), '"' . sql_quote(end($decompose)) . '"'];
512
-		}
513
-	} else {
514
-		$cle = $boucle->id_table;
515
-	}
516
-
517
-	$c = "sql_in('$cle" . ".$champ', calcul_branche_in($arg)"
518
-		. ($not ? ", 'NOT'" : '') . ')';
519
-	$boucle->where[] = !$crit->cond ? $c :
520
-		("($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')');
490
+    $not = $crit->not;
491
+    $boucle = &$boucles[$idb];
492
+    // prendre en priorite un identifiant en parametre {branche XX}
493
+    if (isset($crit->param[0])) {
494
+        $arg = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
495
+        // sinon on le prend chez une boucle parente
496
+    } else {
497
+        $arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles), $boucle->sql_serveur, 'int NOT NULL');
498
+    }
499
+
500
+    //Trouver une jointure
501
+    $champ = 'id_rubrique';
502
+    $desc = $boucle->show;
503
+    //Seulement si necessaire
504
+    if (!array_key_exists($champ, $desc['field'])) {
505
+        $cle = trouver_jointure_champ($champ, $boucle);
506
+        $trouver_table = charger_fonction('trouver_table', 'base');
507
+        $desc = $trouver_table($boucle->from[$cle]);
508
+        if (count(trouver_champs_decomposes($champ, $desc)) > 1) {
509
+            $decompose = decompose_champ_id_objet($champ);
510
+            $champ = array_shift($decompose);
511
+            $boucle->where[] = ["'='", _q($cle . '.' . reset($decompose)), '"' . sql_quote(end($decompose)) . '"'];
512
+        }
513
+    } else {
514
+        $cle = $boucle->id_table;
515
+    }
516
+
517
+    $c = "sql_in('$cle" . ".$champ', calcul_branche_in($arg)"
518
+        . ($not ? ", 'NOT'" : '') . ')';
519
+    $boucle->where[] = !$crit->cond ? $c :
520
+        ("($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')');
521 521
 }
522 522
 
523 523
 /**
@@ -533,15 +533,15 @@  discard block
 block discarded – undo
533 533
  **/
534 534
 function critere_logo_dist($idb, &$boucles, $crit) {
535 535
 
536
-	$boucle = &$boucles[$idb];
537
-	$not = ($crit->not ? 'NOT' : '');
538
-	$serveur = $boucle->sql_serveur;
536
+    $boucle = &$boucles[$idb];
537
+    $not = ($crit->not ? 'NOT' : '');
538
+    $serveur = $boucle->sql_serveur;
539 539
 
540
-	$c = "sql_in('" .
541
-		$boucle->id_table . '.' . $boucle->primary
542
-		. "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')";
540
+    $c = "sql_in('" .
541
+        $boucle->id_table . '.' . $boucle->primary
542
+        . "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')";
543 543
 
544
-	$boucle->where[] = $c;
544
+    $boucle->where[] = $c;
545 545
 }
546 546
 
547 547
 
@@ -563,31 +563,31 @@  discard block
 block discarded – undo
563 563
  * @return void|array
564 564
  **/
565 565
 function critere_fusion_dist($idb, &$boucles, $crit) {
566
-	if ($t = isset($crit->param[0])) {
567
-		$t = $crit->param[0];
568
-		if ($t[0]->type == 'texte') {
569
-			$t = $t[0]->texte;
570
-			if (preg_match('/^(.*)\.(.*)$/', $t, $r)) {
571
-				$t = table_objet_sql($r[1]);
572
-				$t = array_search($t, $boucles[$idb]->from);
573
-				if ($t) {
574
-					$t .= '.' . $r[2];
575
-				}
576
-			}
577
-		} else {
578
-			$t = '".'
579
-				. calculer_critere_arg_dynamique($idb, $boucles, $t)
580
-				. '."';
581
-		}
582
-	}
583
-	if ($t) {
584
-		$boucles[$idb]->group[] = $t;
585
-		if (!in_array($t, $boucles[$idb]->select)) {
586
-			$boucles[$idb]->select[] = $t;
587
-		}
588
-	} else {
589
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
590
-	}
566
+    if ($t = isset($crit->param[0])) {
567
+        $t = $crit->param[0];
568
+        if ($t[0]->type == 'texte') {
569
+            $t = $t[0]->texte;
570
+            if (preg_match('/^(.*)\.(.*)$/', $t, $r)) {
571
+                $t = table_objet_sql($r[1]);
572
+                $t = array_search($t, $boucles[$idb]->from);
573
+                if ($t) {
574
+                    $t .= '.' . $r[2];
575
+                }
576
+            }
577
+        } else {
578
+            $t = '".'
579
+                . calculer_critere_arg_dynamique($idb, $boucles, $t)
580
+                . '."';
581
+        }
582
+    }
583
+    if ($t) {
584
+        $boucles[$idb]->group[] = $t;
585
+        if (!in_array($t, $boucles[$idb]->select)) {
586
+            $boucles[$idb]->select[] = $t;
587
+        }
588
+    } else {
589
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
590
+    }
591 591
 }
592 592
 
593 593
 /**
@@ -607,7 +607,7 @@  discard block
 block discarded – undo
607 607
  * @return void
608 608
  **/
609 609
 function critere_fusion_supprimer_dist($idb, &$boucles, $crit) {
610
-	$boucles[$idb]->group = [];
610
+    $boucles[$idb]->group = [];
611 611
 }
612 612
 
613 613
 /**
@@ -644,44 +644,44 @@  discard block
 block discarded – undo
644 644
  * @param Critere $crit Paramètres du critère dans cette boucle
645 645
  */
646 646
 function critere_collecte_dist($idb, &$boucles, $crit) {
647
-	if (isset($crit->param[0])) {
648
-		$_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
649
-		$boucle = $boucles[$idb];
650
-		$boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')";
651
-		$n = is_countable($boucle->order) ? count($boucle->order) : 0;
652
-		if ($n && (strpos($boucle->order[$n - 1], 'COLLATE') === false)) {
653
-			// l'instruction COLLATE doit être placée avant ASC ou DESC
654
-			// notamment lors de l'utilisation `{!par xxx}{collate yyy}`
655
-			if (
656
-				(false !== $i = strpos($boucle->order[$n - 1], 'ASC'))
657
-				or (false !== $i = strpos($boucle->order[$n - 1], 'DESC'))
658
-			) {
659
-				$boucle->order[$n - 1] = substr_replace($boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0);
660
-			} else {
661
-				$boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate'];
662
-			}
663
-		}
664
-	} else {
665
-		return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]);
666
-	}
647
+    if (isset($crit->param[0])) {
648
+        $_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
649
+        $boucle = $boucles[$idb];
650
+        $boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')";
651
+        $n = is_countable($boucle->order) ? count($boucle->order) : 0;
652
+        if ($n && (strpos($boucle->order[$n - 1], 'COLLATE') === false)) {
653
+            // l'instruction COLLATE doit être placée avant ASC ou DESC
654
+            // notamment lors de l'utilisation `{!par xxx}{collate yyy}`
655
+            if (
656
+                (false !== $i = strpos($boucle->order[$n - 1], 'ASC'))
657
+                or (false !== $i = strpos($boucle->order[$n - 1], 'DESC'))
658
+            ) {
659
+                $boucle->order[$n - 1] = substr_replace($boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0);
660
+            } else {
661
+                $boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate'];
662
+            }
663
+        }
664
+    } else {
665
+        return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]);
666
+    }
667 667
 }
668 668
 
669 669
 function calculer_critere_arg_dynamique($idb, &$boucles, $crit, $suffix = '') {
670
-	$boucle = $boucles[$idb];
671
-	$alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')';
672
-	$var = '$champs_' . $idb;
673
-	$desc = (strpos($boucle->in, (string) "static $var =") !== false);
674
-	if (!$desc) {
675
-		$desc = $boucle->show['field'];
676
-		$desc = implode(',', array_map('_q', array_keys($desc)));
677
-		$boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');';
678
-	}
679
-	if ($desc) {
680
-		$alt = "(in_array(\$x, $var)  ? $alt :(\$x$suffix))";
681
-	}
682
-	$arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent);
683
-
684
-	return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')";
670
+    $boucle = $boucles[$idb];
671
+    $alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')';
672
+    $var = '$champs_' . $idb;
673
+    $desc = (strpos($boucle->in, (string) "static $var =") !== false);
674
+    if (!$desc) {
675
+        $desc = $boucle->show['field'];
676
+        $desc = implode(',', array_map('_q', array_keys($desc)));
677
+        $boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');';
678
+    }
679
+    if ($desc) {
680
+        $alt = "(in_array(\$x, $var)  ? $alt :(\$x$suffix))";
681
+    }
682
+    $arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent);
683
+
684
+    return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')";
685 685
 }
686 686
 
687 687
 /**
@@ -720,7 +720,7 @@  discard block
 block discarded – undo
720 720
  * @param Critere $crit Paramètres du critère dans cette boucle
721 721
  */
722 722
 function critere_par_dist($idb, &$boucles, $crit) {
723
-	return critere_parinverse($idb, $boucles, $crit);
723
+    return critere_parinverse($idb, $boucles, $crit);
724 724
 }
725 725
 
726 726
 /**
@@ -742,93 +742,93 @@  discard block
 block discarded – undo
742 742
  * @param Critere $crit Paramètres du critère dans cette boucle
743 743
  */
744 744
 function critere_parinverse($idb, &$boucles, $crit) {
745
-	$boucle = &$boucles[$idb];
746
-
747
-	$sens = $collecte = '';
748
-	if ($crit->not) {
749
-		$sens = " . ' DESC'";
750
-	}
751
-	if (isset($boucle->modificateur['collate'])) {
752
-		$collecte = ' . ' . $boucle->modificateur['collate'];
753
-	}
754
-
755
-	// Pour chaque paramètre du critère
756
-	foreach ($crit->param as $tri) {
757
-		$order = $fct = '';
758
-		// tris specifiés dynamiquement {par #ENV{tri}}
759
-		if ($tri[0]->type != 'texte') {
760
-			// calculer le order dynamique qui verifie les champs
761
-			$order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens);
762
-			// ajouter 'hasard' comme possibilité de tri dynamique
763
-			calculer_critere_par_hasard($idb, $boucles, $crit);
764
-		}
765
-		// tris textuels {par titre}
766
-		else {
767
-			$par = array_shift($tri);
768
-			$par = $par->texte;
769
-
770
-			// tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre}
771
-			if (preg_match(',^(\w+)[\s]+(.*)$,', $par, $m)) {
772
-				$expression = trim($m[1]);
773
-				$champ = trim($m[2]);
774
-				if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) {
775
-					$order = $f($idb, $boucles, $crit, $tri, $champ);
776
-				} else {
777
-					return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
778
-				}
779
-
780
-			// tris de la forme {par champ} ou {par FONCTION(champ)}
781
-			} elseif ($boucle->type_requete == 'DATA' or preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', $par, $match)) {
782
-				// {par FONCTION(champ)}
783
-				if (isset($match) and count($match) > 2) {
784
-					$par = substr($match[2], 1, -1);
785
-					$fct = $match[1];
786
-				}
787
-				// quelques cas spécifiques {par hasard}, {par date}
788
-				if ($par == 'hasard') {
789
-					$order = calculer_critere_par_hasard($idb, $boucles, $crit);
790
-				} elseif ($par == 'date' and !empty($boucle->show['date'])) {
791
-					$order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'";
792
-				} else {
793
-					// cas général {par champ}, {par table.champ}, ...
794
-					$order = calculer_critere_par_champ($idb, $boucles, $crit, $par);
795
-				}
796
-			}
797
-
798
-			// on ne sait pas traiter…
799
-			else {
800
-				return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
801
-			}
802
-
803
-			// En cas d'erreur de squelette retournée par une fonction
804
-			if (is_array($order)) {
805
-				return $order;
806
-			}
807
-		}
808
-
809
-		if (preg_match('/^\'([^"]*)\'$/', $order, $m)) {
810
-			$t = $m[1];
811
-			if (strpos($t, '.') and !in_array($t, $boucle->select)) {
812
-				$boucle->select[] = $t;
813
-			}
814
-		} else {
815
-			$sens = '';
816
-		}
817
-
818
-		if ($fct) {
819
-			if (preg_match("/^\s*'(.*)'\s*$/", $order, $r)) {
820
-				$order = "'$fct(" . $r[1] . ")'";
821
-			} else {
822
-				$order = "'$fct(' . $order . ')'";
823
-			}
824
-		}
825
-		$t = $order . $collecte . $sens;
826
-		if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
827
-			$t = $r[1] . $r[2];
828
-		}
829
-
830
-		$boucle->order[] = $t;
831
-	}
745
+    $boucle = &$boucles[$idb];
746
+
747
+    $sens = $collecte = '';
748
+    if ($crit->not) {
749
+        $sens = " . ' DESC'";
750
+    }
751
+    if (isset($boucle->modificateur['collate'])) {
752
+        $collecte = ' . ' . $boucle->modificateur['collate'];
753
+    }
754
+
755
+    // Pour chaque paramètre du critère
756
+    foreach ($crit->param as $tri) {
757
+        $order = $fct = '';
758
+        // tris specifiés dynamiquement {par #ENV{tri}}
759
+        if ($tri[0]->type != 'texte') {
760
+            // calculer le order dynamique qui verifie les champs
761
+            $order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens);
762
+            // ajouter 'hasard' comme possibilité de tri dynamique
763
+            calculer_critere_par_hasard($idb, $boucles, $crit);
764
+        }
765
+        // tris textuels {par titre}
766
+        else {
767
+            $par = array_shift($tri);
768
+            $par = $par->texte;
769
+
770
+            // tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre}
771
+            if (preg_match(',^(\w+)[\s]+(.*)$,', $par, $m)) {
772
+                $expression = trim($m[1]);
773
+                $champ = trim($m[2]);
774
+                if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) {
775
+                    $order = $f($idb, $boucles, $crit, $tri, $champ);
776
+                } else {
777
+                    return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
778
+                }
779
+
780
+            // tris de la forme {par champ} ou {par FONCTION(champ)}
781
+            } elseif ($boucle->type_requete == 'DATA' or preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', $par, $match)) {
782
+                // {par FONCTION(champ)}
783
+                if (isset($match) and count($match) > 2) {
784
+                    $par = substr($match[2], 1, -1);
785
+                    $fct = $match[1];
786
+                }
787
+                // quelques cas spécifiques {par hasard}, {par date}
788
+                if ($par == 'hasard') {
789
+                    $order = calculer_critere_par_hasard($idb, $boucles, $crit);
790
+                } elseif ($par == 'date' and !empty($boucle->show['date'])) {
791
+                    $order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'";
792
+                } else {
793
+                    // cas général {par champ}, {par table.champ}, ...
794
+                    $order = calculer_critere_par_champ($idb, $boucles, $crit, $par);
795
+                }
796
+            }
797
+
798
+            // on ne sait pas traiter…
799
+            else {
800
+                return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
801
+            }
802
+
803
+            // En cas d'erreur de squelette retournée par une fonction
804
+            if (is_array($order)) {
805
+                return $order;
806
+            }
807
+        }
808
+
809
+        if (preg_match('/^\'([^"]*)\'$/', $order, $m)) {
810
+            $t = $m[1];
811
+            if (strpos($t, '.') and !in_array($t, $boucle->select)) {
812
+                $boucle->select[] = $t;
813
+            }
814
+        } else {
815
+            $sens = '';
816
+        }
817
+
818
+        if ($fct) {
819
+            if (preg_match("/^\s*'(.*)'\s*$/", $order, $r)) {
820
+                $order = "'$fct(" . $r[1] . ")'";
821
+            } else {
822
+                $order = "'$fct(' . $order . ')'";
823
+            }
824
+        }
825
+        $t = $order . $collecte . $sens;
826
+        if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
827
+            $t = $r[1] . $r[2];
828
+        }
829
+
830
+        $boucle->order[] = $t;
831
+    }
832 832
 }
833 833
 
834 834
 /**
@@ -842,13 +842,13 @@  discard block
 block discarded – undo
842 842
  * @return string Clause pour le Order by
843 843
  */
844 844
 function calculer_critere_par_hasard($idb, &$boucles, $crit) {
845
-	$boucle = &$boucles[$idb];
846
-	// Si ce n'est fait, ajouter un champ 'hasard' dans le select
847
-	$parha = 'rand() AS hasard';
848
-	if (!in_array($parha, $boucle->select)) {
849
-		$boucle->select[] = $parha;
850
-	}
851
-	return "'hasard'";
845
+    $boucle = &$boucles[$idb];
846
+    // Si ce n'est fait, ajouter un champ 'hasard' dans le select
847
+    $parha = 'rand() AS hasard';
848
+    if (!in_array($parha, $boucle->select)) {
849
+        $boucle->select[] = $parha;
850
+    }
851
+    return "'hasard'";
852 852
 }
853 853
 
854 854
 /**
@@ -872,24 +872,24 @@  discard block
 block discarded – undo
872 872
  * @return string|array Clause pour le Order by (array si erreur)
873 873
  */
874 874
 function calculer_critere_par_expression_num($idb, &$boucles, $crit, $tri, $champ) {
875
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
876
-	if (is_array($_champ)) {
877
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]];
878
-	}
879
-	$boucle = &$boucles[$idb];
880
-	$texte = '0+' . $_champ;
881
-	$suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
882
-	if ($suite !== "''") {
883
-		$texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
884
-	}
885
-	$asnum = 'num' . ($boucle->order ? count($boucle->order) : '');
886
-	$boucle->select[] = $texte . " AS $asnum";
887
-
888
-	$orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ);
889
-	$orderassinum = trim($orderassinum, "'");
890
-
891
-	$order = "'$orderassinum, $asnum'";
892
-	return $order;
875
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
876
+    if (is_array($_champ)) {
877
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]];
878
+    }
879
+    $boucle = &$boucles[$idb];
880
+    $texte = '0+' . $_champ;
881
+    $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
882
+    if ($suite !== "''") {
883
+        $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
884
+    }
885
+    $asnum = 'num' . ($boucle->order ? count($boucle->order) : '');
886
+    $boucle->select[] = $texte . " AS $asnum";
887
+
888
+    $orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ);
889
+    $orderassinum = trim($orderassinum, "'");
890
+
891
+    $order = "'$orderassinum, $asnum'";
892
+    return $order;
893 893
 }
894 894
 
895 895
 /**
@@ -910,35 +910,35 @@  discard block
 block discarded – undo
910 910
  * @return string|array Clause pour le Order by (array si erreur)
911 911
  */
912 912
 function calculer_critere_par_expression_sinum($idb, &$boucles, $crit, $tri, $champ) {
913
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
914
-	if (is_array($_champ)) {
915
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]];
916
-	}
917
-	$boucle = &$boucles[$idb];
918
-	$texte = '0+' . $_champ;
919
-	$suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
920
-	if ($suite !== "''") {
921
-		$texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
922
-	}
923
-
924
-	$as = false;
925
-	$select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS ";
926
-	foreach ($boucle->select as $s) {
927
-		if (strpos($s, $select) === 0) {
928
-			$as = trim(substr($s, strlen($select)));
929
-			if (!preg_match(',\W,', $as)) {
930
-				break;
931
-			}
932
-			$as = false;
933
-		}
934
-	}
935
-
936
-	if (!$as) {
937
-		$as = 'sinum' . ($boucle->order ? count($boucle->order) : '');
938
-		$boucle->select[] = $select . $as;
939
-	}
940
-	$order = "'$as'";
941
-	return $order;
913
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
914
+    if (is_array($_champ)) {
915
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]];
916
+    }
917
+    $boucle = &$boucles[$idb];
918
+    $texte = '0+' . $_champ;
919
+    $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
920
+    if ($suite !== "''") {
921
+        $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
922
+    }
923
+
924
+    $as = false;
925
+    $select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS ";
926
+    foreach ($boucle->select as $s) {
927
+        if (strpos($s, $select) === 0) {
928
+            $as = trim(substr($s, strlen($select)));
929
+            if (!preg_match(',\W,', $as)) {
930
+                break;
931
+            }
932
+            $as = false;
933
+        }
934
+    }
935
+
936
+    if (!$as) {
937
+        $as = 'sinum' . ($boucle->order ? count($boucle->order) : '');
938
+        $boucle->select[] = $select . $as;
939
+    }
940
+    $order = "'$as'";
941
+    return $order;
942 942
 }
943 943
 
944 944
 
@@ -958,14 +958,14 @@  discard block
 block discarded – undo
958 958
  * @return string|array Clause pour le Order by (array si erreur)
959 959
  */
960 960
 function calculer_critere_par_expression_multi($idb, &$boucles, $crit, $tri, $champ) {
961
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
962
-	if (is_array($_champ)) {
963
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]];
964
-	}
965
-	$boucle = &$boucles[$idb];
966
-	$boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\"";
967
-	$order = "'multi'";
968
-	return $order;
961
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
962
+    if (is_array($_champ)) {
963
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]];
964
+    }
965
+    $boucle = &$boucles[$idb];
966
+    $boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\"";
967
+    $order = "'multi'";
968
+    return $order;
969 969
 }
970 970
 
971 971
 /**
@@ -984,56 +984,56 @@  discard block
 block discarded – undo
984 984
  * @return array|string
985 985
  */
986 986
 function calculer_critere_par_champ($idb, &$boucles, $crit, $par, $raw = false) {
987
-	$boucle = &$boucles[$idb];
988
-	$desc = $boucle->show;
989
-
990
-	// le champ existe dans la table, pas de souci (le plus commun)
991
-	if (isset($desc['field'][$par])) {
992
-		$par = $boucle->id_table . '.' . $par;
993
-	}
994
-	// le champ est peut être une jointure
995
-	else {
996
-		$table = $table_alias = false; // toutes les tables de jointure possibles
997
-		$champ = $par;
998
-
999
-		// le champ demandé est une exception de jointure {par titre_mot}
1000
-		if (isset($GLOBALS['exceptions_des_jointures'][$par])) {
1001
-			[$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par];
1002
-		} // la table de jointure est explicitement indiquée {par truc.muche}
1003
-		elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) {
1004
-			[, $table, $champ] = $r;
1005
-			$table_alias = $table; // c'est peut-être un alias de table {par L1.titre}
1006
-			$table = table_objet_sql($table);
1007
-		}
1008
-
1009
-		// Si on connait la table d'arrivée, on la demande donc explicitement
1010
-		// Sinon on cherche le champ dans les tables possibles de jointures
1011
-		// Si la table est déjà dans le from, on la réutilise.
1012
-		if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) {
1013
-			$par = $infos['alias'] . '.' . $champ;
1014
-		} elseif (
1015
-			$boucle->jointures_explicites
1016
-			and $alias = trouver_jointure_champ($champ, $boucle, explode(' ', $boucle->jointures_explicites), false, $table)
1017
-		) {
1018
-			$par = $alias . '.' . $champ;
1019
-		} elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) {
1020
-			$par = $alias . '.' . $champ;
1021
-		// en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même)
1022
-		} elseif (
1023
-			$table_alias
1024
-			and isset($boucle->from[$table_alias])
1025
-			and $infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias])
1026
-		) {
1027
-			$par = $infos['alias'] . '.' . $champ;
1028
-		} elseif ($table) {
1029
-			// On avait table + champ, mais on ne les a pas trouvés
1030
-			return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
1031
-		} else {
1032
-			// Sinon tant pis, ca doit etre un champ synthetise (cf points)
1033
-		}
1034
-	}
1035
-
1036
-	return $raw ? $par : "'$par'";
987
+    $boucle = &$boucles[$idb];
988
+    $desc = $boucle->show;
989
+
990
+    // le champ existe dans la table, pas de souci (le plus commun)
991
+    if (isset($desc['field'][$par])) {
992
+        $par = $boucle->id_table . '.' . $par;
993
+    }
994
+    // le champ est peut être une jointure
995
+    else {
996
+        $table = $table_alias = false; // toutes les tables de jointure possibles
997
+        $champ = $par;
998
+
999
+        // le champ demandé est une exception de jointure {par titre_mot}
1000
+        if (isset($GLOBALS['exceptions_des_jointures'][$par])) {
1001
+            [$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par];
1002
+        } // la table de jointure est explicitement indiquée {par truc.muche}
1003
+        elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) {
1004
+            [, $table, $champ] = $r;
1005
+            $table_alias = $table; // c'est peut-être un alias de table {par L1.titre}
1006
+            $table = table_objet_sql($table);
1007
+        }
1008
+
1009
+        // Si on connait la table d'arrivée, on la demande donc explicitement
1010
+        // Sinon on cherche le champ dans les tables possibles de jointures
1011
+        // Si la table est déjà dans le from, on la réutilise.
1012
+        if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) {
1013
+            $par = $infos['alias'] . '.' . $champ;
1014
+        } elseif (
1015
+            $boucle->jointures_explicites
1016
+            and $alias = trouver_jointure_champ($champ, $boucle, explode(' ', $boucle->jointures_explicites), false, $table)
1017
+        ) {
1018
+            $par = $alias . '.' . $champ;
1019
+        } elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) {
1020
+            $par = $alias . '.' . $champ;
1021
+        // en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même)
1022
+        } elseif (
1023
+            $table_alias
1024
+            and isset($boucle->from[$table_alias])
1025
+            and $infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias])
1026
+        ) {
1027
+            $par = $infos['alias'] . '.' . $champ;
1028
+        } elseif ($table) {
1029
+            // On avait table + champ, mais on ne les a pas trouvés
1030
+            return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
1031
+        } else {
1032
+            // Sinon tant pis, ca doit etre un champ synthetise (cf points)
1033
+        }
1034
+    }
1035
+
1036
+    return $raw ? $par : "'$par'";
1037 1037
 }
1038 1038
 
1039 1039
 /**
@@ -1047,11 +1047,11 @@  discard block
 block discarded – undo
1047 1047
  * @return string Champ pour le compilateur si trouvé, tel que "'alias.champ'", sinon vide.
1048 1048
  */
1049 1049
 function critere_par_joint($table, $champ, &$boucle) {
1050
-	$t = array_search($table, $boucle->from);
1051
-	if (!$t) {
1052
-		$t = trouver_jointure_champ($champ, $boucle);
1053
-	}
1054
-	return !$t ? '' : ("'" . $t . '.' . $champ . "'");
1050
+    $t = array_search($table, $boucle->from);
1051
+    if (!$t) {
1052
+        $t = trouver_jointure_champ($champ, $boucle);
1053
+    }
1054
+    return !$t ? '' : ("'" . $t . '.' . $champ . "'");
1055 1055
 }
1056 1056
 
1057 1057
 /**
@@ -1076,33 +1076,33 @@  discard block
 block discarded – undo
1076 1076
  */
1077 1077
 function critere_inverse_dist($idb, &$boucles, $crit) {
1078 1078
 
1079
-	$boucle = &$boucles[$idb];
1080
-	// Classement par ordre inverse
1081
-	if ($crit->not) {
1082
-		critere_parinverse($idb, $boucles, $crit);
1083
-	} else {
1084
-		$order = "' DESC'";
1085
-		// Classement par ordre inverse fonction eventuelle de #ENV{...}
1086
-		if (isset($crit->param[0])) {
1087
-			$critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
1088
-			$order = "(($critere)?' DESC':'')";
1089
-		}
1090
-
1091
-		$n = is_countable($boucle->order) ? count($boucle->order) : 0;
1092
-		if (!$n) {
1093
-			if (isset($boucle->default_order[0])) {
1094
-				$boucle->default_order[0] .= ' . " DESC"';
1095
-			} else {
1096
-				$boucle->default_order[] = ' DESC';
1097
-			}
1098
-		} else {
1099
-			$t = $boucle->order[$n - 1] . " . $order";
1100
-			if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
1101
-				$t = $r[1] . $r[2];
1102
-			}
1103
-			$boucle->order[$n - 1] = $t;
1104
-		}
1105
-	}
1079
+    $boucle = &$boucles[$idb];
1080
+    // Classement par ordre inverse
1081
+    if ($crit->not) {
1082
+        critere_parinverse($idb, $boucles, $crit);
1083
+    } else {
1084
+        $order = "' DESC'";
1085
+        // Classement par ordre inverse fonction eventuelle de #ENV{...}
1086
+        if (isset($crit->param[0])) {
1087
+            $critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
1088
+            $order = "(($critere)?' DESC':'')";
1089
+        }
1090
+
1091
+        $n = is_countable($boucle->order) ? count($boucle->order) : 0;
1092
+        if (!$n) {
1093
+            if (isset($boucle->default_order[0])) {
1094
+                $boucle->default_order[0] .= ' . " DESC"';
1095
+            } else {
1096
+                $boucle->default_order[] = ' DESC';
1097
+            }
1098
+        } else {
1099
+            $t = $boucle->order[$n - 1] . " . $order";
1100
+            if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
1101
+                $t = $r[1] . $r[2];
1102
+            }
1103
+            $boucle->order[$n - 1] = $t;
1104
+        }
1105
+    }
1106 1106
 }
1107 1107
 
1108 1108
 /**
@@ -1113,137 +1113,137 @@  discard block
 block discarded – undo
1113 1113
  * @return void|array
1114 1114
  */
1115 1115
 function critere_par_ordre_liste_dist($idb, &$boucles, $crit) {
1116
-	$boucle = &$boucles[$idb];
1116
+    $boucle = &$boucles[$idb];
1117 1117
 
1118
-	$sens = $collecte = '';
1119
-	if ($crit->not) {
1120
-		$sens = " . ' DESC'";
1121
-	}
1118
+    $sens = $collecte = '';
1119
+    if ($crit->not) {
1120
+        $sens = " . ' DESC'";
1121
+    }
1122 1122
 
1123
-	$crit2 = clone $crit;
1124
-	$crit2->not = false;
1125
-	$crit2->param = [reset($crit->param)];
1126
-	$res = critere_parinverse($idb, $boucles, $crit2);
1123
+    $crit2 = clone $crit;
1124
+    $crit2->not = false;
1125
+    $crit2->param = [reset($crit->param)];
1126
+    $res = critere_parinverse($idb, $boucles, $crit2);
1127 1127
 
1128
-	// erreur ?
1129
-	if (is_array($res)) {
1130
-		return $res;
1131
-	}
1128
+    // erreur ?
1129
+    if (is_array($res)) {
1130
+        return $res;
1131
+    }
1132 1132
 
1133
-	$_order = array_pop($boucle->order);
1133
+    $_order = array_pop($boucle->order);
1134 1134
 
1135
-	$_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent);
1136
-	$boucle->order[] = "'FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste($_liste,'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens";
1135
+    $_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent);
1136
+    $boucle->order[] = "'FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste($_liste,'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens";
1137 1137
 }
1138 1138
 
1139 1139
 
1140 1140
 function critere_agenda_dist($idb, &$boucles, $crit) {
1141
-	$params = $crit->param;
1142
-
1143
-	if ((is_countable($params) ? count($params) : 0) < 1) {
1144
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1145
-	}
1146
-
1147
-	$boucle = &$boucles[$idb];
1148
-	$parent = $boucle->id_parent;
1149
-	$fields = $boucle->show['field'];
1150
-
1151
-	$date = array_shift($params);
1152
-	$type = array_shift($params);
1153
-
1154
-	// la valeur $type doit etre connue a la compilation
1155
-	// donc etre forcement reduite a un litteral unique dans le source
1156
-	$type = is_object($type[0]) ? $type[0]->texte : null;
1157
-
1158
-	// La valeur date doit designer un champ de la table SQL.
1159
-	// Si c'est un litteral unique dans le source, verifier a la compil,
1160
-	// sinon synthetiser le test de verif pour execution ulterieure
1161
-	// On prendra arbitrairement le premier champ si test negatif.
1162
-	if (((is_countable($date) ? count($date) : 0) == 1) and ($date[0]->type == 'texte')) {
1163
-		$date = $date[0]->texte;
1164
-		if (!isset($fields[$date])) {
1165
-			return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]];
1166
-		}
1167
-	} else {
1168
-		$a = calculer_liste($date, $idb, $boucles, $parent);
1169
-		$noms = array_keys($fields);
1170
-		$defaut = $noms[0];
1171
-		$noms = join(' ', $noms);
1172
-		# bien laisser 2 espaces avant $nom pour que strpos<>0
1173
-		$cond = "(\$a=strval($a))AND\nstrpos(\"  $noms \",\" \$a \")";
1174
-		$date = "'.(($cond)\n?\$a:\"$defaut\").'";
1175
-	}
1176
-	$annee = $params ? array_shift($params) : '';
1177
-	$annee = "\n" . 'sprintf("%04d", ($x = ' .
1178
-		calculer_liste($annee, $idb, $boucles, $parent) .
1179
-		') ? $x : date("Y"))';
1180
-
1181
-	$mois = $params ? array_shift($params) : '';
1182
-	$mois = "\n" . 'sprintf("%02d", ($x = ' .
1183
-		calculer_liste($mois, $idb, $boucles, $parent) .
1184
-		') ? $x : date("m"))';
1185
-
1186
-	$jour = $params ? array_shift($params) : '';
1187
-	$jour = "\n" . 'sprintf("%02d", ($x = ' .
1188
-		calculer_liste($jour, $idb, $boucles, $parent) .
1189
-		') ? $x : date("d"))';
1190
-
1191
-	$annee2 = $params ? array_shift($params) : '';
1192
-	$annee2 = "\n" . 'sprintf("%04d", ($x = ' .
1193
-		calculer_liste($annee2, $idb, $boucles, $parent) .
1194
-		') ? $x : date("Y"))';
1195
-
1196
-	$mois2 = $params ? array_shift($params) : '';
1197
-	$mois2 = "\n" . 'sprintf("%02d", ($x = ' .
1198
-		calculer_liste($mois2, $idb, $boucles, $parent) .
1199
-		') ? $x : date("m"))';
1200
-
1201
-	$jour2 = $params ? array_shift($params) : '';
1202
-	$jour2 = "\n" . 'sprintf("%02d", ($x = ' .
1203
-		calculer_liste($jour2, $idb, $boucles, $parent) .
1204
-		') ? $x : date("d"))';
1205
-
1206
-	$date = $boucle->id_table . ".$date";
1207
-
1208
-	$quote_end = ",'" . $boucle->sql_serveur . "','text'";
1209
-	if ($type == 'jour') {
1210
-		$boucle->where[] = [
1211
-			"'='",
1212
-			"'DATE_FORMAT($date, \'%Y%m%d\')'",
1213
-			("sql_quote($annee . $mois . $jour$quote_end)")
1214
-		];
1215
-	} elseif ($type == 'mois') {
1216
-		$boucle->where[] = [
1217
-			"'='",
1218
-			"'DATE_FORMAT($date, \'%Y%m\')'",
1219
-			("sql_quote($annee . $mois$quote_end)")
1220
-		];
1221
-	} elseif ($type == 'semaine') {
1222
-		$boucle->where[] = [
1223
-			"'AND'",
1224
-			[
1225
-				"'>='",
1226
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1227
-				("date_debut_semaine($annee, $mois, $jour)")
1228
-			],
1229
-			[
1230
-				"'<='",
1231
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1232
-				("date_fin_semaine($annee, $mois, $jour)")
1233
-			]
1234
-		];
1235
-	} elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) {
1236
-		$boucle->where[] = [
1237
-			"'AND'",
1238
-			[
1239
-				"'>='",
1240
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1241
-				("sql_quote($annee . $mois . $jour$quote_end)")
1242
-			],
1243
-			["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")]
1244
-		];
1245
-	}
1246
-	// sinon on prend tout
1141
+    $params = $crit->param;
1142
+
1143
+    if ((is_countable($params) ? count($params) : 0) < 1) {
1144
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1145
+    }
1146
+
1147
+    $boucle = &$boucles[$idb];
1148
+    $parent = $boucle->id_parent;
1149
+    $fields = $boucle->show['field'];
1150
+
1151
+    $date = array_shift($params);
1152
+    $type = array_shift($params);
1153
+
1154
+    // la valeur $type doit etre connue a la compilation
1155
+    // donc etre forcement reduite a un litteral unique dans le source
1156
+    $type = is_object($type[0]) ? $type[0]->texte : null;
1157
+
1158
+    // La valeur date doit designer un champ de la table SQL.
1159
+    // Si c'est un litteral unique dans le source, verifier a la compil,
1160
+    // sinon synthetiser le test de verif pour execution ulterieure
1161
+    // On prendra arbitrairement le premier champ si test negatif.
1162
+    if (((is_countable($date) ? count($date) : 0) == 1) and ($date[0]->type == 'texte')) {
1163
+        $date = $date[0]->texte;
1164
+        if (!isset($fields[$date])) {
1165
+            return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]];
1166
+        }
1167
+    } else {
1168
+        $a = calculer_liste($date, $idb, $boucles, $parent);
1169
+        $noms = array_keys($fields);
1170
+        $defaut = $noms[0];
1171
+        $noms = join(' ', $noms);
1172
+        # bien laisser 2 espaces avant $nom pour que strpos<>0
1173
+        $cond = "(\$a=strval($a))AND\nstrpos(\"  $noms \",\" \$a \")";
1174
+        $date = "'.(($cond)\n?\$a:\"$defaut\").'";
1175
+    }
1176
+    $annee = $params ? array_shift($params) : '';
1177
+    $annee = "\n" . 'sprintf("%04d", ($x = ' .
1178
+        calculer_liste($annee, $idb, $boucles, $parent) .
1179
+        ') ? $x : date("Y"))';
1180
+
1181
+    $mois = $params ? array_shift($params) : '';
1182
+    $mois = "\n" . 'sprintf("%02d", ($x = ' .
1183
+        calculer_liste($mois, $idb, $boucles, $parent) .
1184
+        ') ? $x : date("m"))';
1185
+
1186
+    $jour = $params ? array_shift($params) : '';
1187
+    $jour = "\n" . 'sprintf("%02d", ($x = ' .
1188
+        calculer_liste($jour, $idb, $boucles, $parent) .
1189
+        ') ? $x : date("d"))';
1190
+
1191
+    $annee2 = $params ? array_shift($params) : '';
1192
+    $annee2 = "\n" . 'sprintf("%04d", ($x = ' .
1193
+        calculer_liste($annee2, $idb, $boucles, $parent) .
1194
+        ') ? $x : date("Y"))';
1195
+
1196
+    $mois2 = $params ? array_shift($params) : '';
1197
+    $mois2 = "\n" . 'sprintf("%02d", ($x = ' .
1198
+        calculer_liste($mois2, $idb, $boucles, $parent) .
1199
+        ') ? $x : date("m"))';
1200
+
1201
+    $jour2 = $params ? array_shift($params) : '';
1202
+    $jour2 = "\n" . 'sprintf("%02d", ($x = ' .
1203
+        calculer_liste($jour2, $idb, $boucles, $parent) .
1204
+        ') ? $x : date("d"))';
1205
+
1206
+    $date = $boucle->id_table . ".$date";
1207
+
1208
+    $quote_end = ",'" . $boucle->sql_serveur . "','text'";
1209
+    if ($type == 'jour') {
1210
+        $boucle->where[] = [
1211
+            "'='",
1212
+            "'DATE_FORMAT($date, \'%Y%m%d\')'",
1213
+            ("sql_quote($annee . $mois . $jour$quote_end)")
1214
+        ];
1215
+    } elseif ($type == 'mois') {
1216
+        $boucle->where[] = [
1217
+            "'='",
1218
+            "'DATE_FORMAT($date, \'%Y%m\')'",
1219
+            ("sql_quote($annee . $mois$quote_end)")
1220
+        ];
1221
+    } elseif ($type == 'semaine') {
1222
+        $boucle->where[] = [
1223
+            "'AND'",
1224
+            [
1225
+                "'>='",
1226
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1227
+                ("date_debut_semaine($annee, $mois, $jour)")
1228
+            ],
1229
+            [
1230
+                "'<='",
1231
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1232
+                ("date_fin_semaine($annee, $mois, $jour)")
1233
+            ]
1234
+        ];
1235
+    } elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) {
1236
+        $boucle->where[] = [
1237
+            "'AND'",
1238
+            [
1239
+                "'>='",
1240
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1241
+                ("sql_quote($annee . $mois . $jour$quote_end)")
1242
+            ],
1243
+            ["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")]
1244
+        ];
1245
+    }
1246
+    // sinon on prend tout
1247 1247
 }
1248 1248
 
1249 1249
 
@@ -1268,33 +1268,33 @@  discard block
 block discarded – undo
1268 1268
  * @return void
1269 1269
  **/
1270 1270
 function calculer_critere_parties($idb, &$boucles, $crit) {
1271
-	$boucle = &$boucles[$idb];
1272
-	$a1 = $crit->param[0];
1273
-	$a2 = $crit->param[1];
1274
-	$op = $crit->op;
1275
-
1276
-	[$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1);
1277
-	[$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2);
1278
-
1279
-	if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) {
1280
-		$boucle->limit = $a11 . ',' . $a21;
1281
-	} else {
1282
-		// 3 dans {1/3}, {2,3} ou {1,n-3}
1283
-		$boucle->total_parties = ($a21 != 'n') ? $a21 : $a22;
1284
-		// 2 dans {2/3}, {2,5}, {n-2,1}
1285
-		$partie = ($a11 != 'n') ? $a11 : $a12;
1286
-		$mode = (($op == '/') ? '/' :
1287
-			(($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+'));
1288
-		// cas simple {0,#ENV{truc}} compilons le en LIMIT :
1289
-		if ($a11 !== 'n' and $a21 !== 'n' and $mode == '++' and $op == ',') {
1290
-			$boucle->limit =
1291
-				(is_numeric($a11) ? "'$a11'" : $a11)
1292
-				. ".','."
1293
-				. (is_numeric($a21) ? "'$a21'" : $a21);
1294
-		} else {
1295
-			calculer_parties($boucles, $idb, $partie, $mode);
1296
-		}
1297
-	}
1271
+    $boucle = &$boucles[$idb];
1272
+    $a1 = $crit->param[0];
1273
+    $a2 = $crit->param[1];
1274
+    $op = $crit->op;
1275
+
1276
+    [$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1);
1277
+    [$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2);
1278
+
1279
+    if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) {
1280
+        $boucle->limit = $a11 . ',' . $a21;
1281
+    } else {
1282
+        // 3 dans {1/3}, {2,3} ou {1,n-3}
1283
+        $boucle->total_parties = ($a21 != 'n') ? $a21 : $a22;
1284
+        // 2 dans {2/3}, {2,5}, {n-2,1}
1285
+        $partie = ($a11 != 'n') ? $a11 : $a12;
1286
+        $mode = (($op == '/') ? '/' :
1287
+            (($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+'));
1288
+        // cas simple {0,#ENV{truc}} compilons le en LIMIT :
1289
+        if ($a11 !== 'n' and $a21 !== 'n' and $mode == '++' and $op == ',') {
1290
+            $boucle->limit =
1291
+                (is_numeric($a11) ? "'$a11'" : $a11)
1292
+                . ".','."
1293
+                . (is_numeric($a21) ? "'$a21'" : $a21);
1294
+        } else {
1295
+            calculer_parties($boucles, $idb, $partie, $mode);
1296
+        }
1297
+    }
1298 1298
 }
1299 1299
 
1300 1300
 /**
@@ -1322,63 +1322,63 @@  discard block
 block discarded – undo
1322 1322
  * @return void
1323 1323
  **/
1324 1324
 function calculer_parties(&$boucles, $id_boucle, $debut, $mode) {
1325
-	$total_parties = $boucles[$id_boucle]->total_parties;
1326
-
1327
-	preg_match(',([+-/p])([+-/])?,', $mode, $regs);
1328
-	[, $op1, $op2] = array_pad($regs, 3, null);
1329
-	$nombre_boucle = "\$Numrows['$id_boucle']['total']";
1330
-	// {1/3}
1331
-	if ($op1 == '/') {
1332
-		$pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)";
1333
-		$totpos = is_numeric($total_parties) ? ($total_parties) :
1334
-			"($total_parties ? $total_parties : 1)";
1335
-		$fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1";
1336
-		$debut = !$pmoins1 ? 0 : "ceil(($nombre_boucle * $pmoins1)/$totpos);";
1337
-	} else {
1338
-		// cas {n-1,x}
1339
-		if ($op1 == '-') {
1340
-			$debut = "$nombre_boucle - $debut;";
1341
-		}
1342
-
1343
-		// cas {x,n-1}
1344
-		if ($op2 == '-') {
1345
-			$fin = '$debut_boucle + ' . $nombre_boucle . ' - '
1346
-				. (is_numeric($total_parties) ? ($total_parties + 1) :
1347
-					($total_parties . ' - 1'));
1348
-		} else {
1349
-			// {x,1} ou {pagination}
1350
-			$fin = '$debut_boucle'
1351
-				. (is_numeric($total_parties) ?
1352
-					(($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) :
1353
-					('+' . $total_parties . ' - 1'));
1354
-		}
1355
-
1356
-		// {pagination}, gerer le debut_xx=-1 pour tout voir
1357
-		if ($op1 == 'p') {
1358
-			$debut .= ";\n	\$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))";
1359
-			$debut .= ";\n	\$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))";
1360
-			$fin = "(\$tout ? $nombre_boucle : $fin)";
1361
-		}
1362
-	}
1363
-
1364
-	// Notes :
1365
-	// $debut_boucle et $fin_boucle sont les indices SQL du premier
1366
-	// et du dernier demandes dans la boucle : 0 pour le premier,
1367
-	// n-1 pour le dernier ; donc total_boucle = 1 + debut - fin
1368
-	// Utiliser min pour rabattre $fin_boucle sur total_boucle.
1369
-
1370
-	$boucles[$id_boucle]->mode_partie = "\n\t"
1371
-		. '$debut_boucle = ' . $debut . ";\n	"
1372
-		. "\$debut_boucle = intval(\$debut_boucle);\n	"
1373
-		. '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n	"
1374
-		. '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n	"
1375
-		. '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);'
1376
-		. "\n\tif (\$debut_boucle>0"
1377
-		. " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']"
1378
-		. " AND \$iter->seek(\$debut_boucle,'continue'))"
1379
-		. "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t";
1380
-
1381
-	$boucles[$id_boucle]->partie = "
1325
+    $total_parties = $boucles[$id_boucle]->total_parties;
1326
+
1327
+    preg_match(',([+-/p])([+-/])?,', $mode, $regs);
1328
+    [, $op1, $op2] = array_pad($regs, 3, null);
1329
+    $nombre_boucle = "\$Numrows['$id_boucle']['total']";
1330
+    // {1/3}
1331
+    if ($op1 == '/') {
1332
+        $pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)";
1333
+        $totpos = is_numeric($total_parties) ? ($total_parties) :
1334
+            "($total_parties ? $total_parties : 1)";
1335
+        $fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1";
1336
+        $debut = !$pmoins1 ? 0 : "ceil(($nombre_boucle * $pmoins1)/$totpos);";
1337
+    } else {
1338
+        // cas {n-1,x}
1339
+        if ($op1 == '-') {
1340
+            $debut = "$nombre_boucle - $debut;";
1341
+        }
1342
+
1343
+        // cas {x,n-1}
1344
+        if ($op2 == '-') {
1345
+            $fin = '$debut_boucle + ' . $nombre_boucle . ' - '
1346
+                . (is_numeric($total_parties) ? ($total_parties + 1) :
1347
+                    ($total_parties . ' - 1'));
1348
+        } else {
1349
+            // {x,1} ou {pagination}
1350
+            $fin = '$debut_boucle'
1351
+                . (is_numeric($total_parties) ?
1352
+                    (($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) :
1353
+                    ('+' . $total_parties . ' - 1'));
1354
+        }
1355
+
1356
+        // {pagination}, gerer le debut_xx=-1 pour tout voir
1357
+        if ($op1 == 'p') {
1358
+            $debut .= ";\n	\$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))";
1359
+            $debut .= ";\n	\$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))";
1360
+            $fin = "(\$tout ? $nombre_boucle : $fin)";
1361
+        }
1362
+    }
1363
+
1364
+    // Notes :
1365
+    // $debut_boucle et $fin_boucle sont les indices SQL du premier
1366
+    // et du dernier demandes dans la boucle : 0 pour le premier,
1367
+    // n-1 pour le dernier ; donc total_boucle = 1 + debut - fin
1368
+    // Utiliser min pour rabattre $fin_boucle sur total_boucle.
1369
+
1370
+    $boucles[$id_boucle]->mode_partie = "\n\t"
1371
+        . '$debut_boucle = ' . $debut . ";\n	"
1372
+        . "\$debut_boucle = intval(\$debut_boucle);\n	"
1373
+        . '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n	"
1374
+        . '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n	"
1375
+        . '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);'
1376
+        . "\n\tif (\$debut_boucle>0"
1377
+        . " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']"
1378
+        . " AND \$iter->seek(\$debut_boucle,'continue'))"
1379
+        . "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t";
1380
+
1381
+    $boucles[$id_boucle]->partie = "
1382 1382
 		if (\$Numrows['$id_boucle']['compteur_boucle'] <= \$debut_boucle) continue;
1383 1383
 		if (\$Numrows['$id_boucle']['compteur_boucle']-1 > \$fin_boucle) break;";
1384 1384
 }
@@ -1395,26 +1395,26 @@  discard block
 block discarded – undo
1395 1395
  * @return array          Valeur de l'élément (peut être une expression PHP), Nombre soustrait
1396 1396
  **/
1397 1397
 function calculer_critere_parties_aux($idb, &$boucles, $param) {
1398
-	if ($param[0]->type != 'texte') {
1399
-		$a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent);
1400
-		if (isset($param[1]->texte)) {
1401
-			preg_match(',^\s*(-([0-9]+))?\s*$,', $param[1]->texte, $m);
1402
-
1403
-			return ["intval($a1)", ((isset($m[2]) and $m[2]) ? $m[2] : 0)];
1404
-		} else {
1405
-			return ["intval($a1)", 0];
1406
-		}
1407
-	} else {
1408
-		preg_match(',^\s*(([0-9]+)|n)\s*(-\s*([0-9]+)?\s*)?$,', $param[0]->texte, $m);
1409
-		$a1 = $m[1];
1410
-		if (empty($m[3])) {
1411
-			return [$a1, 0];
1412
-		} elseif (!empty($m[4])) {
1413
-			return [$a1, $m[4]];
1414
-		} else {
1415
-			return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)];
1416
-		}
1417
-	}
1398
+    if ($param[0]->type != 'texte') {
1399
+        $a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent);
1400
+        if (isset($param[1]->texte)) {
1401
+            preg_match(',^\s*(-([0-9]+))?\s*$,', $param[1]->texte, $m);
1402
+
1403
+            return ["intval($a1)", ((isset($m[2]) and $m[2]) ? $m[2] : 0)];
1404
+        } else {
1405
+            return ["intval($a1)", 0];
1406
+        }
1407
+    } else {
1408
+        preg_match(',^\s*(([0-9]+)|n)\s*(-\s*([0-9]+)?\s*)?$,', $param[0]->texte, $m);
1409
+        $a1 = $m[1];
1410
+        if (empty($m[3])) {
1411
+            return [$a1, 0];
1412
+        } elseif (!empty($m[4])) {
1413
+            return [$a1, $m[4]];
1414
+        } else {
1415
+            return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)];
1416
+        }
1417
+    }
1418 1418
 }
1419 1419
 
1420 1420
 
@@ -1441,47 +1441,47 @@  discard block
 block discarded – undo
1441 1441
  *     array : Erreur sur un des critères
1442 1442
  **/
1443 1443
 function calculer_criteres($idb, &$boucles) {
1444
-	$msg = '';
1445
-	$boucle = $boucles[$idb];
1446
-	$table = strtoupper($boucle->type_requete);
1447
-	$serveur = strtolower($boucle->sql_serveur);
1448
-
1449
-	$defaut = charger_fonction('DEFAUT', 'calculer_critere');
1450
-	// s'il y avait une erreur de syntaxe, propager cette info
1451
-	if (!is_array($boucle->criteres)) {
1452
-		return [];
1453
-	}
1454
-
1455
-	foreach ($boucle->criteres as $crit) {
1456
-		$critere = $crit->op;
1457
-		// critere personnalise ?
1458
-		if (
1459
-			(!$serveur or
1460
-				((!function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere))
1461
-					and (!function_exists($f = $f . '_dist'))
1462
-					and (!function_exists($f = 'critere_' . $serveur . '_' . $critere))
1463
-					and (!function_exists($f = $f . '_dist'))
1464
-				)
1465
-			)
1466
-			and (!function_exists($f = 'critere_' . $table . '_' . $critere))
1467
-			and (!function_exists($f = $f . '_dist'))
1468
-			and (!function_exists($f = 'critere_' . $critere))
1469
-			and (!function_exists($f = $f . '_dist'))
1470
-		) {
1471
-			// fonction critere standard
1472
-			$f = $defaut;
1473
-		}
1474
-		// compile le critere
1475
-		$res = $f($idb, $boucles, $crit);
1476
-
1477
-		// Gestion centralisee des erreurs pour pouvoir propager
1478
-		if (is_array($res)) {
1479
-			$msg = $res;
1480
-			erreur_squelette($msg, $boucle);
1481
-		}
1482
-	}
1483
-
1484
-	return $msg;
1444
+    $msg = '';
1445
+    $boucle = $boucles[$idb];
1446
+    $table = strtoupper($boucle->type_requete);
1447
+    $serveur = strtolower($boucle->sql_serveur);
1448
+
1449
+    $defaut = charger_fonction('DEFAUT', 'calculer_critere');
1450
+    // s'il y avait une erreur de syntaxe, propager cette info
1451
+    if (!is_array($boucle->criteres)) {
1452
+        return [];
1453
+    }
1454
+
1455
+    foreach ($boucle->criteres as $crit) {
1456
+        $critere = $crit->op;
1457
+        // critere personnalise ?
1458
+        if (
1459
+            (!$serveur or
1460
+                ((!function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere))
1461
+                    and (!function_exists($f = $f . '_dist'))
1462
+                    and (!function_exists($f = 'critere_' . $serveur . '_' . $critere))
1463
+                    and (!function_exists($f = $f . '_dist'))
1464
+                )
1465
+            )
1466
+            and (!function_exists($f = 'critere_' . $table . '_' . $critere))
1467
+            and (!function_exists($f = $f . '_dist'))
1468
+            and (!function_exists($f = 'critere_' . $critere))
1469
+            and (!function_exists($f = $f . '_dist'))
1470
+        ) {
1471
+            // fonction critere standard
1472
+            $f = $defaut;
1473
+        }
1474
+        // compile le critere
1475
+        $res = $f($idb, $boucles, $crit);
1476
+
1477
+        // Gestion centralisee des erreurs pour pouvoir propager
1478
+        if (is_array($res)) {
1479
+            $msg = $res;
1480
+            erreur_squelette($msg, $boucle);
1481
+        }
1482
+    }
1483
+
1484
+    return $msg;
1485 1485
 }
1486 1486
 
1487 1487
 /**
@@ -1496,11 +1496,11 @@  discard block
 block discarded – undo
1496 1496
  * @return string         Code compilé rééchappé
1497 1497
  */
1498 1498
 function kwote($lisp, $serveur = '', $type = '') {
1499
-	if (preg_match(_CODE_QUOTE, $lisp, $r)) {
1500
-		return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"';
1501
-	} else {
1502
-		return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')";
1503
-	}
1499
+    if (preg_match(_CODE_QUOTE, $lisp, $r)) {
1500
+        return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"';
1501
+    } else {
1502
+        return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')";
1503
+    }
1504 1504
 }
1505 1505
 
1506 1506
 
@@ -1519,81 +1519,81 @@  discard block
 block discarded – undo
1519 1519
  * @return void|array
1520 1520
  **/
1521 1521
 function critere_IN_dist($idb, &$boucles, $crit) {
1522
-	$r = calculer_critere_infixe($idb, $boucles, $crit);
1523
-	if (!$r) {
1524
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1525
-	}
1526
-	[$arg, $op, $val, $col, $where_complement] = $r;
1527
-
1528
-	$in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col);
1529
-
1530
-	//	inserer la condition; exemple: {id_mot ?IN (66, 62, 64)}
1531
-	$where = $in;
1532
-	if ($crit->cond) {
1533
-		$pred = calculer_argument_precedent($idb, $col, $boucles);
1534
-		$where = ["'?'", $pred, $where, "''"];
1535
-		if ($where_complement) { // condition annexe du type "AND (objet='article')"
1536
-		$where_complement = ["'?'", $pred, $where_complement, "''"];
1537
-		}
1538
-	}
1539
-	if ($crit->exclus) {
1540
-		if (!preg_match(',^L[0-9]+[.],', $arg)) {
1541
-			$where = ["'NOT'", $where];
1542
-		} else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1543
-			// c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1544
-		{
1545
-			$where = [
1546
-				"'NOT'",
1547
-				[
1548
-					"'IN'",
1549
-					"'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1550
-					["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1551
-				]
1552
-			];
1553
-		}
1554
-	}
1555
-
1556
-	$boucles[$idb]->where[] = $where;
1557
-	if ($where_complement) { // condition annexe du type "AND (objet='article')"
1558
-	$boucles[$idb]->where[] = $where_complement;
1559
-	}
1522
+    $r = calculer_critere_infixe($idb, $boucles, $crit);
1523
+    if (!$r) {
1524
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1525
+    }
1526
+    [$arg, $op, $val, $col, $where_complement] = $r;
1527
+
1528
+    $in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col);
1529
+
1530
+    //	inserer la condition; exemple: {id_mot ?IN (66, 62, 64)}
1531
+    $where = $in;
1532
+    if ($crit->cond) {
1533
+        $pred = calculer_argument_precedent($idb, $col, $boucles);
1534
+        $where = ["'?'", $pred, $where, "''"];
1535
+        if ($where_complement) { // condition annexe du type "AND (objet='article')"
1536
+        $where_complement = ["'?'", $pred, $where_complement, "''"];
1537
+        }
1538
+    }
1539
+    if ($crit->exclus) {
1540
+        if (!preg_match(',^L[0-9]+[.],', $arg)) {
1541
+            $where = ["'NOT'", $where];
1542
+        } else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1543
+            // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1544
+        {
1545
+            $where = [
1546
+                "'NOT'",
1547
+                [
1548
+                    "'IN'",
1549
+                    "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1550
+                    ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1551
+                ]
1552
+            ];
1553
+        }
1554
+    }
1555
+
1556
+    $boucles[$idb]->where[] = $where;
1557
+    if ($where_complement) { // condition annexe du type "AND (objet='article')"
1558
+    $boucles[$idb]->where[] = $where_complement;
1559
+    }
1560 1560
 }
1561 1561
 
1562 1562
 function critere_IN_cas($idb, &$boucles, $crit2, $arg, $op, $val, $col) {
1563
-	static $num = [];
1564
-	$descr = $boucles[$idb]->descr;
1565
-	$cpt = &$num[$descr['nom']][$descr['gram']][$idb];
1566
-
1567
-	$var = '$in' . $cpt++;
1568
-	$x = "\n\t$var = array();";
1569
-	foreach ($val as $k => $v) {
1570
-		if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) {
1571
-			// optimiser le traitement des constantes
1572
-			if (is_numeric($r[2])) {
1573
-				$x .= "\n\t$var" . "[]= $r[2];";
1574
-			} else {
1575
-				$x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';';
1576
-			}
1577
-		} else {
1578
-			// Pour permettre de passer des tableaux de valeurs
1579
-			// on repere l'utilisation brute de #ENV**{X},
1580
-			// c'est-a-dire sa  traduction en ($PILE[0][X]).
1581
-			// et on deballe mais en rajoutant l'anti XSS
1582
-			$x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);";
1583
-		}
1584
-	}
1585
-
1586
-	$boucles[$idb]->in .= $x;
1587
-
1588
-	// inserer le tri par defaut selon les ordres du IN ...
1589
-	// avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp)
1590
-	// et que l'on limite donc strictement aux cas necessaires :
1591
-	// si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle
1592
-	if (!$crit2) {
1593
-		$boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))";
1594
-	}
1595
-
1596
-	return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')';
1563
+    static $num = [];
1564
+    $descr = $boucles[$idb]->descr;
1565
+    $cpt = &$num[$descr['nom']][$descr['gram']][$idb];
1566
+
1567
+    $var = '$in' . $cpt++;
1568
+    $x = "\n\t$var = array();";
1569
+    foreach ($val as $k => $v) {
1570
+        if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) {
1571
+            // optimiser le traitement des constantes
1572
+            if (is_numeric($r[2])) {
1573
+                $x .= "\n\t$var" . "[]= $r[2];";
1574
+            } else {
1575
+                $x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';';
1576
+            }
1577
+        } else {
1578
+            // Pour permettre de passer des tableaux de valeurs
1579
+            // on repere l'utilisation brute de #ENV**{X},
1580
+            // c'est-a-dire sa  traduction en ($PILE[0][X]).
1581
+            // et on deballe mais en rajoutant l'anti XSS
1582
+            $x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);";
1583
+        }
1584
+    }
1585
+
1586
+    $boucles[$idb]->in .= $x;
1587
+
1588
+    // inserer le tri par defaut selon les ordres du IN ...
1589
+    // avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp)
1590
+    // et que l'on limite donc strictement aux cas necessaires :
1591
+    // si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle
1592
+    if (!$crit2) {
1593
+        $boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))";
1594
+    }
1595
+
1596
+    return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')';
1597 1597
 }
1598 1598
 
1599 1599
 /**
@@ -1609,22 +1609,22 @@  discard block
 block discarded – undo
1609 1609
  * @return void
1610 1610
  */
1611 1611
 function critere_where_dist($idb, &$boucles, $crit) {
1612
-	$boucle = &$boucles[$idb];
1613
-	if (isset($crit->param[0])) {
1614
-		$_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1615
-	} else {
1616
-		$_where = 'spip_sanitize_from_request(@$Pile[0]["where"],"where","vide")';
1617
-	}
1618
-
1619
-	if ($crit->cond) {
1620
-		$_where = "((\$zzw = $_where) ? \$zzw : '')";
1621
-	}
1622
-
1623
-	if ($crit->not) {
1624
-		$_where = "array('NOT',$_where)";
1625
-	}
1626
-
1627
-	$boucle->where[] = $_where;
1612
+    $boucle = &$boucles[$idb];
1613
+    if (isset($crit->param[0])) {
1614
+        $_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1615
+    } else {
1616
+        $_where = 'spip_sanitize_from_request(@$Pile[0]["where"],"where","vide")';
1617
+    }
1618
+
1619
+    if ($crit->cond) {
1620
+        $_where = "((\$zzw = $_where) ? \$zzw : '')";
1621
+    }
1622
+
1623
+    if ($crit->not) {
1624
+        $_where = "array('NOT',$_where)";
1625
+    }
1626
+
1627
+    $boucle->where[] = $_where;
1628 1628
 }
1629 1629
 
1630 1630
 /**
@@ -1652,31 +1652,31 @@  discard block
 block discarded – undo
1652 1652
  * @return void
1653 1653
  */
1654 1654
 function critere_id__dist($idb, &$boucles, $crit) {
1655
-	/** @var Boucle $boucle */
1656
-	$boucle = $boucles[$idb];
1657
-
1658
-	$champs = lister_champs_id_conditionnel(
1659
-		$boucle->show['table'],
1660
-		$boucle->show,
1661
-		$boucle->sql_serveur
1662
-	);
1663
-
1664
-	// ne pas tenir compte des critères identiques déjà présents.
1665
-	if (!empty($boucle->modificateur['criteres'])) {
1666
-		$champs = array_diff($champs, array_keys($boucle->modificateur['criteres']));
1667
-	}
1668
-	// nous aider en mode debug.
1669
-	$boucle->debug[] = 'id_ : ' . implode(', ', $champs);
1670
-	$boucle->modificateur['id_'] = $champs;
1671
-
1672
-	// créer un critère {id_xxx?} de chaque champ retenu
1673
-	foreach ($champs as $champ) {
1674
-		$critere_id_table = new Critere();
1675
-		$critere_id_table->op = $champ;
1676
-		$critere_id_table->cond = '?';
1677
-		$critere_id_table->ligne = $crit->ligne;
1678
-		calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table);
1679
-	}
1655
+    /** @var Boucle $boucle */
1656
+    $boucle = $boucles[$idb];
1657
+
1658
+    $champs = lister_champs_id_conditionnel(
1659
+        $boucle->show['table'],
1660
+        $boucle->show,
1661
+        $boucle->sql_serveur
1662
+    );
1663
+
1664
+    // ne pas tenir compte des critères identiques déjà présents.
1665
+    if (!empty($boucle->modificateur['criteres'])) {
1666
+        $champs = array_diff($champs, array_keys($boucle->modificateur['criteres']));
1667
+    }
1668
+    // nous aider en mode debug.
1669
+    $boucle->debug[] = 'id_ : ' . implode(', ', $champs);
1670
+    $boucle->modificateur['id_'] = $champs;
1671
+
1672
+    // créer un critère {id_xxx?} de chaque champ retenu
1673
+    foreach ($champs as $champ) {
1674
+        $critere_id_table = new Critere();
1675
+        $critere_id_table->op = $champ;
1676
+        $critere_id_table->cond = '?';
1677
+        $critere_id_table->ligne = $crit->ligne;
1678
+        calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table);
1679
+    }
1680 1680
 }
1681 1681
 
1682 1682
 /**
@@ -1696,75 +1696,75 @@  discard block
 block discarded – undo
1696 1696
  * @return array Liste de nom de champs (tel que id_article, id_mot, id_parent ...)
1697 1697
  */
1698 1698
 function lister_champs_id_conditionnel($table, $desc = null, $serveur = '') {
1699
-	// calculer la description de la table
1700
-	if (!is_array($desc)) {
1701
-		$desc = description_table($table, $serveur);
1702
-	}
1703
-	if (!$desc) {
1704
-		return [];
1705
-	}
1706
-
1707
-	// Les champs id_xx de la table demandée
1708
-	$champs = array_filter(
1709
-		array_keys($desc['field']),
1710
-		fn($champ) => strpos($champ, 'id_') === 0 or (in_array($champ, ['objet']))
1711
-	);
1712
-
1713
-	// Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute.
1714
-	if (
1715
-		in_array('id_rubrique', $champs)
1716
-		and !in_array('id_secteur', $champs)
1717
-	) {
1718
-		$champs[] = 'id_secteur';
1719
-	}
1720
-
1721
-	// On ne fera pas mieux pour les tables d’un autre serveur
1722
-	if ($serveur) {
1723
-		return $champs;
1724
-	}
1725
-
1726
-	$primary = false;
1727
-	$associable = false;
1728
-	include_spip('action/editer_liens');
1729
-
1730
-	if (isset($desc['type'])) {
1731
-		$primary = id_table_objet($desc['type']);
1732
-		$associable = objet_associable($desc['type']);
1733
-	}
1734
-	if (isset($desc['field']['id_objet']) and isset($desc['field']['objet'])) {
1735
-		$associable = true;
1736
-	}
1737
-
1738
-	// liste de toutes les tables principales, sauf la notre
1739
-	$tables = lister_tables_objets_sql();
1740
-	unset($tables[$table]);
1741
-
1742
-	foreach ($tables as $_table => $_desc) {
1743
-		if (
1744
-			$associable
1745
-			or ($primary and in_array($primary, array_keys($_desc['field'])))
1746
-			or objet_associable($_desc['type'])
1747
-		) {
1748
-			$champs[] = id_table_objet($_table);
1749
-		}
1750
-	}
1751
-	$champs = array_values(array_unique($champs));
1752
-
1753
-	// Exclusions de certains id
1754
-	$exclusions = pipeline(
1755
-		'exclure_id_conditionnel',
1756
-		[
1757
-			'args' => [
1758
-				'table' => $table,
1759
-				'id_table_objet' => $primary,
1760
-				'associable' => $associable,
1761
-			],
1762
-			'data' => [],
1763
-		]
1764
-	);
1765
-	$champs = array_diff($champs, $exclusions);
1766
-
1767
-	return $champs;
1699
+    // calculer la description de la table
1700
+    if (!is_array($desc)) {
1701
+        $desc = description_table($table, $serveur);
1702
+    }
1703
+    if (!$desc) {
1704
+        return [];
1705
+    }
1706
+
1707
+    // Les champs id_xx de la table demandée
1708
+    $champs = array_filter(
1709
+        array_keys($desc['field']),
1710
+        fn($champ) => strpos($champ, 'id_') === 0 or (in_array($champ, ['objet']))
1711
+    );
1712
+
1713
+    // Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute.
1714
+    if (
1715
+        in_array('id_rubrique', $champs)
1716
+        and !in_array('id_secteur', $champs)
1717
+    ) {
1718
+        $champs[] = 'id_secteur';
1719
+    }
1720
+
1721
+    // On ne fera pas mieux pour les tables d’un autre serveur
1722
+    if ($serveur) {
1723
+        return $champs;
1724
+    }
1725
+
1726
+    $primary = false;
1727
+    $associable = false;
1728
+    include_spip('action/editer_liens');
1729
+
1730
+    if (isset($desc['type'])) {
1731
+        $primary = id_table_objet($desc['type']);
1732
+        $associable = objet_associable($desc['type']);
1733
+    }
1734
+    if (isset($desc['field']['id_objet']) and isset($desc['field']['objet'])) {
1735
+        $associable = true;
1736
+    }
1737
+
1738
+    // liste de toutes les tables principales, sauf la notre
1739
+    $tables = lister_tables_objets_sql();
1740
+    unset($tables[$table]);
1741
+
1742
+    foreach ($tables as $_table => $_desc) {
1743
+        if (
1744
+            $associable
1745
+            or ($primary and in_array($primary, array_keys($_desc['field'])))
1746
+            or objet_associable($_desc['type'])
1747
+        ) {
1748
+            $champs[] = id_table_objet($_table);
1749
+        }
1750
+    }
1751
+    $champs = array_values(array_unique($champs));
1752
+
1753
+    // Exclusions de certains id
1754
+    $exclusions = pipeline(
1755
+        'exclure_id_conditionnel',
1756
+        [
1757
+            'args' => [
1758
+                'table' => $table,
1759
+                'id_table_objet' => $primary,
1760
+                'associable' => $associable,
1761
+            ],
1762
+            'data' => [],
1763
+        ]
1764
+    );
1765
+    $champs = array_diff($champs, $exclusions);
1766
+
1767
+    return $champs;
1768 1768
 }
1769 1769
 
1770 1770
 /**
@@ -1819,27 +1819,27 @@  discard block
 block discarded – undo
1819 1819
  * @return void
1820 1820
  */
1821 1821
 function critere_tri_dist($idb, &$boucles, $crit) {
1822
-	$boucle = &$boucles[$idb];
1823
-
1824
-	// definition du champ par defaut
1825
-	$_champ_defaut = !isset($crit->param[0][0]) ? "''"
1826
-		: calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent);
1827
-	$_sens_defaut = !isset($crit->param[1][0]) ? '1'
1828
-		: calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
1829
-	$_variable = !isset($crit->param[2][0]) ? "'$idb'"
1830
-		: calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent);
1831
-
1832
-	$_tri = "((\$t=(isset(\$Pile[0]['tri'.$_variable]))?\$Pile[0]['tri'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('tri'.$_variable))?session_get('tri'.$_variable):$_champ_defaut))?tri_protege_champ(\$t):'')";
1833
-
1834
-	$_sens_defaut = "(is_array(\$s=$_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)";
1835
-	$_sens = "((intval(\$t=(isset(\$Pile[0]['sens'.$_variable]))?\$Pile[0]['sens'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('sens'.$_variable))?session_get('sens'.$_variable):$_sens_defaut))==-1 OR \$t=='inverse')?-1:1)";
1836
-
1837
-	$boucle->modificateur['tri_champ'] = $_tri;
1838
-	$boucle->modificateur['tri_sens'] = $_sens;
1839
-	$boucle->modificateur['tri_nom'] = $_variable;
1840
-	// faut il inserer un test sur l'existence de $tri parmi les champs de la table ?
1841
-	// evite des erreurs sql, mais peut empecher des tri sur jointure ...
1842
-	$boucle->hash .= "
1822
+    $boucle = &$boucles[$idb];
1823
+
1824
+    // definition du champ par defaut
1825
+    $_champ_defaut = !isset($crit->param[0][0]) ? "''"
1826
+        : calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent);
1827
+    $_sens_defaut = !isset($crit->param[1][0]) ? '1'
1828
+        : calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
1829
+    $_variable = !isset($crit->param[2][0]) ? "'$idb'"
1830
+        : calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent);
1831
+
1832
+    $_tri = "((\$t=(isset(\$Pile[0]['tri'.$_variable]))?\$Pile[0]['tri'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('tri'.$_variable))?session_get('tri'.$_variable):$_champ_defaut))?tri_protege_champ(\$t):'')";
1833
+
1834
+    $_sens_defaut = "(is_array(\$s=$_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)";
1835
+    $_sens = "((intval(\$t=(isset(\$Pile[0]['sens'.$_variable]))?\$Pile[0]['sens'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('sens'.$_variable))?session_get('sens'.$_variable):$_sens_defaut))==-1 OR \$t=='inverse')?-1:1)";
1836
+
1837
+    $boucle->modificateur['tri_champ'] = $_tri;
1838
+    $boucle->modificateur['tri_sens'] = $_sens;
1839
+    $boucle->modificateur['tri_nom'] = $_variable;
1840
+    // faut il inserer un test sur l'existence de $tri parmi les champs de la table ?
1841
+    // evite des erreurs sql, mais peut empecher des tri sur jointure ...
1842
+    $boucle->hash .= "
1843 1843
 	\$senstri = '';
1844 1844
 	\$tri = $_tri;
1845 1845
 	if (\$tri){
@@ -1847,8 +1847,8 @@  discard block
 block discarded – undo
1847 1847
 		\$senstri = (\$senstri<0)?' DESC':'';
1848 1848
 	};
1849 1849
 	";
1850
-	$boucle->select[] = '".tri_champ_select($tri)."';
1851
-	$boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)";
1850
+    $boucle->select[] = '".tri_champ_select($tri)."';
1851
+    $boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)";
1852 1852
 }
1853 1853
 
1854 1854
 # Criteres de comparaison
@@ -1865,20 +1865,20 @@  discard block
 block discarded – undo
1865 1865
  * @return void|array
1866 1866
  **/
1867 1867
 function calculer_critere_DEFAUT_dist($idb, &$boucles, $crit) {
1868
-	// double cas particulier {0,1} et {1/2} repere a l'analyse lexicale
1869
-	if (($crit->op == ',') or ($crit->op == '/')) {
1870
-		return calculer_critere_parties($idb, $boucles, $crit);
1871
-	}
1872
-
1873
-	$r = calculer_critere_infixe($idb, $boucles, $crit);
1874
-	if (!$r) {
1875
-		#	// on produit une erreur seulement si le critere n'a pas de '?'
1876
-		#	if (!$crit->cond) {
1877
-		return ['zbug_critere_inconnu', ['critere' => $crit->op]];
1878
-		#	}
1879
-	} else {
1880
-		calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r);
1881
-	}
1868
+    // double cas particulier {0,1} et {1/2} repere a l'analyse lexicale
1869
+    if (($crit->op == ',') or ($crit->op == '/')) {
1870
+        return calculer_critere_parties($idb, $boucles, $crit);
1871
+    }
1872
+
1873
+    $r = calculer_critere_infixe($idb, $boucles, $crit);
1874
+    if (!$r) {
1875
+        #	// on produit une erreur seulement si le critere n'a pas de '?'
1876
+        #	if (!$crit->cond) {
1877
+        return ['zbug_critere_inconnu', ['critere' => $crit->op]];
1878
+        #	}
1879
+    } else {
1880
+        calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r);
1881
+    }
1882 1882
 }
1883 1883
 
1884 1884
 
@@ -1898,62 +1898,62 @@  discard block
 block discarded – undo
1898 1898
  * @return void
1899 1899
  **/
1900 1900
 function calculer_critere_DEFAUT_args($idb, &$boucles, $crit, $args) {
1901
-	[$arg, $op, $val, $col, $where_complement] = $args;
1902
-
1903
-	$where = ["'$op'", "'$arg'", $val[0]];
1904
-
1905
-	// inserer la negation (cf !...)
1906
-
1907
-	if ($crit->not) {
1908
-		$where = ["'NOT'", $where];
1909
-	}
1910
-	if ($crit->exclus) {
1911
-		if (!preg_match(',^L[0-9]+[.],', $arg)) {
1912
-			$where = ["'NOT'", $where];
1913
-		} else {
1914
-			// un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1915
-			// c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1916
-			$where = [
1917
-				"'NOT'",
1918
-				[
1919
-					"'IN'",
1920
-					"'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1921
-					["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1922
-				]
1923
-			];
1924
-		}
1925
-	}
1926
-
1927
-	// inserer la condition (cf {lang?})
1928
-	// traiter a part la date, elle est mise d'office par SPIP,
1929
-	if ($crit->cond) {
1930
-		$pred = calculer_argument_precedent($idb, $col, $boucles);
1931
-		if ($col === 'date' or $col === 'date_redac') {
1932
-			if ($pred === "\$Pile[0]['" . $col . "']") {
1933
-				$pred = "(\$Pile[0]['{$col}_default']?'':$pred)";
1934
-			}
1935
-		}
1936
-
1937
-		if ($op === '=' and !$crit->not) {
1938
-			$where = [
1939
-				"'?'",
1940
-				"(is_array($pred))",
1941
-				critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col),
1942
-				$where
1943
-			];
1944
-		}
1945
-		$where = ["'?'", "!is_whereable($pred)", "''", $where];
1946
-		if ($where_complement) {
1947
-			// condition annexe du type "AND (objet='article')"
1948
-			$where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement];
1949
-		}
1950
-	}
1951
-
1952
-	$boucles[$idb]->where[] = $where;
1953
-	if ($where_complement) {
1954
-		// condition annexe du type "AND (objet='article')"
1955
-		$boucles[$idb]->where[] = $where_complement;
1956
-	}
1901
+    [$arg, $op, $val, $col, $where_complement] = $args;
1902
+
1903
+    $where = ["'$op'", "'$arg'", $val[0]];
1904
+
1905
+    // inserer la negation (cf !...)
1906
+
1907
+    if ($crit->not) {
1908
+        $where = ["'NOT'", $where];
1909
+    }
1910
+    if ($crit->exclus) {
1911
+        if (!preg_match(',^L[0-9]+[.],', $arg)) {
1912
+            $where = ["'NOT'", $where];
1913
+        } else {
1914
+            // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1915
+            // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1916
+            $where = [
1917
+                "'NOT'",
1918
+                [
1919
+                    "'IN'",
1920
+                    "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1921
+                    ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1922
+                ]
1923
+            ];
1924
+        }
1925
+    }
1926
+
1927
+    // inserer la condition (cf {lang?})
1928
+    // traiter a part la date, elle est mise d'office par SPIP,
1929
+    if ($crit->cond) {
1930
+        $pred = calculer_argument_precedent($idb, $col, $boucles);
1931
+        if ($col === 'date' or $col === 'date_redac') {
1932
+            if ($pred === "\$Pile[0]['" . $col . "']") {
1933
+                $pred = "(\$Pile[0]['{$col}_default']?'':$pred)";
1934
+            }
1935
+        }
1936
+
1937
+        if ($op === '=' and !$crit->not) {
1938
+            $where = [
1939
+                "'?'",
1940
+                "(is_array($pred))",
1941
+                critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col),
1942
+                $where
1943
+            ];
1944
+        }
1945
+        $where = ["'?'", "!is_whereable($pred)", "''", $where];
1946
+        if ($where_complement) {
1947
+            // condition annexe du type "AND (objet='article')"
1948
+            $where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement];
1949
+        }
1950
+    }
1951
+
1952
+    $boucles[$idb]->where[] = $where;
1953
+    if ($where_complement) {
1954
+        // condition annexe du type "AND (objet='article')"
1955
+        $boucles[$idb]->where[] = $where_complement;
1956
+    }
1957 1957
 }
1958 1958
 
1959 1959
 
@@ -1994,165 +1994,165 @@  discard block
 block discarded – undo
1994 1994
  **/
1995 1995
 function calculer_critere_infixe($idb, &$boucles, $crit) {
1996 1996
 
1997
-	$boucle = &$boucles[$idb];
1998
-	$type = $boucle->type_requete;
1999
-	$table = $boucle->id_table ?? '';
2000
-	$desc = $boucle->show;
2001
-	$col_vraie = null;
2002
-
2003
-	[$fct, $col, $op, $val, $args_sql] =
2004
-		calculer_critere_infixe_ops($idb, $boucles, $crit);
2005
-
2006
-	$col_alias = $col;
2007
-	$where_complement = false;
2008
-
2009
-	// Cas particulier : id_enfant => utiliser la colonne id_objet
2010
-	if ($col == 'id_enfant') {
2011
-		$col = $boucle->primary;
2012
-	}
2013
-
2014
-	// Cas particulier : id_parent => verifier les exceptions de tables
2015
-	if (
2016
-		(in_array($col, ['id_parent', 'id_secteur']) and isset($GLOBALS['exceptions_des_tables'][$table][$col]))
2017
-		or (isset($GLOBALS['exceptions_des_tables'][$table][$col]) and is_string($GLOBALS['exceptions_des_tables'][$table][$col]))
2018
-	) {
2019
-		$col = $GLOBALS['exceptions_des_tables'][$table][$col];
2020
-	} // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums)
2021
-	else {
2022
-		if (($col == 'id_secteur') and ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) {
2023
-			$table = $critere_secteur($idb, $boucles, $val, $crit);
2024
-		}
2025
-
2026
-		// cas id_article=xx qui se mappe en id_objet=xx AND objet=article
2027
-		// sauf si exception declaree : sauter cette etape
2028
-		else {
2029
-			if (
2030
-				!isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col])
2031
-				and !isset($GLOBALS['exceptions_des_jointures'][$col])
2032
-				and count(trouver_champs_decomposes($col, $desc)) > 1
2033
-			) {
2034
-				$e = decompose_champ_id_objet($col);
2035
-				$col = array_shift($e);
2036
-				$where_complement = primary_doublee($e, $table);
2037
-			} // Cas particulier : expressions de date
2038
-			else {
2039
-				if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) {
2040
-					[$col, $col_vraie] = $c;
2041
-					$table = '';
2042
-				} // table explicitée {mots.titre}
2043
-				else {
2044
-					if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2045
-						[, $table, $col] = $r;
2046
-						$col_alias = $col;
2047
-
2048
-						$trouver_table = charger_fonction('trouver_table', 'base');
2049
-						if (
2050
-							$desc = $trouver_table($table, $boucle->sql_serveur)
2051
-							and isset($desc['field'][$col])
2052
-							and $cle = array_search($desc['table'], $boucle->from)
2053
-						) {
2054
-							$table = $cle;
2055
-						} else {
2056
-							$table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond or $op != '='));
2057
-						}
2058
-						#$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true);
2059
-						if (!$table) {
2060
-							return '';
2061
-						}
2062
-					}
2063
-					// si le champ n'est pas trouvé dans la table,
2064
-					// on cherche si une jointure peut l'obtenir
2065
-					elseif (@!array_key_exists($col, $desc['field'])) {
2066
-						// Champ joker * des iterateurs DATA qui accepte tout
2067
-						if (@array_key_exists('*', $desc['field'])) {
2068
-							$desc['field'][$col_vraie ?: $col] = ''; // on veut pas de cast INT par defaut car le type peut etre n'importe quoi dans les boucles DATA
2069
-						}
2070
-						else {
2071
-							$r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table);
2072
-							if (!$r) {
2073
-								return '';
2074
-							}
2075
-							[$col, $col_alias, $table, $where_complement, $desc] = $r;
2076
-						}
2077
-					}
2078
-				}
2079
-			}
2080
-		}
2081
-	}
2082
-
2083
-	$col_vraie = ($col_vraie ?: $col);
2084
-	// Dans tous les cas,
2085
-	// virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL)
2086
-	// et passer dans sql_quote avec le type si connu
2087
-	// et int sinon si la valeur est numerique
2088
-	// sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon)
2089
-	// Ne pas utiliser intval, PHP tronquant les Bigint de SQL
2090
-	if ($op == '=' or in_array($op, $GLOBALS['table_criteres_infixes'])) {
2091
-		$type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL');
2092
-		// defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon
2093
-		// prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut
2094
-		if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", $val[0], $r)) {
2095
-			$val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"';
2096
-		}
2097
-		// sinon expliciter les
2098
-		// sql_quote(truc) en sql_quote(truc,'',type)
2099
-		// sql_quote(truc,serveur) en sql_quote(truc,serveur,type)
2100
-		// sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type)
2101
-		// sans toucher aux
2102
-		// sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE')
2103
-		// sql_quote(truc,'','varchar')
2104
-		elseif (
2105
-			preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', $val[0], $r)
2106
-			// si pas deja un type
2107
-			and (!isset($r[3]) or !$r[3] or !trim($r[3], ", '"))
2108
-		) {
2109
-			$r = $r[1]
2110
-				. ((isset($r[2]) and $r[2]) ? $r[2] : ",''")
2111
-				. ",'" . addslashes($type_cast_quote) . "'";
2112
-			$val[0] = "sql_quote($r)";
2113
-		}
2114
-		elseif (
2115
-			strpos($val[0], '@@defaultcast@@') !== false
2116
-			and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2117
-		) {
2118
-			$val[0] = substr($val[0], 0, -strlen($r[0])) . "'" . addslashes($type_cast_quote) . "')";
2119
-		}
2120
-	}
2121
-
2122
-	if (
2123
-		strpos($val[0], '@@defaultcast@@') !== false
2124
-		and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2125
-	) {
2126
-		$val[0] = substr($val[0], 0, -strlen($r[0])) . "'char')";
2127
-	}
2128
-
2129
-	// Indicateur pour permettre aux fonctionx boucle_X de modifier
2130
-	// leurs requetes par defaut, notamment le champ statut
2131
-	// Ne pas confondre champs de la table principale et des jointures
2132
-	if ($table === $boucle->id_table) {
2133
-		$boucles[$idb]->modificateur['criteres'][$col_vraie] = true;
2134
-		if ($col_alias != $col_vraie) {
2135
-			$boucles[$idb]->modificateur['criteres'][$col_alias] = true;
2136
-		}
2137
-	}
2138
-
2139
-	// inserer le nom de la table SQL devant le nom du champ
2140
-	if ($table) {
2141
-		if ($col[0] == '`') {
2142
-			$arg = "$table." . substr($col, 1, -1);
2143
-		} else {
2144
-			$arg = "$table.$col";
2145
-		}
2146
-	} else {
2147
-		$arg = $col;
2148
-	}
2149
-
2150
-	// inserer la fonction SQL
2151
-	if ($fct) {
2152
-		$arg = "$fct($arg$args_sql)";
2153
-	}
2154
-
2155
-	return [$arg, $op, $val, $col_alias, $where_complement];
1997
+    $boucle = &$boucles[$idb];
1998
+    $type = $boucle->type_requete;
1999
+    $table = $boucle->id_table ?? '';
2000
+    $desc = $boucle->show;
2001
+    $col_vraie = null;
2002
+
2003
+    [$fct, $col, $op, $val, $args_sql] =
2004
+        calculer_critere_infixe_ops($idb, $boucles, $crit);
2005
+
2006
+    $col_alias = $col;
2007
+    $where_complement = false;
2008
+
2009
+    // Cas particulier : id_enfant => utiliser la colonne id_objet
2010
+    if ($col == 'id_enfant') {
2011
+        $col = $boucle->primary;
2012
+    }
2013
+
2014
+    // Cas particulier : id_parent => verifier les exceptions de tables
2015
+    if (
2016
+        (in_array($col, ['id_parent', 'id_secteur']) and isset($GLOBALS['exceptions_des_tables'][$table][$col]))
2017
+        or (isset($GLOBALS['exceptions_des_tables'][$table][$col]) and is_string($GLOBALS['exceptions_des_tables'][$table][$col]))
2018
+    ) {
2019
+        $col = $GLOBALS['exceptions_des_tables'][$table][$col];
2020
+    } // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums)
2021
+    else {
2022
+        if (($col == 'id_secteur') and ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) {
2023
+            $table = $critere_secteur($idb, $boucles, $val, $crit);
2024
+        }
2025
+
2026
+        // cas id_article=xx qui se mappe en id_objet=xx AND objet=article
2027
+        // sauf si exception declaree : sauter cette etape
2028
+        else {
2029
+            if (
2030
+                !isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col])
2031
+                and !isset($GLOBALS['exceptions_des_jointures'][$col])
2032
+                and count(trouver_champs_decomposes($col, $desc)) > 1
2033
+            ) {
2034
+                $e = decompose_champ_id_objet($col);
2035
+                $col = array_shift($e);
2036
+                $where_complement = primary_doublee($e, $table);
2037
+            } // Cas particulier : expressions de date
2038
+            else {
2039
+                if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) {
2040
+                    [$col, $col_vraie] = $c;
2041
+                    $table = '';
2042
+                } // table explicitée {mots.titre}
2043
+                else {
2044
+                    if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2045
+                        [, $table, $col] = $r;
2046
+                        $col_alias = $col;
2047
+
2048
+                        $trouver_table = charger_fonction('trouver_table', 'base');
2049
+                        if (
2050
+                            $desc = $trouver_table($table, $boucle->sql_serveur)
2051
+                            and isset($desc['field'][$col])
2052
+                            and $cle = array_search($desc['table'], $boucle->from)
2053
+                        ) {
2054
+                            $table = $cle;
2055
+                        } else {
2056
+                            $table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond or $op != '='));
2057
+                        }
2058
+                        #$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true);
2059
+                        if (!$table) {
2060
+                            return '';
2061
+                        }
2062
+                    }
2063
+                    // si le champ n'est pas trouvé dans la table,
2064
+                    // on cherche si une jointure peut l'obtenir
2065
+                    elseif (@!array_key_exists($col, $desc['field'])) {
2066
+                        // Champ joker * des iterateurs DATA qui accepte tout
2067
+                        if (@array_key_exists('*', $desc['field'])) {
2068
+                            $desc['field'][$col_vraie ?: $col] = ''; // on veut pas de cast INT par defaut car le type peut etre n'importe quoi dans les boucles DATA
2069
+                        }
2070
+                        else {
2071
+                            $r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table);
2072
+                            if (!$r) {
2073
+                                return '';
2074
+                            }
2075
+                            [$col, $col_alias, $table, $where_complement, $desc] = $r;
2076
+                        }
2077
+                    }
2078
+                }
2079
+            }
2080
+        }
2081
+    }
2082
+
2083
+    $col_vraie = ($col_vraie ?: $col);
2084
+    // Dans tous les cas,
2085
+    // virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL)
2086
+    // et passer dans sql_quote avec le type si connu
2087
+    // et int sinon si la valeur est numerique
2088
+    // sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon)
2089
+    // Ne pas utiliser intval, PHP tronquant les Bigint de SQL
2090
+    if ($op == '=' or in_array($op, $GLOBALS['table_criteres_infixes'])) {
2091
+        $type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL');
2092
+        // defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon
2093
+        // prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut
2094
+        if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", $val[0], $r)) {
2095
+            $val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"';
2096
+        }
2097
+        // sinon expliciter les
2098
+        // sql_quote(truc) en sql_quote(truc,'',type)
2099
+        // sql_quote(truc,serveur) en sql_quote(truc,serveur,type)
2100
+        // sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type)
2101
+        // sans toucher aux
2102
+        // sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE')
2103
+        // sql_quote(truc,'','varchar')
2104
+        elseif (
2105
+            preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', $val[0], $r)
2106
+            // si pas deja un type
2107
+            and (!isset($r[3]) or !$r[3] or !trim($r[3], ", '"))
2108
+        ) {
2109
+            $r = $r[1]
2110
+                . ((isset($r[2]) and $r[2]) ? $r[2] : ",''")
2111
+                . ",'" . addslashes($type_cast_quote) . "'";
2112
+            $val[0] = "sql_quote($r)";
2113
+        }
2114
+        elseif (
2115
+            strpos($val[0], '@@defaultcast@@') !== false
2116
+            and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2117
+        ) {
2118
+            $val[0] = substr($val[0], 0, -strlen($r[0])) . "'" . addslashes($type_cast_quote) . "')";
2119
+        }
2120
+    }
2121
+
2122
+    if (
2123
+        strpos($val[0], '@@defaultcast@@') !== false
2124
+        and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2125
+    ) {
2126
+        $val[0] = substr($val[0], 0, -strlen($r[0])) . "'char')";
2127
+    }
2128
+
2129
+    // Indicateur pour permettre aux fonctionx boucle_X de modifier
2130
+    // leurs requetes par defaut, notamment le champ statut
2131
+    // Ne pas confondre champs de la table principale et des jointures
2132
+    if ($table === $boucle->id_table) {
2133
+        $boucles[$idb]->modificateur['criteres'][$col_vraie] = true;
2134
+        if ($col_alias != $col_vraie) {
2135
+            $boucles[$idb]->modificateur['criteres'][$col_alias] = true;
2136
+        }
2137
+    }
2138
+
2139
+    // inserer le nom de la table SQL devant le nom du champ
2140
+    if ($table) {
2141
+        if ($col[0] == '`') {
2142
+            $arg = "$table." . substr($col, 1, -1);
2143
+        } else {
2144
+            $arg = "$table.$col";
2145
+        }
2146
+    } else {
2147
+        $arg = $col;
2148
+    }
2149
+
2150
+    // inserer la fonction SQL
2151
+    if ($fct) {
2152
+        $arg = "$fct($arg$args_sql)";
2153
+    }
2154
+
2155
+    return [$arg, $op, $val, $col_alias, $where_complement];
2156 2156
 }
2157 2157
 
2158 2158
 
@@ -2181,77 +2181,77 @@  discard block
 block discarded – undo
2181 2181
  **/
2182 2182
 function calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table) {
2183 2183
 
2184
-	$where = '';
2185
-
2186
-	$calculer_critere_externe = 'calculer_critere_externe_init';
2187
-	// gestion par les plugins des jointures tordues
2188
-	// pas automatiques mais necessaires
2189
-	$table_sql = table_objet_sql($table);
2190
-	if (
2191
-		isset($GLOBALS['exceptions_des_jointures'][$table_sql])
2192
-		and is_array($GLOBALS['exceptions_des_jointures'][$table_sql])
2193
-		and
2194
-		(
2195
-			isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col])
2196
-			or
2197
-			isset($GLOBALS['exceptions_des_jointures'][$table_sql][''])
2198
-		)
2199
-	) {
2200
-		$t = $GLOBALS['exceptions_des_jointures'][$table_sql];
2201
-		$index = $t[$col] ?? $t[''] ?? [];
2202
-
2203
-		if ((is_countable($index) ? count($index) : 0) == 3) {
2204
-			[$t, $col, $calculer_critere_externe] = $index;
2205
-		} elseif ((is_countable($index) ? count($index) : 0) == 2) {
2206
-			[$t, $col] = $t[$col];
2207
-		} elseif ((is_countable($index) ? count($index) : 0) == 1) {
2208
-			[$calculer_critere_externe] = $index;
2209
-			$t = $table;
2210
-		} else {
2211
-			$t = '';
2212
-		} // jointure non declaree. La trouver.
2213
-	} elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) {
2214
-		[$t, $col] = $GLOBALS['exceptions_des_jointures'][$col];
2215
-	} else {
2216
-		$t = '';
2217
-	} // jointure non declaree. La trouver.
2218
-
2219
-	// ici on construit le from pour fournir $col en piochant dans les jointures
2220
-
2221
-	// si des jointures explicites sont fournies, on cherche d'abord dans celles ci
2222
-	// permet de forcer une table de lien quand il y a ambiguite
2223
-	// <BOUCLE_(DOCUMENTS documents_liens){id_mot}>
2224
-	// alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}>
2225
-	$table = '';
2226
-	if ($boucle->jointures_explicites) {
2227
-		$jointures_explicites = explode(' ', $boucle->jointures_explicites);
2228
-		$table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond or $op != '='), $t);
2229
-	}
2230
-
2231
-	// et sinon on cherche parmi toutes les jointures declarees
2232
-	if (!$table) {
2233
-		$table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond or $op != '='), $t);
2234
-	}
2235
-
2236
-	if (!$table) {
2237
-		return '';
2238
-	}
2239
-
2240
-	// il ne reste plus qu'a trouver le champ dans les from
2241
-	[$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle);
2242
-
2243
-	if ((is_countable($cle) ? count($cle) : 0) > 1 or reset($cle) !== $col) {
2244
-		$col_alias = $col; // id_article devient juste le nom d'origine
2245
-		if ((is_countable($cle) ? count($cle) : 0) > 1 and reset($cle) == 'id_objet') {
2246
-			$e = decompose_champ_id_objet($col);
2247
-			$col = array_shift($e);
2248
-			$where = primary_doublee($e, $table);
2249
-		} else {
2250
-			$col = reset($cle);
2251
-		}
2252
-	}
2253
-
2254
-	return [$col, $col_alias, $table, $where, $desc];
2184
+    $where = '';
2185
+
2186
+    $calculer_critere_externe = 'calculer_critere_externe_init';
2187
+    // gestion par les plugins des jointures tordues
2188
+    // pas automatiques mais necessaires
2189
+    $table_sql = table_objet_sql($table);
2190
+    if (
2191
+        isset($GLOBALS['exceptions_des_jointures'][$table_sql])
2192
+        and is_array($GLOBALS['exceptions_des_jointures'][$table_sql])
2193
+        and
2194
+        (
2195
+            isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col])
2196
+            or
2197
+            isset($GLOBALS['exceptions_des_jointures'][$table_sql][''])
2198
+        )
2199
+    ) {
2200
+        $t = $GLOBALS['exceptions_des_jointures'][$table_sql];
2201
+        $index = $t[$col] ?? $t[''] ?? [];
2202
+
2203
+        if ((is_countable($index) ? count($index) : 0) == 3) {
2204
+            [$t, $col, $calculer_critere_externe] = $index;
2205
+        } elseif ((is_countable($index) ? count($index) : 0) == 2) {
2206
+            [$t, $col] = $t[$col];
2207
+        } elseif ((is_countable($index) ? count($index) : 0) == 1) {
2208
+            [$calculer_critere_externe] = $index;
2209
+            $t = $table;
2210
+        } else {
2211
+            $t = '';
2212
+        } // jointure non declaree. La trouver.
2213
+    } elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) {
2214
+        [$t, $col] = $GLOBALS['exceptions_des_jointures'][$col];
2215
+    } else {
2216
+        $t = '';
2217
+    } // jointure non declaree. La trouver.
2218
+
2219
+    // ici on construit le from pour fournir $col en piochant dans les jointures
2220
+
2221
+    // si des jointures explicites sont fournies, on cherche d'abord dans celles ci
2222
+    // permet de forcer une table de lien quand il y a ambiguite
2223
+    // <BOUCLE_(DOCUMENTS documents_liens){id_mot}>
2224
+    // alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}>
2225
+    $table = '';
2226
+    if ($boucle->jointures_explicites) {
2227
+        $jointures_explicites = explode(' ', $boucle->jointures_explicites);
2228
+        $table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond or $op != '='), $t);
2229
+    }
2230
+
2231
+    // et sinon on cherche parmi toutes les jointures declarees
2232
+    if (!$table) {
2233
+        $table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond or $op != '='), $t);
2234
+    }
2235
+
2236
+    if (!$table) {
2237
+        return '';
2238
+    }
2239
+
2240
+    // il ne reste plus qu'a trouver le champ dans les from
2241
+    [$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle);
2242
+
2243
+    if ((is_countable($cle) ? count($cle) : 0) > 1 or reset($cle) !== $col) {
2244
+        $col_alias = $col; // id_article devient juste le nom d'origine
2245
+        if ((is_countable($cle) ? count($cle) : 0) > 1 and reset($cle) == 'id_objet') {
2246
+            $e = decompose_champ_id_objet($col);
2247
+            $col = array_shift($e);
2248
+            $where = primary_doublee($e, $table);
2249
+        } else {
2250
+            $col = reset($cle);
2251
+        }
2252
+    }
2253
+
2254
+    return [$col, $col_alias, $table, $where, $desc];
2255 2255
 }
2256 2256
 
2257 2257
 
@@ -2272,10 +2272,10 @@  discard block
 block discarded – undo
2272 2272
  *     - valeur
2273 2273
  **/
2274 2274
 function primary_doublee($decompose, $table) {
2275
-	$e1 = reset($decompose);
2276
-	$e2 = "sql_quote('" . end($decompose) . "')";
2275
+    $e1 = reset($decompose);
2276
+    $e2 = "sql_quote('" . end($decompose) . "')";
2277 2277
 
2278
-	return ["'='", "'$table." . $e1 . "'", $e2];
2278
+    return ["'='", "'$table." . $e1 . "'", $e2];
2279 2279
 }
2280 2280
 
2281 2281
 /**
@@ -2306,57 +2306,57 @@  discard block
 block discarded – undo
2306 2306
  *     Vide sinon.
2307 2307
  */
2308 2308
 function calculer_critere_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) {
2309
-	// si on demande un truc du genre spip_mots
2310
-	// avec aussi spip_mots_liens dans les jointures dispo
2311
-	// et qu'on est la
2312
-	// il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots
2313
-	if (
2314
-		$checkarrivee
2315
-		and is_string($checkarrivee)
2316
-		and $a = table_objet($checkarrivee)
2317
-		and in_array($a . '_liens', $joints)
2318
-	) {
2319
-		if ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee)) {
2320
-			return $res;
2321
-		}
2322
-	}
2323
-	foreach ($joints as $joint) {
2324
-		if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) {
2325
-			// alias de table dans le from
2326
-			$t = array_search($arrivee[0], $boucle->from);
2327
-			// recuperer la cle id_xx eventuellement decomposee en (id_objet,objet)
2328
-			$cols = $arrivee[2];
2329
-			// mais on ignore la 3eme cle si presente qui correspond alors au point de depart
2330
-			if ((is_countable($cols) ? count($cols) : 0) > 2) {
2331
-				array_pop($cols);
2332
-			}
2333
-			if ($t) {
2334
-				// la table est déjà dans le FROM, on vérifie si le champ est utilisé.
2335
-				$joindre = false;
2336
-				foreach ($cols as $col) {
2337
-					$c = '/\b' . $t . ".$col" . '\b/';
2338
-					if (trouver_champ($c, $boucle->where)) {
2339
-						$joindre = true;
2340
-					} else {
2341
-						// mais ca peut etre dans le FIELD pour le Having
2342
-						$c = "/FIELD.$t" . ".$col,/";
2343
-						if (trouver_champ($c, $boucle->select)) {
2344
-							$joindre = true;
2345
-						}
2346
-					}
2347
-				}
2348
-				if (!$joindre) {
2349
-					return $t;
2350
-				}
2351
-			}
2352
-			array_pop($arrivee);
2353
-			if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) {
2354
-				return $res;
2355
-			}
2356
-		}
2357
-	}
2358
-
2359
-	return '';
2309
+    // si on demande un truc du genre spip_mots
2310
+    // avec aussi spip_mots_liens dans les jointures dispo
2311
+    // et qu'on est la
2312
+    // il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots
2313
+    if (
2314
+        $checkarrivee
2315
+        and is_string($checkarrivee)
2316
+        and $a = table_objet($checkarrivee)
2317
+        and in_array($a . '_liens', $joints)
2318
+    ) {
2319
+        if ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee)) {
2320
+            return $res;
2321
+        }
2322
+    }
2323
+    foreach ($joints as $joint) {
2324
+        if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) {
2325
+            // alias de table dans le from
2326
+            $t = array_search($arrivee[0], $boucle->from);
2327
+            // recuperer la cle id_xx eventuellement decomposee en (id_objet,objet)
2328
+            $cols = $arrivee[2];
2329
+            // mais on ignore la 3eme cle si presente qui correspond alors au point de depart
2330
+            if ((is_countable($cols) ? count($cols) : 0) > 2) {
2331
+                array_pop($cols);
2332
+            }
2333
+            if ($t) {
2334
+                // la table est déjà dans le FROM, on vérifie si le champ est utilisé.
2335
+                $joindre = false;
2336
+                foreach ($cols as $col) {
2337
+                    $c = '/\b' . $t . ".$col" . '\b/';
2338
+                    if (trouver_champ($c, $boucle->where)) {
2339
+                        $joindre = true;
2340
+                    } else {
2341
+                        // mais ca peut etre dans le FIELD pour le Having
2342
+                        $c = "/FIELD.$t" . ".$col,/";
2343
+                        if (trouver_champ($c, $boucle->select)) {
2344
+                            $joindre = true;
2345
+                        }
2346
+                    }
2347
+                }
2348
+                if (!$joindre) {
2349
+                    return $t;
2350
+                }
2351
+            }
2352
+            array_pop($arrivee);
2353
+            if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) {
2354
+                return $res;
2355
+            }
2356
+        }
2357
+    }
2358
+
2359
+    return '';
2360 2360
 }
2361 2361
 
2362 2362
 /**
@@ -2382,35 +2382,35 @@  discard block
 block discarded – undo
2382 2382
  *     Alias de la table de jointure (Lx)
2383 2383
  */
2384 2384
 function calculer_lien_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) {
2385
-	$primary_arrivee = id_table_objet($checkarrivee);
2386
-
2387
-	// [FIXME] $checkarrivee peut-il arriver avec false ????
2388
-	$intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens');
2389
-	$arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee);
2390
-
2391
-	if (!$intermediaire or !$arrivee) {
2392
-		return '';
2393
-	}
2394
-	array_pop($intermediaire); // enlever la cle en 3eme argument
2395
-	array_pop($arrivee); // enlever la cle en 3eme argument
2396
-
2397
-	$res = fabrique_jointures(
2398
-		$boucle,
2399
-		[
2400
-			[
2401
-				$boucle->id_table,
2402
-				$intermediaire,
2403
-				[id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']]
2404
-			],
2405
-			[reset($intermediaire), $arrivee, $primary_arrivee]
2406
-		],
2407
-		$cond,
2408
-		$desc,
2409
-		$boucle->id_table,
2410
-		[$col]
2411
-	);
2412
-
2413
-	return $res;
2385
+    $primary_arrivee = id_table_objet($checkarrivee);
2386
+
2387
+    // [FIXME] $checkarrivee peut-il arriver avec false ????
2388
+    $intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens');
2389
+    $arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee);
2390
+
2391
+    if (!$intermediaire or !$arrivee) {
2392
+        return '';
2393
+    }
2394
+    array_pop($intermediaire); // enlever la cle en 3eme argument
2395
+    array_pop($arrivee); // enlever la cle en 3eme argument
2396
+
2397
+    $res = fabrique_jointures(
2398
+        $boucle,
2399
+        [
2400
+            [
2401
+                $boucle->id_table,
2402
+                $intermediaire,
2403
+                [id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']]
2404
+            ],
2405
+            [reset($intermediaire), $arrivee, $primary_arrivee]
2406
+        ],
2407
+        $cond,
2408
+        $desc,
2409
+        $boucle->id_table,
2410
+        [$col]
2411
+    );
2412
+
2413
+    return $res;
2414 2414
 }
2415 2415
 
2416 2416
 
@@ -2427,17 +2427,17 @@  discard block
 block discarded – undo
2427 2427
  *     false sinon.
2428 2428
  **/
2429 2429
 function trouver_champ($champ, $where) {
2430
-	if (!is_array($where)) {
2431
-		return preg_match($champ, $where);
2432
-	} else {
2433
-		foreach ($where as $clause) {
2434
-			if (trouver_champ($champ, $clause)) {
2435
-				return true;
2436
-			}
2437
-		}
2438
-
2439
-		return false;
2440
-	}
2430
+    if (!is_array($where)) {
2431
+        return preg_match($champ, $where);
2432
+    } else {
2433
+        foreach ($where as $clause) {
2434
+            if (trouver_champ($champ, $clause)) {
2435
+                return true;
2436
+            }
2437
+        }
2438
+
2439
+        return false;
2440
+    }
2441 2441
 }
2442 2442
 
2443 2443
 
@@ -2463,129 +2463,129 @@  discard block
 block discarded – undo
2463 2463
  *     - string $args_sql  Suite des arguments du critère. ?
2464 2464
  **/
2465 2465
 function calculer_critere_infixe_ops($idb, &$boucles, $crit) {
2466
-	// cas d'une valeur comparee a elle-meme ou son referent
2467
-	if (count($crit->param) == 0) {
2468
-		$op = '=';
2469
-		$col = $val = $crit->op;
2470
-		if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2471
-			$val = $r[2];
2472
-		}
2473
-		// Cas special {lang} : aller chercher $GLOBALS['spip_lang']
2474
-		if ($val == 'lang') {
2475
-			$val = [kwote('$GLOBALS[\'spip_lang\']')];
2476
-		} else {
2477
-			$defaut = null;
2478
-			if ($val == 'id_parent') {
2479
-				// Si id_parent, comparer l'id_parent avec l'id_objet
2480
-				// de la boucle superieure.... faudrait verifier qu'il existe
2481
-				// pour eviter l'erreur SQL
2482
-				$val = $boucles[$idb]->primary;
2483
-				// mais si pas de boucle superieure, prendre id_parent dans l'env
2484
-				$defaut = "(\$Pile[0]['id_parent'] ?? null)";
2485
-			} elseif ($val == 'id_enfant') {
2486
-				// Si id_enfant, comparer l'id_objet avec l'id_parent
2487
-				// de la boucle superieure
2488
-				$val = 'id_parent';
2489
-			} elseif ($crit->cond and ($col == 'date' or $col == 'date_redac')) {
2490
-				// un critere conditionnel sur date est traite a part
2491
-				// car la date est mise d'office par SPIP,
2492
-				$defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])";
2493
-			}
2494
-
2495
-			$val = calculer_argument_precedent($idb, $val, $boucles, $defaut);
2496
-			$val = [kwote($val)];
2497
-		}
2498
-	} else {
2499
-		// comparaison explicite
2500
-		// le phraseur impose que le premier param soit du texte
2501
-		$params = $crit->param;
2502
-		$op = $crit->op;
2503
-		if ($op == '==') {
2504
-			$op = 'REGEXP';
2505
-		}
2506
-		$col = array_shift($params);
2507
-		$col = $col[0]->texte;
2508
-
2509
-		$val = [];
2510
-		$parent = $boucles[$idb]->id_parent;
2511
-
2512
-		// Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
2513
-		// celui ne sachant pas ce qu'est un critere infixe
2514
-		// et a fortiori son 2e operande qu'entoure " ou '
2515
-		if (
2516
-			count($params) == 1
2517
-			and (is_countable($params[0]) ? count($params[0]) : 0) == 3
2518
-			and $params[0][0]->type == 'texte'
2519
-			and $params[0][2]->type == 'texte'
2520
-			and ($p = $params[0][0]->texte) == $params[0][2]->texte
2521
-			and (($p == "'") or ($p == '"'))
2522
-			and $params[0][1]->type == 'champ'
2523
-		) {
2524
-			$val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p";
2525
-		} else {
2526
-			foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
2527
-				$a = calculer_liste($p, $idb, $boucles, $parent);
2528
-				if (strcasecmp($op, 'IN') == 0) {
2529
-					$val[] = $a;
2530
-				} else {
2531
-					$val[] = kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@');
2532
-				} // toujours quoter en char ici
2533
-			}
2534
-		}
2535
-	}
2536
-
2537
-	$fct = $args_sql = '';
2538
-	// fonction SQL ?
2539
-	// chercher FONCTION(champ) tel que CONCAT(titre,descriptif)
2540
-	if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) {
2541
-		$fct = $m[1];
2542
-		preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a);
2543
-		$col = $a[1];
2544
-		if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) {
2545
-			$col = $m[1];
2546
-			$args_sql = $m[2];
2547
-		}
2548
-		$args_sql .= $a[2];
2549
-	}
2550
-
2551
-	return [$fct, $col, $op, $val, $args_sql];
2466
+    // cas d'une valeur comparee a elle-meme ou son referent
2467
+    if (count($crit->param) == 0) {
2468
+        $op = '=';
2469
+        $col = $val = $crit->op;
2470
+        if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2471
+            $val = $r[2];
2472
+        }
2473
+        // Cas special {lang} : aller chercher $GLOBALS['spip_lang']
2474
+        if ($val == 'lang') {
2475
+            $val = [kwote('$GLOBALS[\'spip_lang\']')];
2476
+        } else {
2477
+            $defaut = null;
2478
+            if ($val == 'id_parent') {
2479
+                // Si id_parent, comparer l'id_parent avec l'id_objet
2480
+                // de la boucle superieure.... faudrait verifier qu'il existe
2481
+                // pour eviter l'erreur SQL
2482
+                $val = $boucles[$idb]->primary;
2483
+                // mais si pas de boucle superieure, prendre id_parent dans l'env
2484
+                $defaut = "(\$Pile[0]['id_parent'] ?? null)";
2485
+            } elseif ($val == 'id_enfant') {
2486
+                // Si id_enfant, comparer l'id_objet avec l'id_parent
2487
+                // de la boucle superieure
2488
+                $val = 'id_parent';
2489
+            } elseif ($crit->cond and ($col == 'date' or $col == 'date_redac')) {
2490
+                // un critere conditionnel sur date est traite a part
2491
+                // car la date est mise d'office par SPIP,
2492
+                $defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])";
2493
+            }
2494
+
2495
+            $val = calculer_argument_precedent($idb, $val, $boucles, $defaut);
2496
+            $val = [kwote($val)];
2497
+        }
2498
+    } else {
2499
+        // comparaison explicite
2500
+        // le phraseur impose que le premier param soit du texte
2501
+        $params = $crit->param;
2502
+        $op = $crit->op;
2503
+        if ($op == '==') {
2504
+            $op = 'REGEXP';
2505
+        }
2506
+        $col = array_shift($params);
2507
+        $col = $col[0]->texte;
2508
+
2509
+        $val = [];
2510
+        $parent = $boucles[$idb]->id_parent;
2511
+
2512
+        // Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
2513
+        // celui ne sachant pas ce qu'est un critere infixe
2514
+        // et a fortiori son 2e operande qu'entoure " ou '
2515
+        if (
2516
+            count($params) == 1
2517
+            and (is_countable($params[0]) ? count($params[0]) : 0) == 3
2518
+            and $params[0][0]->type == 'texte'
2519
+            and $params[0][2]->type == 'texte'
2520
+            and ($p = $params[0][0]->texte) == $params[0][2]->texte
2521
+            and (($p == "'") or ($p == '"'))
2522
+            and $params[0][1]->type == 'champ'
2523
+        ) {
2524
+            $val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p";
2525
+        } else {
2526
+            foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
2527
+                $a = calculer_liste($p, $idb, $boucles, $parent);
2528
+                if (strcasecmp($op, 'IN') == 0) {
2529
+                    $val[] = $a;
2530
+                } else {
2531
+                    $val[] = kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@');
2532
+                } // toujours quoter en char ici
2533
+            }
2534
+        }
2535
+    }
2536
+
2537
+    $fct = $args_sql = '';
2538
+    // fonction SQL ?
2539
+    // chercher FONCTION(champ) tel que CONCAT(titre,descriptif)
2540
+    if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) {
2541
+        $fct = $m[1];
2542
+        preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a);
2543
+        $col = $a[1];
2544
+        if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) {
2545
+            $col = $m[1];
2546
+            $args_sql = $m[2];
2547
+        }
2548
+        $args_sql .= $a[2];
2549
+    }
2550
+
2551
+    return [$fct, $col, $op, $val, $args_sql];
2552 2552
 }
2553 2553
 
2554 2554
 // compatibilite ancienne version
2555 2555
 
2556 2556
 function calculer_vieux_in($params) {
2557
-	$deb = $params[0][0];
2558
-	$k = (is_countable($params) ? count($params) : 0) - 1;
2559
-	$last = $params[$k];
2560
-	$j = (is_countable($last) ? count($last) : 0) - 1;
2561
-	$last = $last[$j];
2562
-	$n = isset($last->texte) ? strlen($last->texte) : 0;
2563
-
2564
-	if (
2565
-		!((isset($deb->texte[0]) and $deb->texte[0] == '(')
2566
-		&& (isset($last->texte[$n - 1]) and $last->texte[$n - 1] == ')'))
2567
-	) {
2568
-		return $params;
2569
-	}
2570
-	$params[0][0]->texte = substr($deb->texte, 1);
2571
-	// attention, on peut avoir k=0,j=0 ==> recalculer
2572
-	$last = $params[$k][$j];
2573
-	$n = strlen($last->texte);
2574
-	$params[$k][$j]->texte = substr($last->texte, 0, $n - 1);
2575
-	$newp = [];
2576
-	foreach ($params as $v) {
2577
-		if ($v[0]->type != 'texte') {
2578
-			$newp[] = $v;
2579
-		} else {
2580
-			foreach (explode(',', $v[0]->texte) as $x) {
2581
-				$t = new Texte();
2582
-				$t->texte = $x;
2583
-				$newp[] = [$t];
2584
-			}
2585
-		}
2586
-	}
2587
-
2588
-	return $newp;
2557
+    $deb = $params[0][0];
2558
+    $k = (is_countable($params) ? count($params) : 0) - 1;
2559
+    $last = $params[$k];
2560
+    $j = (is_countable($last) ? count($last) : 0) - 1;
2561
+    $last = $last[$j];
2562
+    $n = isset($last->texte) ? strlen($last->texte) : 0;
2563
+
2564
+    if (
2565
+        !((isset($deb->texte[0]) and $deb->texte[0] == '(')
2566
+        && (isset($last->texte[$n - 1]) and $last->texte[$n - 1] == ')'))
2567
+    ) {
2568
+        return $params;
2569
+    }
2570
+    $params[0][0]->texte = substr($deb->texte, 1);
2571
+    // attention, on peut avoir k=0,j=0 ==> recalculer
2572
+    $last = $params[$k][$j];
2573
+    $n = strlen($last->texte);
2574
+    $params[$k][$j]->texte = substr($last->texte, 0, $n - 1);
2575
+    $newp = [];
2576
+    foreach ($params as $v) {
2577
+        if ($v[0]->type != 'texte') {
2578
+            $newp[] = $v;
2579
+        } else {
2580
+            foreach (explode(',', $v[0]->texte) as $x) {
2581
+                $t = new Texte();
2582
+                $t->texte = $x;
2583
+                $newp[] = [$t];
2584
+            }
2585
+        }
2586
+    }
2587
+
2588
+    return $newp;
2589 2589
 }
2590 2590
 
2591 2591
 /**
@@ -2604,95 +2604,95 @@  discard block
 block discarded – undo
2604 2604
  *     - nom de la colonne de date (si le calcul n'est pas relatif)
2605 2605
  **/
2606 2606
 function calculer_critere_infixe_date($idb, &$boucles, $col) {
2607
-	if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) {
2608
-		return '';
2609
-	}
2610
-
2611
-	$boucle = $boucles[$idb];
2612
-	$table = $boucle->show;
2613
-
2614
-	// si c'est une colonne de la table, ne rien faire
2615
-	if (isset($table['field'][$col])) {
2616
-		return '';
2617
-	}
2618
-
2619
-	// Le type de critère à prendre en compte
2620
-	$col = $regs[1];
2621
-
2622
-	// Si on trouve un nom de champ date précis, on l'utilise, pas besoin de déclaration dans l'API objet
2623
-	if (isset($regs[3]) and $suite = $regs[3]) {
2624
-		# Recherche de l'existence du champ date_xxxx,
2625
-		# si oui choisir ce champ, sinon choisir xxxx
2626
-		if (isset($table['field']["date$suite"])) {
2627
-			$date_orig = 'date' . $suite;
2628
-		} else {
2629
-			$date_orig = substr($suite, 1);
2630
-		}
2631
-
2632
-		$pred = $date_orig;
2633
-	} else { // Sinon il FAUT avoir déclaré le champ date officiel dans l'API objet
2634
-		// Si aucune déclaration trouvée, on quitte
2635
-		if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) {
2636
-			return '';
2637
-		}
2638
-		// Par défaut, on prend le champ date déclaré dans l'API
2639
-		$pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date'];
2640
-
2641
-		// Si c'est pour du relatif
2642
-		if (isset($regs[2]) and $rel = $regs[2]) {
2643
-			$pred = 'date';
2644
-		}
2645
-	}
2646
-
2647
-	$date_compare = "\"' . normaliser_date(" .
2648
-		calculer_argument_precedent($idb, $pred, $boucles) .
2649
-		") . '\"";
2650
-
2651
-	$col_vraie = $date_orig;
2652
-	$date_orig = $boucle->id_table . '.' . $date_orig;
2653
-
2654
-	switch ($col) {
2655
-		case 'date':
2656
-			$col = $date_orig;
2657
-			break;
2658
-		case 'jour':
2659
-			$col = "DAYOFMONTH($date_orig)";
2660
-			break;
2661
-		case 'mois':
2662
-			$col = "MONTH($date_orig)";
2663
-			break;
2664
-		case 'annee':
2665
-			$col = "YEAR($date_orig)";
2666
-			break;
2667
-		case 'heure':
2668
-			$col = "DATE_FORMAT($date_orig, \\'%H:%i\\')";
2669
-			break;
2670
-		case 'age':
2671
-			$col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig);
2672
-			$col_vraie = '';// comparer a un int (par defaut)
2673
-			break;
2674
-		case 'age_relatif':
2675
-			$col = calculer_param_date($date_compare, $date_orig);
2676
-			$col_vraie = '';// comparer a un int (par defaut)
2677
-			break;
2678
-		case 'jour_relatif':
2679
-			$col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))';
2680
-			$col_vraie = '';// comparer a un int (par defaut)
2681
-			break;
2682
-		case 'mois_relatif':
2683
-			$col = 'MONTH(' . $date_compare . ')-MONTH(' .
2684
-				$date_orig . ')+12*(YEAR(' . $date_compare .
2685
-				')-YEAR(' . $date_orig . '))';
2686
-			$col_vraie = '';// comparer a un int (par defaut)
2687
-			break;
2688
-		case 'annee_relatif':
2689
-			$col = 'YEAR(' . $date_compare . ')-YEAR(' .
2690
-				$date_orig . ')';
2691
-			$col_vraie = '';// comparer a un int (par defaut)
2692
-			break;
2693
-	}
2694
-
2695
-	return [$col, $col_vraie];
2607
+    if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) {
2608
+        return '';
2609
+    }
2610
+
2611
+    $boucle = $boucles[$idb];
2612
+    $table = $boucle->show;
2613
+
2614
+    // si c'est une colonne de la table, ne rien faire
2615
+    if (isset($table['field'][$col])) {
2616
+        return '';
2617
+    }
2618
+
2619
+    // Le type de critère à prendre en compte
2620
+    $col = $regs[1];
2621
+
2622
+    // Si on trouve un nom de champ date précis, on l'utilise, pas besoin de déclaration dans l'API objet
2623
+    if (isset($regs[3]) and $suite = $regs[3]) {
2624
+        # Recherche de l'existence du champ date_xxxx,
2625
+        # si oui choisir ce champ, sinon choisir xxxx
2626
+        if (isset($table['field']["date$suite"])) {
2627
+            $date_orig = 'date' . $suite;
2628
+        } else {
2629
+            $date_orig = substr($suite, 1);
2630
+        }
2631
+
2632
+        $pred = $date_orig;
2633
+    } else { // Sinon il FAUT avoir déclaré le champ date officiel dans l'API objet
2634
+        // Si aucune déclaration trouvée, on quitte
2635
+        if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) {
2636
+            return '';
2637
+        }
2638
+        // Par défaut, on prend le champ date déclaré dans l'API
2639
+        $pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date'];
2640
+
2641
+        // Si c'est pour du relatif
2642
+        if (isset($regs[2]) and $rel = $regs[2]) {
2643
+            $pred = 'date';
2644
+        }
2645
+    }
2646
+
2647
+    $date_compare = "\"' . normaliser_date(" .
2648
+        calculer_argument_precedent($idb, $pred, $boucles) .
2649
+        ") . '\"";
2650
+
2651
+    $col_vraie = $date_orig;
2652
+    $date_orig = $boucle->id_table . '.' . $date_orig;
2653
+
2654
+    switch ($col) {
2655
+        case 'date':
2656
+            $col = $date_orig;
2657
+            break;
2658
+        case 'jour':
2659
+            $col = "DAYOFMONTH($date_orig)";
2660
+            break;
2661
+        case 'mois':
2662
+            $col = "MONTH($date_orig)";
2663
+            break;
2664
+        case 'annee':
2665
+            $col = "YEAR($date_orig)";
2666
+            break;
2667
+        case 'heure':
2668
+            $col = "DATE_FORMAT($date_orig, \\'%H:%i\\')";
2669
+            break;
2670
+        case 'age':
2671
+            $col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig);
2672
+            $col_vraie = '';// comparer a un int (par defaut)
2673
+            break;
2674
+        case 'age_relatif':
2675
+            $col = calculer_param_date($date_compare, $date_orig);
2676
+            $col_vraie = '';// comparer a un int (par defaut)
2677
+            break;
2678
+        case 'jour_relatif':
2679
+            $col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))';
2680
+            $col_vraie = '';// comparer a un int (par defaut)
2681
+            break;
2682
+        case 'mois_relatif':
2683
+            $col = 'MONTH(' . $date_compare . ')-MONTH(' .
2684
+                $date_orig . ')+12*(YEAR(' . $date_compare .
2685
+                ')-YEAR(' . $date_orig . '))';
2686
+            $col_vraie = '';// comparer a un int (par defaut)
2687
+            break;
2688
+        case 'annee_relatif':
2689
+            $col = 'YEAR(' . $date_compare . ')-YEAR(' .
2690
+                $date_orig . ')';
2691
+            $col_vraie = '';// comparer a un int (par defaut)
2692
+            break;
2693
+    }
2694
+
2695
+    return [$col, $col_vraie];
2696 2696
 }
2697 2697
 
2698 2698
 /**
@@ -2711,16 +2711,16 @@  discard block
 block discarded – undo
2711 2711
  *     de colonne SQL et une date.
2712 2712
  **/
2713 2713
 function calculer_param_date($date_compare, $date_orig) {
2714
-	if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) {
2715
-		$init = "'\" . (\$x = $r[1]) . \"'";
2716
-		$date_compare = '\'$x\'';
2717
-	} else {
2718
-		$init = $date_compare;
2719
-	}
2720
-
2721
-	return
2722
-		// optimisation : mais prevoir le support SQLite avant
2723
-		"TIMESTAMPDIFF(HOUR,$date_orig,$init)/24";
2714
+    if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) {
2715
+        $init = "'\" . (\$x = $r[1]) . \"'";
2716
+        $date_compare = '\'$x\'';
2717
+    } else {
2718
+        $init = $date_compare;
2719
+    }
2720
+
2721
+    return
2722
+        // optimisation : mais prevoir le support SQLite avant
2723
+        "TIMESTAMPDIFF(HOUR,$date_orig,$init)/24";
2724 2724
 }
2725 2725
 
2726 2726
 /**
@@ -2738,20 +2738,20 @@  discard block
 block discarded – undo
2738 2738
  * @param Critere $crit Paramètres du critère dans cette boucle
2739 2739
  */
2740 2740
 function critere_DATA_source_dist($idb, &$boucles, $crit) {
2741
-	$boucle = &$boucles[$idb];
2742
-
2743
-	$args = [];
2744
-	foreach ($crit->param as &$param) {
2745
-		array_push(
2746
-			$args,
2747
-			calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent)
2748
-		);
2749
-	}
2741
+    $boucle = &$boucles[$idb];
2750 2742
 
2751
-	$boucle->hash .= '
2743
+    $args = [];
2744
+    foreach ($crit->param as &$param) {
2745
+        array_push(
2746
+            $args,
2747
+            calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent)
2748
+        );
2749
+    }
2750
+
2751
+    $boucle->hash .= '
2752 2752
 	$command[\'sourcemode\'] = ' . array_shift($args) . ";\n";
2753 2753
 
2754
-	$boucle->hash .= '
2754
+    $boucle->hash .= '
2755 2755
 	$command[\'source\'] = array(' . join(', ', $args) . ");\n";
2756 2756
 }
2757 2757
 
@@ -2769,8 +2769,8 @@  discard block
 block discarded – undo
2769 2769
  * @param Critere $crit Paramètres du critère dans cette boucle
2770 2770
  */
2771 2771
 function critere_DATA_datacache_dist($idb, &$boucles, $crit) {
2772
-	$boucle = &$boucles[$idb];
2773
-	$boucle->hash .= '
2772
+    $boucle = &$boucles[$idb];
2773
+    $boucle->hash .= '
2774 2774
 	$command[\'datacache\'] = ' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2775 2775
 }
2776 2776
 
@@ -2786,12 +2786,12 @@  discard block
 block discarded – undo
2786 2786
  * @param Critere $crit Paramètres du critère dans cette boucle
2787 2787
  */
2788 2788
 function critere_php_args_dist($idb, &$boucles, $crit) {
2789
-	$boucle = &$boucles[$idb];
2790
-	$boucle->hash .= '$command[\'args\']=array();';
2791
-	foreach ($crit->param as $param) {
2792
-		$boucle->hash .= '
2789
+    $boucle = &$boucles[$idb];
2790
+    $boucle->hash .= '$command[\'args\']=array();';
2791
+    foreach ($crit->param as $param) {
2792
+        $boucle->hash .= '
2793 2793
 			$command[\'args\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2794
-	}
2794
+    }
2795 2795
 }
2796 2796
 
2797 2797
 /**
@@ -2808,16 +2808,16 @@  discard block
 block discarded – undo
2808 2808
  * @param Critere $crit Paramètres du critère dans cette boucle
2809 2809
  */
2810 2810
 function critere_DATA_liste_dist($idb, &$boucles, $crit) {
2811
-	$boucle = &$boucles[$idb];
2812
-	$boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n";
2813
-	foreach ($crit->param as $param) {
2814
-		$boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste(
2815
-			$param,
2816
-			$idb,
2817
-			$boucles,
2818
-			$boucles[$idb]->id_parent
2819
-		) . ";\n";
2820
-	}
2811
+    $boucle = &$boucles[$idb];
2812
+    $boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n";
2813
+    foreach ($crit->param as $param) {
2814
+        $boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste(
2815
+            $param,
2816
+            $idb,
2817
+            $boucles,
2818
+            $boucles[$idb]->id_parent
2819
+        ) . ";\n";
2820
+    }
2821 2821
 }
2822 2822
 
2823 2823
 /**
@@ -2842,16 +2842,16 @@  discard block
 block discarded – undo
2842 2842
  * @param Critere $crit Paramètres du critère dans cette boucle
2843 2843
  */
2844 2844
 function critere_DATA_enum_dist($idb, &$boucles, $crit) {
2845
-	$boucle = &$boucles[$idb];
2846
-	$boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n";
2847
-	foreach ($crit->param as $param) {
2848
-		$boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste(
2849
-			$param,
2850
-			$idb,
2851
-			$boucles,
2852
-			$boucles[$idb]->id_parent
2853
-		) . ";\n";
2854
-	}
2845
+    $boucle = &$boucles[$idb];
2846
+    $boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n";
2847
+    foreach ($crit->param as $param) {
2848
+        $boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste(
2849
+            $param,
2850
+            $idb,
2851
+            $boucles,
2852
+            $boucles[$idb]->id_parent
2853
+        ) . ";\n";
2854
+    }
2855 2855
 }
2856 2856
 
2857 2857
 /**
@@ -2866,11 +2866,11 @@  discard block
 block discarded – undo
2866 2866
  * @param Critere $crit Paramètres du critère dans cette boucle
2867 2867
  */
2868 2868
 function critere_DATA_datapath_dist($idb, &$boucles, $crit) {
2869
-	$boucle = &$boucles[$idb];
2870
-	foreach ($crit->param as $param) {
2871
-		$boucle->hash .= '
2869
+    $boucle = &$boucles[$idb];
2870
+    foreach ($crit->param as $param) {
2871
+        $boucle->hash .= '
2872 2872
 			$command[\'datapath\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2873
-	}
2873
+    }
2874 2874
 }
2875 2875
 
2876 2876
 
@@ -2902,20 +2902,20 @@  discard block
 block discarded – undo
2902 2902
  * @param Critere $crit Paramètres du critère dans cette boucle
2903 2903
  */
2904 2904
 function critere_si_dist($idb, &$boucles, $crit) {
2905
-	$boucle = &$boucles[$idb];
2906
-	// il faut initialiser 1 fois le tableau a chaque appel de la boucle
2907
-	// (par exemple lorsque notre boucle est appelee dans une autre boucle)
2908
-	// mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle !
2909
-	$boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
2910
-	if ($crit->param) {
2911
-		foreach ($crit->param as $param) {
2912
-			$boucle->hash .= "\t\$command['si'][] = "
2913
-				. calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n";
2914
-		}
2915
-		// interdire {si 0} aussi !
2916
-	} else {
2917
-		$boucle->hash .= '$command[\'si\'][] = 0;';
2918
-	}
2905
+    $boucle = &$boucles[$idb];
2906
+    // il faut initialiser 1 fois le tableau a chaque appel de la boucle
2907
+    // (par exemple lorsque notre boucle est appelee dans une autre boucle)
2908
+    // mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle !
2909
+    $boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
2910
+    if ($crit->param) {
2911
+        foreach ($crit->param as $param) {
2912
+            $boucle->hash .= "\t\$command['si'][] = "
2913
+                . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n";
2914
+        }
2915
+        // interdire {si 0} aussi !
2916
+    } else {
2917
+        $boucle->hash .= '$command[\'si\'][] = 0;';
2918
+    }
2919 2919
 }
2920 2920
 
2921 2921
 /**
@@ -2932,8 +2932,8 @@  discard block
 block discarded – undo
2932 2932
  * @param Critere $crit Paramètres du critère dans cette boucle
2933 2933
  */
2934 2934
 function critere_POUR_tableau_dist($idb, &$boucles, $crit) {
2935
-	$boucle = &$boucles[$idb];
2936
-	$boucle->hash .= '
2935
+    $boucle = &$boucles[$idb];
2936
+    $boucle->hash .= '
2937 2937
 	$command[\'source\'] = array(' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent) . ');
2938 2938
 	$command[\'sourcemode\'] = \'table\';';
2939 2939
 }
@@ -2954,27 +2954,27 @@  discard block
 block discarded – undo
2954 2954
  */
2955 2955
 function critere_noeud_dist($idb, &$boucles, $crit) {
2956 2956
 
2957
-	$not = $crit->not;
2958
-	$boucle = &$boucles[$idb];
2959
-	$primary = $boucle->primary;
2957
+    $not = $crit->not;
2958
+    $boucle = &$boucles[$idb];
2959
+    $primary = $boucle->primary;
2960 2960
 
2961
-	if (!$primary or strpos($primary, ',')) {
2962
-		erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle);
2961
+    if (!$primary or strpos($primary, ',')) {
2962
+        erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle);
2963 2963
 
2964
-		return;
2965
-	}
2966
-	$table = $boucle->type_requete;
2967
-	$table_sql = table_objet_sql(objet_type($table));
2964
+        return;
2965
+    }
2966
+    $table = $boucle->type_requete;
2967
+    $table_sql = table_objet_sql(objet_type($table));
2968 2968
 
2969
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
2969
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
2970 2970
 
2971
-	$in = 'IN';
2972
-	$where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"];
2973
-	if ($not) {
2974
-		$where = ["'NOT'", $where];
2975
-	}
2971
+    $in = 'IN';
2972
+    $where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"];
2973
+    if ($not) {
2974
+        $where = ["'NOT'", $where];
2975
+    }
2976 2976
 
2977
-	$boucle->where[] = $where;
2977
+    $boucle->where[] = $where;
2978 2978
 }
2979 2979
 
2980 2980
 /**
@@ -2990,8 +2990,8 @@  discard block
 block discarded – undo
2990 2990
  * @param Critere $crit Paramètres du critère dans cette boucle
2991 2991
  */
2992 2992
 function critere_feuille_dist($idb, &$boucles, $crit) {
2993
-	$not = $crit->not;
2994
-	$crit->not = $not ? false : true;
2995
-	critere_noeud_dist($idb, $boucles, $crit);
2996
-	$crit->not = $not;
2993
+    $not = $crit->not;
2994
+    $crit->not = $not ? false : true;
2995
+    critere_noeud_dist($idb, $boucles, $crit);
2996
+    $crit->not = $not;
2997 2997
 }
Please login to merge, or discard this patch.
ecrire/public/interfaces.php 1 patch
Indentation   +922 added lines, -922 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  **/
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 
@@ -34,53 +34,53 @@  discard block
 block discarded – undo
34 34
  * @package SPIP\Core\Compilateur\AST
35 35
  */
36 36
 class Contexte {
37
-	/**
38
-	 * Description du squelette
39
-	 *
40
-	 * Sert pour la gestion d'erreur et la production de code dependant du contexte
41
-	 *
42
-	 * Peut contenir les index :
43
-	 *
44
-	 * - nom : Nom du fichier de cache
45
-	 * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
46
-	 * - sourcefile : Chemin du squelette
47
-	 * - squelette : Code du squelette
48
-	 * - id_mere : Identifiant de la boucle parente
49
-	 * - documents : Pour embed et img dans les textes
50
-	 * - session : Pour un cache sessionné par auteur
51
-	 * - niv : Niveau de tabulation
52
-	 *
53
-	 * @var array
54
-	 */
55
-	public $descr = [];
56
-
57
-	/**
58
-	 * Identifiant de la boucle
59
-	 *
60
-	 * @var string
61
-	 */
62
-	public $id_boucle = '';
63
-
64
-	/**
65
-	 * Numéro de ligne dans le code source du squelette
66
-	 *
67
-	 * @var int
68
-	 */
69
-	public $ligne = 0;
70
-
71
-	/**
72
-	 * Langue d'exécution
73
-	 *
74
-	 * @var string
75
-	 */
76
-	public $lang = '';
77
-
78
-	/**
79
-	 * Résultat de la compilation: toujours une expression PHP
80
-	 *
81
-	 * @var string
82
-	 */
83
-	public $code = '';
37
+    /**
38
+     * Description du squelette
39
+     *
40
+     * Sert pour la gestion d'erreur et la production de code dependant du contexte
41
+     *
42
+     * Peut contenir les index :
43
+     *
44
+     * - nom : Nom du fichier de cache
45
+     * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
46
+     * - sourcefile : Chemin du squelette
47
+     * - squelette : Code du squelette
48
+     * - id_mere : Identifiant de la boucle parente
49
+     * - documents : Pour embed et img dans les textes
50
+     * - session : Pour un cache sessionné par auteur
51
+     * - niv : Niveau de tabulation
52
+     *
53
+     * @var array
54
+     */
55
+    public $descr = [];
56
+
57
+    /**
58
+     * Identifiant de la boucle
59
+     *
60
+     * @var string
61
+     */
62
+    public $id_boucle = '';
63
+
64
+    /**
65
+     * Numéro de ligne dans le code source du squelette
66
+     *
67
+     * @var int
68
+     */
69
+    public $ligne = 0;
70
+
71
+    /**
72
+     * Langue d'exécution
73
+     *
74
+     * @var string
75
+     */
76
+    public $lang = '';
77
+
78
+    /**
79
+     * Résultat de la compilation: toujours une expression PHP
80
+     *
81
+     * @var string
82
+     */
83
+    public $code = '';
84 84
 }
85 85
 
86 86
 
@@ -90,44 +90,44 @@  discard block
 block discarded – undo
90 90
  * @package SPIP\Core\Compilateur\AST
91 91
  **/
92 92
 class Texte {
93
-	/**
94
-	 * Type de noeud
95
-	 *
96
-	 * @var string
97
-	 */
98
-	public $type = 'texte';
99
-
100
-	/**
101
-	 * Le texte
102
-	 *
103
-	 * @var string
104
-	 */
105
-	public $texte;
106
-
107
-	/**
108
-	 * Contenu avant le texte.
109
-	 *
110
-	 * Vide ou apostrophe simple ou double si le texte en était entouré
111
-	 *
112
-	 * @var string|array
113
-	 */
114
-	public $avant = '';
115
-
116
-	/**
117
-	 * Contenu après le texte.
118
-	 *
119
-	 * Vide ou apostrophe simple ou double si le texte en était entouré
120
-	 *
121
-	 * @var string|array
122
-	 */
123
-	public $apres = '';
124
-
125
-	/**
126
-	 * Numéro de ligne dans le code source du squelette
127
-	 *
128
-	 * @var int
129
-	 */
130
-	public $ligne = 0;
93
+    /**
94
+     * Type de noeud
95
+     *
96
+     * @var string
97
+     */
98
+    public $type = 'texte';
99
+
100
+    /**
101
+     * Le texte
102
+     *
103
+     * @var string
104
+     */
105
+    public $texte;
106
+
107
+    /**
108
+     * Contenu avant le texte.
109
+     *
110
+     * Vide ou apostrophe simple ou double si le texte en était entouré
111
+     *
112
+     * @var string|array
113
+     */
114
+    public $avant = '';
115
+
116
+    /**
117
+     * Contenu après le texte.
118
+     *
119
+     * Vide ou apostrophe simple ou double si le texte en était entouré
120
+     *
121
+     * @var string|array
122
+     */
123
+    public $apres = '';
124
+
125
+    /**
126
+     * Numéro de ligne dans le code source du squelette
127
+     *
128
+     * @var int
129
+     */
130
+    public $ligne = 0;
131 131
 }
132 132
 
133 133
 /**
@@ -136,50 +136,50 @@  discard block
 block discarded – undo
136 136
  * @package SPIP\Core\Compilateur\AST
137 137
  **/
138 138
 class Inclure {
139
-	/**
140
-	 * Type de noeud
141
-	 *
142
-	 * @var string
143
-	 */
144
-	public $type = 'include';
145
-
146
-	/**
147
-	 * Nom d'un fichier inclu
148
-	 *
149
-	 * - Objet Texte si inclusion d'un autre squelette
150
-	 * - chaîne si inclusion d'un fichier PHP directement
151
-	 *
152
-	 * @var string|Texte
153
-	 */
154
-	public $texte;
155
-
156
-	/**
157
-	 * Inutilisé, propriété générique de l'AST
158
-	 *
159
-	 * @var string|array
160
-	 */
161
-	public $avant = '';
162
-
163
-	/**
164
-	 * Inutilisé, propriété générique de l'AST
165
-	 *
166
-	 * @var string|array
167
-	 */
168
-	public $apres = '';
169
-
170
-	/**
171
-	 * Numéro de ligne dans le code source du squelette
172
-	 *
173
-	 * @var int
174
-	 */
175
-	public $ligne = 0;
176
-
177
-	/**
178
-	 * Valeurs des paramètres
179
-	 *
180
-	 * @var array
181
-	 */
182
-	public $param = [];
139
+    /**
140
+     * Type de noeud
141
+     *
142
+     * @var string
143
+     */
144
+    public $type = 'include';
145
+
146
+    /**
147
+     * Nom d'un fichier inclu
148
+     *
149
+     * - Objet Texte si inclusion d'un autre squelette
150
+     * - chaîne si inclusion d'un fichier PHP directement
151
+     *
152
+     * @var string|Texte
153
+     */
154
+    public $texte;
155
+
156
+    /**
157
+     * Inutilisé, propriété générique de l'AST
158
+     *
159
+     * @var string|array
160
+     */
161
+    public $avant = '';
162
+
163
+    /**
164
+     * Inutilisé, propriété générique de l'AST
165
+     *
166
+     * @var string|array
167
+     */
168
+    public $apres = '';
169
+
170
+    /**
171
+     * Numéro de ligne dans le code source du squelette
172
+     *
173
+     * @var int
174
+     */
175
+    public $ligne = 0;
176
+
177
+    /**
178
+     * Valeurs des paramètres
179
+     *
180
+     * @var array
181
+     */
182
+    public $param = [];
183 183
 }
184 184
 
185 185
 
@@ -189,392 +189,392 @@  discard block
 block discarded – undo
189 189
  * @package SPIP\Core\Compilateur\AST
190 190
  **/
191 191
 class Boucle {
192
-	/**
193
-	 * Type de noeud
194
-	 *
195
-	 * @var string
196
-	 */
197
-	public $type = 'boucle';
198
-
199
-	/**
200
-	 * Identifiant de la boucle
201
-	 *
202
-	 * @var string
203
-	 */
204
-	public $id_boucle;
205
-
206
-	/**
207
-	 * Identifiant de la boucle parente
208
-	 *
209
-	 * @var string
210
-	 */
211
-	public $id_parent = '';
212
-
213
-	/**
214
-	 * Partie avant toujours affichee
215
-	 *
216
-	 * @var string|array
217
-	 */
218
-	public $preaff = '';
219
-
220
-	/**
221
-	 * Partie optionnelle avant
222
-	 *
223
-	 * @var string|array
224
-	 */
225
-	public $avant = '';
226
-
227
-	/**
228
-	 * Pour chaque élément
229
-	 *
230
-	 * @var string|array
231
-	 */
232
-	public $milieu = '';
233
-
234
-	/**
235
-	 * Partie optionnelle après
236
-	 *
237
-	 * @var string|array
238
-	 */
239
-	public $apres = '';
240
-
241
-	/**
242
-	 * Partie alternative, si pas de résultat dans la boucle
243
-	 *
244
-	 * @var string|array
245
-	 */
246
-	public $altern = '';
247
-
248
-	/**
249
-	 * Partie apres toujours affichee
250
-	 *
251
-	 * @var string|array
252
-	 */
253
-	public $postaff = '';
254
-
255
-
256
-	/**
257
-	 * La boucle doit-elle sélectionner la langue ?
258
-	 *
259
-	 * @var string|null
260
-	 */
261
-	public $lang_select;
262
-
263
-	/**
264
-	 * Alias de table d'application de la requête ou nom complet de la table SQL
265
-	 *
266
-	 * @var string|null
267
-	 */
268
-	public $type_requete;
269
-
270
-	/**
271
-	 * La table est elle optionnelle ?
272
-	 *
273
-	 * Si oui, aucune erreur ne sera générée si la table demandée n'est pas présente
274
-	 *
275
-	 * @var bool
276
-	 */
277
-	public $table_optionnelle = false;
278
-
279
-	/**
280
-	 * Nom du fichier de connexion
281
-	 *
282
-	 * @var string
283
-	 */
284
-	public $sql_serveur = '';
285
-
286
-	/**
287
-	 * Paramètres de la boucle
288
-	 *
289
-	 * Description des paramètres passés à la boucle, qui servent ensuite
290
-	 * au calcul des critères
291
-	 *
292
-	 * @var array
293
-	 */
294
-	public $param = [];
295
-
296
-	/**
297
-	 * Critères de la boucle
298
-	 *
299
-	 * @var Critere[]
300
-	 */
301
-	public $criteres = [];
302
-
303
-	/**
304
-	 * Textes insérés entre 2 éléments de boucle (critère inter)
305
-	 *
306
-	 * @var string[]
307
-	 */
308
-	public $separateur = [];
309
-
310
-	/**
311
-	 * Liste des jointures possibles avec cette table
312
-	 *
313
-	 * Les jointures par défaut de la table sont complétées en priorité
314
-	 * des jointures déclarées explicitement sur la boucle
315
-	 *
316
-	 * @see base_trouver_table_dist()
317
-	 * @var array
318
-	 */
319
-	public $jointures = [];
320
-
321
-	/**
322
-	 * Jointures explicites avec cette table
323
-	 *
324
-	 * Ces jointures sont utilisées en priorité par rapport aux jointures
325
-	 * normales possibles pour retrouver les colonnes demandées extérieures
326
-	 * à la boucle.
327
-	 *
328
-	 * @var string|bool
329
-	 */
330
-	public $jointures_explicites = false;
331
-
332
-	/**
333
-	 * Nom de la variable PHP stockant le noms de doublons utilisés "$doublons_index"
334
-	 *
335
-	 * @var string|null
336
-	 */
337
-	public $doublons;
338
-
339
-	/**
340
-	 * Code PHP ajouté au début de chaque itération de boucle.
341
-	 *
342
-	 * Utilisé entre autre par les critères {pagination}, {n-a,b}, {a/b}...
343
-	 *
344
-	 * @var string
345
-	 */
346
-	public $partie = '';
347
-
348
-	/**
349
-	 * Nombre de divisions de la boucle, d'éléments à afficher,
350
-	 * ou de soustractions d'éléments à faire
351
-	 *
352
-	 * Dans les critères limitant le nombre d'éléments affichés
353
-	 * {a,b}, {a,n-b}, {a/b}, {pagination b}, b est affecté à total_parties.
354
-	 *
355
-	 * @var string
356
-	 */
357
-	public $total_parties = '';
358
-
359
-	/**
360
-	 * Code PHP ajouté avant l'itération de boucle.
361
-	 *
362
-	 * Utilisé entre autre par les critères {pagination}, {a,b}, {a/b}
363
-	 * pour initialiser les variables de début et de fin d'itération.
364
-	 *
365
-	 * @var string
366
-	 */
367
-	public $mode_partie = '';
368
-
369
-	/**
370
-	 * Identifiant d'une boucle qui appelle celle-ci de manière récursive
371
-	 *
372
-	 * Si une boucle est appelée de manière récursive quelque part par
373
-	 * une autre boucle comme <BOUCLE_rec(boucle_identifiant) />, cette
374
-	 * boucle (identifiant) reçoit dans cette propriété l'identifiant
375
-	 * de l'appelant (rec)
376
-	 *
377
-	 * @var string
378
-	 */
379
-	public $externe = '';
380
-
381
-	// champs pour la construction de la requete SQL
382
-
383
-	/**
384
-	 * Liste des champs à récupérer par la boucle
385
-	 *
386
-	 * Expression 'table.nom_champ' ou calculée 'nom_champ AS x'
387
-	 *
388
-	 * @var string[]
389
-	 */
390
-	public $select = [];
391
-
392
-	/**
393
-	 * Liste des alias / tables SQL utilisées dans la boucle
394
-	 *
395
-	 * L'index est un identifiant (xx dans spip_xx assez souvent) qui servira
396
-	 * d'alias au nom de la table ; la valeur est le nom de la table SQL désirée.
397
-	 *
398
-	 * L'index 0 peut définir le type de sources de données de l'itérateur DATA
399
-	 *
400
-	 * @var string[]
401
-	 */
402
-	public $from = [];
403
-
404
-	/**
405
-	 * Liste des alias / type de jointures utilisées dans la boucle
406
-	 *
407
-	 * L'index est le nom d'alias (comme pour la propriété $from), et la valeur
408
-	 * un type de jointure parmi 'INNER', 'LEFT', 'RIGHT', 'OUTER'.
409
-	 *
410
-	 * Lorsque le type n'est pas déclaré pour un alias, c'est 'INNER'
411
-	 * qui sera utilisé par défaut (créant donc un INNER JOIN).
412
-	 *
413
-	 * @var string[]
414
-	 */
415
-	public $from_type = [];
416
-
417
-	/**
418
-	 * Liste des conditions WHERE de la boucle
419
-	 *
420
-	 * Permet de restreindre les éléments retournés par une boucle
421
-	 * en fonctions des conditions transmises dans ce tableau.
422
-	 *
423
-	 * Ce tableau peut avoir plusieurs niveaux de profondeur.
424
-	 *
425
-	 * Les éléments du premier niveau sont reliés par des AND, donc
426
-	 * chaque élément ajouté directement au where par
427
-	 * $boucle->where[] = array(...) ou $boucle->where[] = "'expression'"
428
-	 * est une condition AND en plus.
429
-	 *
430
-	 * Par contre, lorsqu'on indique un tableau, il peut décrire des relations
431
-	 * internes différentes. Soit $expr un tableau d'expressions quelconques de 3 valeurs :
432
-	 * $expr = array(operateur, val1, val2)
433
-	 *
434
-	 * Ces 3 valeurs sont des expressions PHP. L'index 0 désigne l'opérateur
435
-	 * à réaliser tel que :
436
-	 *
437
-	 * - "'='" , "'>='", "'<'", "'IN'", "'REGEXP'", "'LIKE'", ... :
438
-	 *    val1 et val2 sont des champs et valeurs à utiliser dans la comparaison
439
-	 *    suivant cet ordre : "val1 operateur val2".
440
-	 *    Exemple : $boucle->where[] = array("'='", "'articles.statut'", "'\"publie\"'");
441
-	 * - "'AND'", "'OR'", "'NOT'" :
442
-	 *    dans ce cas val1 et val2 sont également des expressions
443
-	 *    de comparaison complètes, et peuvent être eux-même des tableaux comme $expr
444
-	 *    Exemples :
445
-	 *    $boucle->where[] = array("'OR'", $expr1, $expr2);
446
-	 *    $boucle->where[] = array("'NOT'", $expr); // val2 n'existe pas avec NOT
447
-	 *
448
-	 * D'autres noms sont possibles pour l'opérateur (le nombre de valeurs diffère) :
449
-	 * - "'SELF'", "'SUBSELECT'" : indiquent des sous requêtes
450
-	 * - "'?'" : indique une condition à faire évaluer (val1 ? val2 : val3)
451
-	 *
452
-	 * @var array
453
-	 */
454
-	public $where = [];
455
-
456
-	public $join = [];
457
-	public $having = [];
458
-	public $limit = '';
459
-	public $group = [];
460
-	public $order = [];
461
-	public $default_order = [];
462
-	public $date = 'date';
463
-	public $hash = '';
464
-	public $in = '';
465
-	public $sous_requete = false;
466
-
467
-	/**
468
-	 * Code PHP qui sera ajouté en tout début de la fonction de boucle
469
-	 *
470
-	 * Il sert à insérer le code calculant une hierarchie
471
-	 *
472
-	 * @var string
473
-	 */
474
-	public $hierarchie = '';
475
-
476
-	// champs pour la construction du corps PHP
477
-
478
-	/**
479
-	 * Description des sources de données de la boucle
480
-	 *
481
-	 * Description des données de la boucle issu de trouver_table
482
-	 * dans le cadre de l'itérateur SQL et contenant au moins l'index 'field'.
483
-	 *
484
-	 * @see base_trouver_table_dist()
485
-	 * @var array
486
-	 */
487
-	public $show = [];
488
-
489
-	/**
490
-	 * Nom de la table SQL principale de la boucle, sans son préfixe
491
-	 *
492
-	 * @var string
493
-	 */
494
-	public $id_table;
495
-
496
-	/**
497
-	 * Nom de la clé primaire de la table SQL principale de la boucle
498
-	 *
499
-	 * @var string
500
-	 */
501
-	public $primary;
502
-
503
-	/**
504
-	 * Code PHP compilé de la boucle
505
-	 *
506
-	 * @var string
507
-	 */
508
-	public $return;
509
-
510
-	public $numrows = false;
511
-	public $cptrows = false;
512
-
513
-	/**
514
-	 * Description du squelette
515
-	 *
516
-	 * Sert pour la gestion d'erreur et la production de code dependant du contexte
517
-	 *
518
-	 * Peut contenir les index :
519
-	 *
520
-	 * - nom : Nom du fichier de cache
521
-	 * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
522
-	 * - sourcefile : Chemin du squelette
523
-	 * - squelette : Code du squelette
524
-	 * - id_mere : Identifiant de la boucle parente
525
-	 * - documents : Pour embed et img dans les textes
526
-	 * - session : Pour un cache sessionné par auteur
527
-	 * - niv : Niveau de tabulation
528
-	 *
529
-	 * @var array
530
-	 */
531
-	public $descr = [];
532
-
533
-	/**
534
-	 * Numéro de ligne dans le code source du squelette
535
-	 *
536
-	 * @var int
537
-	 */
538
-	public $ligne = 0;
539
-
540
-
541
-	/**
542
-	 * table pour stocker les modificateurs de boucle tels que tout, plat ...,
543
-	 * utilisable par les plugins egalement
544
-	 *
545
-	 * @var array<string, mixed>
546
-	 */
547
-	public $modificateur = [];
548
-
549
-	/**
550
-	 * Type d'itérateur utilisé pour cette boucle
551
-	 *
552
-	 * - 'SQL' dans le cadre d'une boucle sur une table SQL
553
-	 * - 'DATA' pour l'itérateur DATA, ...
554
-	 *
555
-	 * @var string
556
-	 */
557
-	public $iterateur = ''; // type d'iterateur
558
-
559
-	/**
560
-	 * @var array $debug Textes qui seront insérés dans l’entête de boucle du mode debug
561
-	 */
562
-	public $debug = [];
563
-
564
-	/**
565
-	 * Index de la boucle dont le champ présent dans cette boucle est originaire,
566
-	 * notamment si le champ a été trouve dans une boucle parente
567
-	 *
568
-	 * Tableau nom du champ => index de boucle
569
-	 *
570
-	 * @var array $index_champ
571
-	*/
572
-	public $index_champ = [];
573
-
574
-	// obsoletes, conserves provisoirement pour compatibilite
575
-	public $tout = false;
576
-	public $plat = false;
577
-	public $lien = false;
192
+    /**
193
+     * Type de noeud
194
+     *
195
+     * @var string
196
+     */
197
+    public $type = 'boucle';
198
+
199
+    /**
200
+     * Identifiant de la boucle
201
+     *
202
+     * @var string
203
+     */
204
+    public $id_boucle;
205
+
206
+    /**
207
+     * Identifiant de la boucle parente
208
+     *
209
+     * @var string
210
+     */
211
+    public $id_parent = '';
212
+
213
+    /**
214
+     * Partie avant toujours affichee
215
+     *
216
+     * @var string|array
217
+     */
218
+    public $preaff = '';
219
+
220
+    /**
221
+     * Partie optionnelle avant
222
+     *
223
+     * @var string|array
224
+     */
225
+    public $avant = '';
226
+
227
+    /**
228
+     * Pour chaque élément
229
+     *
230
+     * @var string|array
231
+     */
232
+    public $milieu = '';
233
+
234
+    /**
235
+     * Partie optionnelle après
236
+     *
237
+     * @var string|array
238
+     */
239
+    public $apres = '';
240
+
241
+    /**
242
+     * Partie alternative, si pas de résultat dans la boucle
243
+     *
244
+     * @var string|array
245
+     */
246
+    public $altern = '';
247
+
248
+    /**
249
+     * Partie apres toujours affichee
250
+     *
251
+     * @var string|array
252
+     */
253
+    public $postaff = '';
254
+
255
+
256
+    /**
257
+     * La boucle doit-elle sélectionner la langue ?
258
+     *
259
+     * @var string|null
260
+     */
261
+    public $lang_select;
262
+
263
+    /**
264
+     * Alias de table d'application de la requête ou nom complet de la table SQL
265
+     *
266
+     * @var string|null
267
+     */
268
+    public $type_requete;
269
+
270
+    /**
271
+     * La table est elle optionnelle ?
272
+     *
273
+     * Si oui, aucune erreur ne sera générée si la table demandée n'est pas présente
274
+     *
275
+     * @var bool
276
+     */
277
+    public $table_optionnelle = false;
278
+
279
+    /**
280
+     * Nom du fichier de connexion
281
+     *
282
+     * @var string
283
+     */
284
+    public $sql_serveur = '';
285
+
286
+    /**
287
+     * Paramètres de la boucle
288
+     *
289
+     * Description des paramètres passés à la boucle, qui servent ensuite
290
+     * au calcul des critères
291
+     *
292
+     * @var array
293
+     */
294
+    public $param = [];
295
+
296
+    /**
297
+     * Critères de la boucle
298
+     *
299
+     * @var Critere[]
300
+     */
301
+    public $criteres = [];
302
+
303
+    /**
304
+     * Textes insérés entre 2 éléments de boucle (critère inter)
305
+     *
306
+     * @var string[]
307
+     */
308
+    public $separateur = [];
309
+
310
+    /**
311
+     * Liste des jointures possibles avec cette table
312
+     *
313
+     * Les jointures par défaut de la table sont complétées en priorité
314
+     * des jointures déclarées explicitement sur la boucle
315
+     *
316
+     * @see base_trouver_table_dist()
317
+     * @var array
318
+     */
319
+    public $jointures = [];
320
+
321
+    /**
322
+     * Jointures explicites avec cette table
323
+     *
324
+     * Ces jointures sont utilisées en priorité par rapport aux jointures
325
+     * normales possibles pour retrouver les colonnes demandées extérieures
326
+     * à la boucle.
327
+     *
328
+     * @var string|bool
329
+     */
330
+    public $jointures_explicites = false;
331
+
332
+    /**
333
+     * Nom de la variable PHP stockant le noms de doublons utilisés "$doublons_index"
334
+     *
335
+     * @var string|null
336
+     */
337
+    public $doublons;
338
+
339
+    /**
340
+     * Code PHP ajouté au début de chaque itération de boucle.
341
+     *
342
+     * Utilisé entre autre par les critères {pagination}, {n-a,b}, {a/b}...
343
+     *
344
+     * @var string
345
+     */
346
+    public $partie = '';
347
+
348
+    /**
349
+     * Nombre de divisions de la boucle, d'éléments à afficher,
350
+     * ou de soustractions d'éléments à faire
351
+     *
352
+     * Dans les critères limitant le nombre d'éléments affichés
353
+     * {a,b}, {a,n-b}, {a/b}, {pagination b}, b est affecté à total_parties.
354
+     *
355
+     * @var string
356
+     */
357
+    public $total_parties = '';
358
+
359
+    /**
360
+     * Code PHP ajouté avant l'itération de boucle.
361
+     *
362
+     * Utilisé entre autre par les critères {pagination}, {a,b}, {a/b}
363
+     * pour initialiser les variables de début et de fin d'itération.
364
+     *
365
+     * @var string
366
+     */
367
+    public $mode_partie = '';
368
+
369
+    /**
370
+     * Identifiant d'une boucle qui appelle celle-ci de manière récursive
371
+     *
372
+     * Si une boucle est appelée de manière récursive quelque part par
373
+     * une autre boucle comme <BOUCLE_rec(boucle_identifiant) />, cette
374
+     * boucle (identifiant) reçoit dans cette propriété l'identifiant
375
+     * de l'appelant (rec)
376
+     *
377
+     * @var string
378
+     */
379
+    public $externe = '';
380
+
381
+    // champs pour la construction de la requete SQL
382
+
383
+    /**
384
+     * Liste des champs à récupérer par la boucle
385
+     *
386
+     * Expression 'table.nom_champ' ou calculée 'nom_champ AS x'
387
+     *
388
+     * @var string[]
389
+     */
390
+    public $select = [];
391
+
392
+    /**
393
+     * Liste des alias / tables SQL utilisées dans la boucle
394
+     *
395
+     * L'index est un identifiant (xx dans spip_xx assez souvent) qui servira
396
+     * d'alias au nom de la table ; la valeur est le nom de la table SQL désirée.
397
+     *
398
+     * L'index 0 peut définir le type de sources de données de l'itérateur DATA
399
+     *
400
+     * @var string[]
401
+     */
402
+    public $from = [];
403
+
404
+    /**
405
+     * Liste des alias / type de jointures utilisées dans la boucle
406
+     *
407
+     * L'index est le nom d'alias (comme pour la propriété $from), et la valeur
408
+     * un type de jointure parmi 'INNER', 'LEFT', 'RIGHT', 'OUTER'.
409
+     *
410
+     * Lorsque le type n'est pas déclaré pour un alias, c'est 'INNER'
411
+     * qui sera utilisé par défaut (créant donc un INNER JOIN).
412
+     *
413
+     * @var string[]
414
+     */
415
+    public $from_type = [];
416
+
417
+    /**
418
+     * Liste des conditions WHERE de la boucle
419
+     *
420
+     * Permet de restreindre les éléments retournés par une boucle
421
+     * en fonctions des conditions transmises dans ce tableau.
422
+     *
423
+     * Ce tableau peut avoir plusieurs niveaux de profondeur.
424
+     *
425
+     * Les éléments du premier niveau sont reliés par des AND, donc
426
+     * chaque élément ajouté directement au where par
427
+     * $boucle->where[] = array(...) ou $boucle->where[] = "'expression'"
428
+     * est une condition AND en plus.
429
+     *
430
+     * Par contre, lorsqu'on indique un tableau, il peut décrire des relations
431
+     * internes différentes. Soit $expr un tableau d'expressions quelconques de 3 valeurs :
432
+     * $expr = array(operateur, val1, val2)
433
+     *
434
+     * Ces 3 valeurs sont des expressions PHP. L'index 0 désigne l'opérateur
435
+     * à réaliser tel que :
436
+     *
437
+     * - "'='" , "'>='", "'<'", "'IN'", "'REGEXP'", "'LIKE'", ... :
438
+     *    val1 et val2 sont des champs et valeurs à utiliser dans la comparaison
439
+     *    suivant cet ordre : "val1 operateur val2".
440
+     *    Exemple : $boucle->where[] = array("'='", "'articles.statut'", "'\"publie\"'");
441
+     * - "'AND'", "'OR'", "'NOT'" :
442
+     *    dans ce cas val1 et val2 sont également des expressions
443
+     *    de comparaison complètes, et peuvent être eux-même des tableaux comme $expr
444
+     *    Exemples :
445
+     *    $boucle->where[] = array("'OR'", $expr1, $expr2);
446
+     *    $boucle->where[] = array("'NOT'", $expr); // val2 n'existe pas avec NOT
447
+     *
448
+     * D'autres noms sont possibles pour l'opérateur (le nombre de valeurs diffère) :
449
+     * - "'SELF'", "'SUBSELECT'" : indiquent des sous requêtes
450
+     * - "'?'" : indique une condition à faire évaluer (val1 ? val2 : val3)
451
+     *
452
+     * @var array
453
+     */
454
+    public $where = [];
455
+
456
+    public $join = [];
457
+    public $having = [];
458
+    public $limit = '';
459
+    public $group = [];
460
+    public $order = [];
461
+    public $default_order = [];
462
+    public $date = 'date';
463
+    public $hash = '';
464
+    public $in = '';
465
+    public $sous_requete = false;
466
+
467
+    /**
468
+     * Code PHP qui sera ajouté en tout début de la fonction de boucle
469
+     *
470
+     * Il sert à insérer le code calculant une hierarchie
471
+     *
472
+     * @var string
473
+     */
474
+    public $hierarchie = '';
475
+
476
+    // champs pour la construction du corps PHP
477
+
478
+    /**
479
+     * Description des sources de données de la boucle
480
+     *
481
+     * Description des données de la boucle issu de trouver_table
482
+     * dans le cadre de l'itérateur SQL et contenant au moins l'index 'field'.
483
+     *
484
+     * @see base_trouver_table_dist()
485
+     * @var array
486
+     */
487
+    public $show = [];
488
+
489
+    /**
490
+     * Nom de la table SQL principale de la boucle, sans son préfixe
491
+     *
492
+     * @var string
493
+     */
494
+    public $id_table;
495
+
496
+    /**
497
+     * Nom de la clé primaire de la table SQL principale de la boucle
498
+     *
499
+     * @var string
500
+     */
501
+    public $primary;
502
+
503
+    /**
504
+     * Code PHP compilé de la boucle
505
+     *
506
+     * @var string
507
+     */
508
+    public $return;
509
+
510
+    public $numrows = false;
511
+    public $cptrows = false;
512
+
513
+    /**
514
+     * Description du squelette
515
+     *
516
+     * Sert pour la gestion d'erreur et la production de code dependant du contexte
517
+     *
518
+     * Peut contenir les index :
519
+     *
520
+     * - nom : Nom du fichier de cache
521
+     * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
522
+     * - sourcefile : Chemin du squelette
523
+     * - squelette : Code du squelette
524
+     * - id_mere : Identifiant de la boucle parente
525
+     * - documents : Pour embed et img dans les textes
526
+     * - session : Pour un cache sessionné par auteur
527
+     * - niv : Niveau de tabulation
528
+     *
529
+     * @var array
530
+     */
531
+    public $descr = [];
532
+
533
+    /**
534
+     * Numéro de ligne dans le code source du squelette
535
+     *
536
+     * @var int
537
+     */
538
+    public $ligne = 0;
539
+
540
+
541
+    /**
542
+     * table pour stocker les modificateurs de boucle tels que tout, plat ...,
543
+     * utilisable par les plugins egalement
544
+     *
545
+     * @var array<string, mixed>
546
+     */
547
+    public $modificateur = [];
548
+
549
+    /**
550
+     * Type d'itérateur utilisé pour cette boucle
551
+     *
552
+     * - 'SQL' dans le cadre d'une boucle sur une table SQL
553
+     * - 'DATA' pour l'itérateur DATA, ...
554
+     *
555
+     * @var string
556
+     */
557
+    public $iterateur = ''; // type d'iterateur
558
+
559
+    /**
560
+     * @var array $debug Textes qui seront insérés dans l’entête de boucle du mode debug
561
+     */
562
+    public $debug = [];
563
+
564
+    /**
565
+     * Index de la boucle dont le champ présent dans cette boucle est originaire,
566
+     * notamment si le champ a été trouve dans une boucle parente
567
+     *
568
+     * Tableau nom du champ => index de boucle
569
+     *
570
+     * @var array $index_champ
571
+     */
572
+    public $index_champ = [];
573
+
574
+    // obsoletes, conserves provisoirement pour compatibilite
575
+    public $tout = false;
576
+    public $plat = false;
577
+    public $lien = false;
578 578
 }
579 579
 
580 580
 /**
@@ -585,56 +585,56 @@  discard block
 block discarded – undo
585 585
  * @package SPIP\Core\Compilateur\AST
586 586
  **/
587 587
 class Critere {
588
-	/**
589
-	 * Type de noeud
590
-	 *
591
-	 * @var string
592
-	 */
593
-	public $type = 'critere';
594
-
595
-	/**
596
-	 * Opérateur (>, <, >=, IN, ...)
597
-	 *
598
-	 * @var null|string
599
-	 */
600
-	public $op;
601
-
602
-	/**
603
-	 * Présence d'une négation (truc !op valeur)
604
-	 *
605
-	 * @var null|string
606
-	 */
607
-	public $not;
608
-
609
-	/**
610
-	 * Présence d'une exclusion (!truc op valeur)
611
-	 *
612
-	 * @var null|string
613
-	 */
614
-	public $exclus;
615
-
616
-	/**
617
-	 * Présence d'une condition dans le critère (truc ?)
618
-	 *
619
-	 * @var bool
620
-	 */
621
-	public $cond = false;
622
-
623
-	/**
624
-	 * Paramètres du critère
625
-	 * - $param[0] : élément avant l'opérateur
626
-	 * - $param[1..n] : éléments après l'opérateur
627
-	 *
628
-	 * @var array
629
-	 */
630
-	public $param = [];
631
-
632
-	/**
633
-	 * Numéro de ligne dans le code source du squelette
634
-	 *
635
-	 * @var int
636
-	 */
637
-	public $ligne = 0;
588
+    /**
589
+     * Type de noeud
590
+     *
591
+     * @var string
592
+     */
593
+    public $type = 'critere';
594
+
595
+    /**
596
+     * Opérateur (>, <, >=, IN, ...)
597
+     *
598
+     * @var null|string
599
+     */
600
+    public $op;
601
+
602
+    /**
603
+     * Présence d'une négation (truc !op valeur)
604
+     *
605
+     * @var null|string
606
+     */
607
+    public $not;
608
+
609
+    /**
610
+     * Présence d'une exclusion (!truc op valeur)
611
+     *
612
+     * @var null|string
613
+     */
614
+    public $exclus;
615
+
616
+    /**
617
+     * Présence d'une condition dans le critère (truc ?)
618
+     *
619
+     * @var bool
620
+     */
621
+    public $cond = false;
622
+
623
+    /**
624
+     * Paramètres du critère
625
+     * - $param[0] : élément avant l'opérateur
626
+     * - $param[1..n] : éléments après l'opérateur
627
+     *
628
+     * @var array
629
+     */
630
+    public $param = [];
631
+
632
+    /**
633
+     * Numéro de ligne dans le code source du squelette
634
+     *
635
+     * @var int
636
+     */
637
+    public $ligne = 0;
638 638
 }
639 639
 
640 640
 /**
@@ -643,139 +643,139 @@  discard block
 block discarded – undo
643 643
  * @package SPIP\Core\Compilateur\AST
644 644
  **/
645 645
 class Champ {
646
-	/**
647
-	 * Type de noeud
648
-	 *
649
-	 * @var string
650
-	 */
651
-	public $type = 'champ';
652
-
653
-	/**
654
-	 * Nom du champ demandé. Exemple 'ID_ARTICLE'
655
-	 *
656
-	 * @var string|null
657
-	 */
658
-	public $nom_champ;
659
-
660
-	/**
661
-	 * Identifiant de la boucle parente si explicité
662
-	 *
663
-	 * @var string|null
664
-	 */
665
-	public $nom_boucle = '';
666
-
667
-	/**
668
-	 * Partie optionnelle avant
669
-	 *
670
-	 * @var null|string|array
671
-	 */
672
-	public $avant;
673
-
674
-	/**
675
-	 * Partie optionnelle après
676
-	 *
677
-	 * @var null|string|array
678
-	 */
679
-	public $apres;
680
-
681
-	/**
682
-	 * Étoiles : annuler des automatismes
683
-	 *
684
-	 * - '*' annule les filtres automatiques
685
-	 * - '**' annule en plus les protections de scripts
686
-	 *
687
-	 * @var null|string
688
-	 */
689
-	public $etoile;
690
-
691
-	/**
692
-	 * Arguments et filtres explicites sur la balise
693
-	 *
694
-	 * - $param[0] contient les arguments de la balise
695
-	 * - $param[1..n] contient les filtres à appliquer à la balise
696
-	 *
697
-	 * @var array
698
-	 */
699
-	public $param = [];
700
-
701
-	/**
702
-	 * Source des filtres  (compatibilité) (?)
703
-	 *
704
-	 * @var array|null
705
-	 */
706
-	public $fonctions = [];
707
-
708
-	/**
709
-	 * Identifiant de la boucle
710
-	 *
711
-	 * @var string
712
-	 */
713
-	public $id_boucle = '';
714
-
715
-	/**
716
-	 * AST du squelette, liste de toutes les boucles
717
-	 *
718
-	 * @var Boucles[]
719
-	 */
720
-	public $boucles;
721
-
722
-	/**
723
-	 * Alias de table d'application de la requête ou nom complet de la table SQL
724
-	 *
725
-	 * @var string|null
726
-	 */
727
-	public $type_requete;
728
-
729
-	/**
730
-	 * Résultat de la compilation: toujours une expression PHP
731
-	 *
732
-	 * @var string
733
-	 */
734
-	public $code = '';
735
-
736
-	/**
737
-	 * Interdire les scripts
738
-	 *
739
-	 * false si on est sûr de cette balise
740
-	 *
741
-	 * @see interdire_scripts()
742
-	 * @var bool
743
-	 */
744
-	public $interdire_scripts = true;
745
-
746
-	/**
747
-	 * Description du squelette
748
-	 *
749
-	 * Sert pour la gestion d'erreur et la production de code dependant du contexte
750
-	 *
751
-	 * Peut contenir les index :
752
-	 *
753
-	 * - nom : Nom du fichier de cache
754
-	 * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
755
-	 * - sourcefile : Chemin du squelette
756
-	 * - squelette : Code du squelette
757
-	 * - id_mere : Identifiant de la boucle parente
758
-	 * - documents : Pour embed et img dans les textes
759
-	 * - session : Pour un cache sessionné par auteur
760
-	 * - niv : Niveau de tabulation
761
-	 *
762
-	 * @var array
763
-	 */
764
-	public $descr = [];
765
-
766
-	/**
767
-	 * Numéro de ligne dans le code source du squelette
768
-	 *
769
-	 * @var int
770
-	 */
771
-	public $ligne = 0;
772
-
773
-	/**
774
-	 * Drapeau pour reperer les balises calculées par une fonction explicite
775
-	 *
776
-	 * @var bool
777
-	 */
778
-	public $balise_calculee = false;
646
+    /**
647
+     * Type de noeud
648
+     *
649
+     * @var string
650
+     */
651
+    public $type = 'champ';
652
+
653
+    /**
654
+     * Nom du champ demandé. Exemple 'ID_ARTICLE'
655
+     *
656
+     * @var string|null
657
+     */
658
+    public $nom_champ;
659
+
660
+    /**
661
+     * Identifiant de la boucle parente si explicité
662
+     *
663
+     * @var string|null
664
+     */
665
+    public $nom_boucle = '';
666
+
667
+    /**
668
+     * Partie optionnelle avant
669
+     *
670
+     * @var null|string|array
671
+     */
672
+    public $avant;
673
+
674
+    /**
675
+     * Partie optionnelle après
676
+     *
677
+     * @var null|string|array
678
+     */
679
+    public $apres;
680
+
681
+    /**
682
+     * Étoiles : annuler des automatismes
683
+     *
684
+     * - '*' annule les filtres automatiques
685
+     * - '**' annule en plus les protections de scripts
686
+     *
687
+     * @var null|string
688
+     */
689
+    public $etoile;
690
+
691
+    /**
692
+     * Arguments et filtres explicites sur la balise
693
+     *
694
+     * - $param[0] contient les arguments de la balise
695
+     * - $param[1..n] contient les filtres à appliquer à la balise
696
+     *
697
+     * @var array
698
+     */
699
+    public $param = [];
700
+
701
+    /**
702
+     * Source des filtres  (compatibilité) (?)
703
+     *
704
+     * @var array|null
705
+     */
706
+    public $fonctions = [];
707
+
708
+    /**
709
+     * Identifiant de la boucle
710
+     *
711
+     * @var string
712
+     */
713
+    public $id_boucle = '';
714
+
715
+    /**
716
+     * AST du squelette, liste de toutes les boucles
717
+     *
718
+     * @var Boucles[]
719
+     */
720
+    public $boucles;
721
+
722
+    /**
723
+     * Alias de table d'application de la requête ou nom complet de la table SQL
724
+     *
725
+     * @var string|null
726
+     */
727
+    public $type_requete;
728
+
729
+    /**
730
+     * Résultat de la compilation: toujours une expression PHP
731
+     *
732
+     * @var string
733
+     */
734
+    public $code = '';
735
+
736
+    /**
737
+     * Interdire les scripts
738
+     *
739
+     * false si on est sûr de cette balise
740
+     *
741
+     * @see interdire_scripts()
742
+     * @var bool
743
+     */
744
+    public $interdire_scripts = true;
745
+
746
+    /**
747
+     * Description du squelette
748
+     *
749
+     * Sert pour la gestion d'erreur et la production de code dependant du contexte
750
+     *
751
+     * Peut contenir les index :
752
+     *
753
+     * - nom : Nom du fichier de cache
754
+     * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
755
+     * - sourcefile : Chemin du squelette
756
+     * - squelette : Code du squelette
757
+     * - id_mere : Identifiant de la boucle parente
758
+     * - documents : Pour embed et img dans les textes
759
+     * - session : Pour un cache sessionné par auteur
760
+     * - niv : Niveau de tabulation
761
+     *
762
+     * @var array
763
+     */
764
+    public $descr = [];
765
+
766
+    /**
767
+     * Numéro de ligne dans le code source du squelette
768
+     *
769
+     * @var int
770
+     */
771
+    public $ligne = 0;
772
+
773
+    /**
774
+     * Drapeau pour reperer les balises calculées par une fonction explicite
775
+     *
776
+     * @var bool
777
+     */
778
+    public $balise_calculee = false;
779 779
 }
780 780
 
781 781
 
@@ -783,123 +783,123 @@  discard block
 block discarded – undo
783 783
  * Description d'une chaîne de langue
784 784
  **/
785 785
 class Idiome {
786
-	/**
787
-	 * Type de noeud
788
-	 *
789
-	 * @var string
790
-	 */
791
-	public $type = 'idiome';
792
-
793
-	/**
794
-	 * Clé de traduction demandée. Exemple 'item_oui'
795
-	 *
796
-	 * @var string
797
-	 */
798
-	public $nom_champ = '';
799
-
800
-	/**
801
-	 * Module de langue où chercher la clé de traduction. Exemple 'medias'
802
-	 *
803
-	 * @var string
804
-	 */
805
-	public $module = '';
806
-
807
-	/**
808
-	 * Arguments à passer à la chaîne
809
-	 *
810
-	 * @var array
811
-	 */
812
-	public $arg = [];
813
-
814
-	/**
815
-	 * Filtres à appliquer au résultat
816
-	 *
817
-	 * @var array
818
-	 */
819
-	public $param = [];
820
-
821
-	/**
822
-	 * Source des filtres  (compatibilité) (?)
823
-	 *
824
-	 * @var array|null
825
-	 */
826
-	public $fonctions = [];
827
-
828
-	/**
829
-	 * Inutilisé, propriété générique de l'AST
830
-	 *
831
-	 * @var string|array
832
-	 */
833
-	public $avant = '';
834
-
835
-	/**
836
-	 * Inutilisé, propriété générique de l'AST
837
-	 *
838
-	 * @var string|array
839
-	 */
840
-	public $apres = '';
841
-
842
-	/**
843
-	 * Identifiant de la boucle
844
-	 *
845
-	 * @var string
846
-	 */
847
-	public $id_boucle = '';
848
-
849
-	/**
850
-	 * AST du squelette, liste de toutes les boucles
851
-	 *
852
-	 * @var Boucles[]
853
-	 */
854
-	public $boucles;
855
-
856
-	/**
857
-	 * Alias de table d'application de la requête ou nom complet de la table SQL
858
-	 *
859
-	 * @var string|null
860
-	 */
861
-	public $type_requete;
862
-
863
-	/**
864
-	 * Résultat de la compilation: toujours une expression PHP
865
-	 *
866
-	 * @var string
867
-	 */
868
-	public $code = '';
869
-
870
-	/**
871
-	 * Interdire les scripts
872
-	 *
873
-	 * @see interdire_scripts()
874
-	 * @var bool
875
-	 */
876
-	public $interdire_scripts = false;
877
-
878
-	/**
879
-	 * Description du squelette
880
-	 *
881
-	 * Sert pour la gestion d'erreur et la production de code dependant du contexte
882
-	 *
883
-	 * Peut contenir les index :
884
-	 * - nom : Nom du fichier de cache
885
-	 * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
886
-	 * - sourcefile : Chemin du squelette
887
-	 * - squelette : Code du squelette
888
-	 * - id_mere : Identifiant de la boucle parente
889
-	 * - documents : Pour embed et img dans les textes
890
-	 * - session : Pour un cache sessionné par auteur
891
-	 * - niv : Niveau de tabulation
892
-	 *
893
-	 * @var array
894
-	 */
895
-	public $descr = [];
896
-
897
-	/**
898
-	 * Numéro de ligne dans le code source du squelette
899
-	 *
900
-	 * @var int
901
-	 */
902
-	public $ligne = 0;
786
+    /**
787
+     * Type de noeud
788
+     *
789
+     * @var string
790
+     */
791
+    public $type = 'idiome';
792
+
793
+    /**
794
+     * Clé de traduction demandée. Exemple 'item_oui'
795
+     *
796
+     * @var string
797
+     */
798
+    public $nom_champ = '';
799
+
800
+    /**
801
+     * Module de langue où chercher la clé de traduction. Exemple 'medias'
802
+     *
803
+     * @var string
804
+     */
805
+    public $module = '';
806
+
807
+    /**
808
+     * Arguments à passer à la chaîne
809
+     *
810
+     * @var array
811
+     */
812
+    public $arg = [];
813
+
814
+    /**
815
+     * Filtres à appliquer au résultat
816
+     *
817
+     * @var array
818
+     */
819
+    public $param = [];
820
+
821
+    /**
822
+     * Source des filtres  (compatibilité) (?)
823
+     *
824
+     * @var array|null
825
+     */
826
+    public $fonctions = [];
827
+
828
+    /**
829
+     * Inutilisé, propriété générique de l'AST
830
+     *
831
+     * @var string|array
832
+     */
833
+    public $avant = '';
834
+
835
+    /**
836
+     * Inutilisé, propriété générique de l'AST
837
+     *
838
+     * @var string|array
839
+     */
840
+    public $apres = '';
841
+
842
+    /**
843
+     * Identifiant de la boucle
844
+     *
845
+     * @var string
846
+     */
847
+    public $id_boucle = '';
848
+
849
+    /**
850
+     * AST du squelette, liste de toutes les boucles
851
+     *
852
+     * @var Boucles[]
853
+     */
854
+    public $boucles;
855
+
856
+    /**
857
+     * Alias de table d'application de la requête ou nom complet de la table SQL
858
+     *
859
+     * @var string|null
860
+     */
861
+    public $type_requete;
862
+
863
+    /**
864
+     * Résultat de la compilation: toujours une expression PHP
865
+     *
866
+     * @var string
867
+     */
868
+    public $code = '';
869
+
870
+    /**
871
+     * Interdire les scripts
872
+     *
873
+     * @see interdire_scripts()
874
+     * @var bool
875
+     */
876
+    public $interdire_scripts = false;
877
+
878
+    /**
879
+     * Description du squelette
880
+     *
881
+     * Sert pour la gestion d'erreur et la production de code dependant du contexte
882
+     *
883
+     * Peut contenir les index :
884
+     * - nom : Nom du fichier de cache
885
+     * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser)
886
+     * - sourcefile : Chemin du squelette
887
+     * - squelette : Code du squelette
888
+     * - id_mere : Identifiant de la boucle parente
889
+     * - documents : Pour embed et img dans les textes
890
+     * - session : Pour un cache sessionné par auteur
891
+     * - niv : Niveau de tabulation
892
+     *
893
+     * @var array
894
+     */
895
+    public $descr = [];
896
+
897
+    /**
898
+     * Numéro de ligne dans le code source du squelette
899
+     *
900
+     * @var int
901
+     */
902
+    public $ligne = 0;
903 903
 }
904 904
 
905 905
 /**
@@ -908,28 +908,28 @@  discard block
 block discarded – undo
908 908
  * @package SPIP\Core\Compilateur\AST
909 909
  **/
910 910
 class Polyglotte {
911
-	/**
912
-	 * Type de noeud
913
-	 *
914
-	 * @var string
915
-	 */
916
-	public $type = 'polyglotte';
917
-
918
-	/**
919
-	 * Tableau des traductions possibles classées par langue
920
-	 *
921
-	 * Tableau code de langue => texte
922
-	 *
923
-	 * @var array
924
-	 */
925
-	public $traductions = [];
926
-
927
-	/**
928
-	 * Numéro de ligne dans le code source du squelette
929
-	 *
930
-	 * @var int
931
-	 */
932
-	public $ligne = 0;
911
+    /**
912
+     * Type de noeud
913
+     *
914
+     * @var string
915
+     */
916
+    public $type = 'polyglotte';
917
+
918
+    /**
919
+     * Tableau des traductions possibles classées par langue
920
+     *
921
+     * Tableau code de langue => texte
922
+     *
923
+     * @var array
924
+     */
925
+    public $traductions = [];
926
+
927
+    /**
928
+     * Numéro de ligne dans le code source du squelette
929
+     *
930
+     * @var int
931
+     */
932
+    public $ligne = 0;
933 933
 }
934 934
 
935 935
 
@@ -952,90 +952,90 @@  discard block
 block discarded – undo
952 952
  */
953 953
 function declarer_interfaces() {
954 954
 
955
-	$GLOBALS['table_des_tables']['articles'] = 'articles';
956
-	$GLOBALS['table_des_tables']['auteurs'] = 'auteurs';
957
-	$GLOBALS['table_des_tables']['rubriques'] = 'rubriques';
958
-	$GLOBALS['table_des_tables']['hierarchie'] = 'rubriques';
959
-
960
-	// definition des statuts de publication
961
-	$GLOBALS['table_statut'] = [];
962
-
963
-	//
964
-	// tableau des tables de jointures
965
-	// Ex: gestion du critere {id_mot} dans la boucle(ARTICLES)
966
-	$GLOBALS['tables_jointures'] = [];
967
-	$GLOBALS['tables_jointures']['spip_jobs'][] = 'jobs_liens';
968
-
969
-	// $GLOBALS['exceptions_des_jointures']['titre_mot'] = array('spip_mots', 'titre'); // pour exemple
970
-	$GLOBALS['exceptions_des_jointures']['profondeur'] = ['spip_rubriques', 'profondeur'];
971
-
972
-
973
-	if (!defined('_TRAITEMENT_TYPO')) {
974
-		define('_TRAITEMENT_TYPO', 'typo(%s, "TYPO", $connect, $Pile[0])');
975
-	}
976
-	if (!defined('_TRAITEMENT_RACCOURCIS')) {
977
-		define('_TRAITEMENT_RACCOURCIS', 'propre(%s, $connect, $Pile[0])');
978
-	}
979
-	if (!defined('_TRAITEMENT_TYPO_SANS_NUMERO')) {
980
-		define('_TRAITEMENT_TYPO_SANS_NUMERO', 'supprimer_numero(typo(%s, "TYPO", $connect, $Pile[0]))');
981
-	}
982
-	$GLOBALS['table_des_traitements']['BIO'][] = 'safehtml(' . _TRAITEMENT_RACCOURCIS . ')';
983
-	$GLOBALS['table_des_traitements']['NOM_SITE']['spip_auteurs'] = 'entites_html(%s)';
984
-	$GLOBALS['table_des_traitements']['NOM']['spip_auteurs'] = 'safehtml(' . _TRAITEMENT_TYPO_SANS_NUMERO . ')';
985
-	$GLOBALS['table_des_traitements']['CHAPO'][] = _TRAITEMENT_RACCOURCIS;
986
-	$GLOBALS['table_des_traitements']['DATE'][] = 'normaliser_date(%s)';
987
-	$GLOBALS['table_des_traitements']['DATE_REDAC'][] = 'normaliser_date(%s)';
988
-	$GLOBALS['table_des_traitements']['DATE_MODIF'][] = 'normaliser_date(%s)';
989
-	$GLOBALS['table_des_traitements']['DATE_NOUVEAUTES'][] = 'normaliser_date(%s)';
990
-	$GLOBALS['table_des_traitements']['DESCRIPTIF'][] = _TRAITEMENT_RACCOURCIS;
991
-	$GLOBALS['table_des_traitements']['INTRODUCTION'][] = _TRAITEMENT_RACCOURCIS;
992
-	$GLOBALS['table_des_traitements']['NOM_SITE_SPIP'][] = _TRAITEMENT_TYPO;
993
-	$GLOBALS['table_des_traitements']['NOM'][] = _TRAITEMENT_TYPO_SANS_NUMERO;
994
-	$GLOBALS['table_des_traitements']['AUTEUR'][] = _TRAITEMENT_TYPO;
995
-	$GLOBALS['table_des_traitements']['PS'][] = _TRAITEMENT_RACCOURCIS;
996
-	$GLOBALS['table_des_traitements']['SOURCE'][] = _TRAITEMENT_TYPO;
997
-	$GLOBALS['table_des_traitements']['SOUSTITRE'][] = _TRAITEMENT_TYPO;
998
-	$GLOBALS['table_des_traitements']['SURTITRE'][] = _TRAITEMENT_TYPO;
999
-	$GLOBALS['table_des_traitements']['TAGS'][] = '%s';
1000
-	$GLOBALS['table_des_traitements']['TEXTE'][] = _TRAITEMENT_RACCOURCIS;
1001
-	$GLOBALS['table_des_traitements']['TITRE'][] = _TRAITEMENT_TYPO_SANS_NUMERO;
1002
-	$GLOBALS['table_des_traitements']['TYPE'][] = _TRAITEMENT_TYPO;
1003
-	$GLOBALS['table_des_traitements']['DESCRIPTIF_SITE_SPIP'][] = _TRAITEMENT_RACCOURCIS;
1004
-	$GLOBALS['table_des_traitements']['SLOGAN_SITE_SPIP'][] = _TRAITEMENT_TYPO;
1005
-	$GLOBALS['table_des_traitements']['ENV'][] = 'entites_html(%s,true)';
1006
-
1007
-	// valeur par defaut pour les balises non listees ci-dessus
1008
-	$GLOBALS['table_des_traitements']['*'][] = false; // pas de traitement, mais permet au compilo de trouver la declaration suivante
1009
-	// toujours securiser les DATA
1010
-	$GLOBALS['table_des_traitements']['*']['DATA'] = 'safehtml(%s)';
1011
-	// expliciter pour VALEUR qui est un champ calcule et ne sera pas protege par le catch-all *
1012
-	$GLOBALS['table_des_traitements']['VALEUR']['DATA'] = 'safehtml(%s)';
1013
-
1014
-
1015
-	// gerer l'affectation en 2 temps car si le pipe n'est pas encore declare, on ecrase les globales
1016
-	$interfaces = pipeline(
1017
-		'declarer_tables_interfaces',
1018
-		[
1019
-			'table_des_tables' => $GLOBALS['table_des_tables'],
1020
-			'exceptions_des_tables' => $GLOBALS['exceptions_des_tables'],
1021
-			'table_date' => $GLOBALS['table_date'],
1022
-			'table_titre' => $GLOBALS['table_titre'],
1023
-			'tables_jointures' => $GLOBALS['tables_jointures'],
1024
-			'exceptions_des_jointures' => $GLOBALS['exceptions_des_jointures'],
1025
-			'table_des_traitements' => $GLOBALS['table_des_traitements'],
1026
-			'table_statut' => $GLOBALS['table_statut'],
1027
-		]
1028
-	);
1029
-	if ($interfaces) {
1030
-		$GLOBALS['table_des_tables'] = $interfaces['table_des_tables'];
1031
-		$GLOBALS['exceptions_des_tables'] = $interfaces['exceptions_des_tables'];
1032
-		$GLOBALS['table_date'] = $interfaces['table_date'];
1033
-		$GLOBALS['table_titre'] = $interfaces['table_titre'];
1034
-		$GLOBALS['tables_jointures'] = $interfaces['tables_jointures'];
1035
-		$GLOBALS['exceptions_des_jointures'] = $interfaces['exceptions_des_jointures'];
1036
-		$GLOBALS['table_des_traitements'] = $interfaces['table_des_traitements'];
1037
-		$GLOBALS['table_statut'] = $interfaces['table_statut'];
1038
-	}
955
+    $GLOBALS['table_des_tables']['articles'] = 'articles';
956
+    $GLOBALS['table_des_tables']['auteurs'] = 'auteurs';
957
+    $GLOBALS['table_des_tables']['rubriques'] = 'rubriques';
958
+    $GLOBALS['table_des_tables']['hierarchie'] = 'rubriques';
959
+
960
+    // definition des statuts de publication
961
+    $GLOBALS['table_statut'] = [];
962
+
963
+    //
964
+    // tableau des tables de jointures
965
+    // Ex: gestion du critere {id_mot} dans la boucle(ARTICLES)
966
+    $GLOBALS['tables_jointures'] = [];
967
+    $GLOBALS['tables_jointures']['spip_jobs'][] = 'jobs_liens';
968
+
969
+    // $GLOBALS['exceptions_des_jointures']['titre_mot'] = array('spip_mots', 'titre'); // pour exemple
970
+    $GLOBALS['exceptions_des_jointures']['profondeur'] = ['spip_rubriques', 'profondeur'];
971
+
972
+
973
+    if (!defined('_TRAITEMENT_TYPO')) {
974
+        define('_TRAITEMENT_TYPO', 'typo(%s, "TYPO", $connect, $Pile[0])');
975
+    }
976
+    if (!defined('_TRAITEMENT_RACCOURCIS')) {
977
+        define('_TRAITEMENT_RACCOURCIS', 'propre(%s, $connect, $Pile[0])');
978
+    }
979
+    if (!defined('_TRAITEMENT_TYPO_SANS_NUMERO')) {
980
+        define('_TRAITEMENT_TYPO_SANS_NUMERO', 'supprimer_numero(typo(%s, "TYPO", $connect, $Pile[0]))');
981
+    }
982
+    $GLOBALS['table_des_traitements']['BIO'][] = 'safehtml(' . _TRAITEMENT_RACCOURCIS . ')';
983
+    $GLOBALS['table_des_traitements']['NOM_SITE']['spip_auteurs'] = 'entites_html(%s)';
984
+    $GLOBALS['table_des_traitements']['NOM']['spip_auteurs'] = 'safehtml(' . _TRAITEMENT_TYPO_SANS_NUMERO . ')';
985
+    $GLOBALS['table_des_traitements']['CHAPO'][] = _TRAITEMENT_RACCOURCIS;
986
+    $GLOBALS['table_des_traitements']['DATE'][] = 'normaliser_date(%s)';
987
+    $GLOBALS['table_des_traitements']['DATE_REDAC'][] = 'normaliser_date(%s)';
988
+    $GLOBALS['table_des_traitements']['DATE_MODIF'][] = 'normaliser_date(%s)';
989
+    $GLOBALS['table_des_traitements']['DATE_NOUVEAUTES'][] = 'normaliser_date(%s)';
990
+    $GLOBALS['table_des_traitements']['DESCRIPTIF'][] = _TRAITEMENT_RACCOURCIS;
991
+    $GLOBALS['table_des_traitements']['INTRODUCTION'][] = _TRAITEMENT_RACCOURCIS;
992
+    $GLOBALS['table_des_traitements']['NOM_SITE_SPIP'][] = _TRAITEMENT_TYPO;
993
+    $GLOBALS['table_des_traitements']['NOM'][] = _TRAITEMENT_TYPO_SANS_NUMERO;
994
+    $GLOBALS['table_des_traitements']['AUTEUR'][] = _TRAITEMENT_TYPO;
995
+    $GLOBALS['table_des_traitements']['PS'][] = _TRAITEMENT_RACCOURCIS;
996
+    $GLOBALS['table_des_traitements']['SOURCE'][] = _TRAITEMENT_TYPO;
997
+    $GLOBALS['table_des_traitements']['SOUSTITRE'][] = _TRAITEMENT_TYPO;
998
+    $GLOBALS['table_des_traitements']['SURTITRE'][] = _TRAITEMENT_TYPO;
999
+    $GLOBALS['table_des_traitements']['TAGS'][] = '%s';
1000
+    $GLOBALS['table_des_traitements']['TEXTE'][] = _TRAITEMENT_RACCOURCIS;
1001
+    $GLOBALS['table_des_traitements']['TITRE'][] = _TRAITEMENT_TYPO_SANS_NUMERO;
1002
+    $GLOBALS['table_des_traitements']['TYPE'][] = _TRAITEMENT_TYPO;
1003
+    $GLOBALS['table_des_traitements']['DESCRIPTIF_SITE_SPIP'][] = _TRAITEMENT_RACCOURCIS;
1004
+    $GLOBALS['table_des_traitements']['SLOGAN_SITE_SPIP'][] = _TRAITEMENT_TYPO;
1005
+    $GLOBALS['table_des_traitements']['ENV'][] = 'entites_html(%s,true)';
1006
+
1007
+    // valeur par defaut pour les balises non listees ci-dessus
1008
+    $GLOBALS['table_des_traitements']['*'][] = false; // pas de traitement, mais permet au compilo de trouver la declaration suivante
1009
+    // toujours securiser les DATA
1010
+    $GLOBALS['table_des_traitements']['*']['DATA'] = 'safehtml(%s)';
1011
+    // expliciter pour VALEUR qui est un champ calcule et ne sera pas protege par le catch-all *
1012
+    $GLOBALS['table_des_traitements']['VALEUR']['DATA'] = 'safehtml(%s)';
1013
+
1014
+
1015
+    // gerer l'affectation en 2 temps car si le pipe n'est pas encore declare, on ecrase les globales
1016
+    $interfaces = pipeline(
1017
+        'declarer_tables_interfaces',
1018
+        [
1019
+            'table_des_tables' => $GLOBALS['table_des_tables'],
1020
+            'exceptions_des_tables' => $GLOBALS['exceptions_des_tables'],
1021
+            'table_date' => $GLOBALS['table_date'],
1022
+            'table_titre' => $GLOBALS['table_titre'],
1023
+            'tables_jointures' => $GLOBALS['tables_jointures'],
1024
+            'exceptions_des_jointures' => $GLOBALS['exceptions_des_jointures'],
1025
+            'table_des_traitements' => $GLOBALS['table_des_traitements'],
1026
+            'table_statut' => $GLOBALS['table_statut'],
1027
+        ]
1028
+    );
1029
+    if ($interfaces) {
1030
+        $GLOBALS['table_des_tables'] = $interfaces['table_des_tables'];
1031
+        $GLOBALS['exceptions_des_tables'] = $interfaces['exceptions_des_tables'];
1032
+        $GLOBALS['table_date'] = $interfaces['table_date'];
1033
+        $GLOBALS['table_titre'] = $interfaces['table_titre'];
1034
+        $GLOBALS['tables_jointures'] = $interfaces['tables_jointures'];
1035
+        $GLOBALS['exceptions_des_jointures'] = $interfaces['exceptions_des_jointures'];
1036
+        $GLOBALS['table_des_traitements'] = $interfaces['table_des_traitements'];
1037
+        $GLOBALS['table_statut'] = $interfaces['table_statut'];
1038
+    }
1039 1039
 }
1040 1040
 
1041 1041
 declarer_interfaces();
Please login to merge, or discard this patch.
ecrire/inc/securiser_action.php 1 patch
Indentation   +188 added lines, -188 removed lines patch added patch discarded remove patch
@@ -16,10 +16,10 @@  discard block
 block discarded – undo
16 16
  * @package SPIP\Core\Actions
17 17
  **/
18 18
 
19
- use Spip\Chiffrer\SpipCles;
19
+    use Spip\Chiffrer\SpipCles;
20 20
 
21 21
 if (!defined('_ECRIRE_INC_VERSION')) {
22
-	return;
22
+    return;
23 23
 }
24 24
 
25 25
 /**
@@ -52,19 +52,19 @@  discard block
 block discarded – undo
52 52
  * @return array|string
53 53
  */
54 54
 function inc_securiser_action_dist($action = '', $arg = '', $redirect = '', $mode = false, $att = '', $public = false) {
55
-	if ($action) {
56
-		return securiser_action_auteur($action, $arg, $redirect, $mode, $att, $public);
57
-	} else {
58
-		$arg = _request('arg');
59
-		$hash = _request('hash');
60
-		$action = _request('action') ?: _request('formulaire_action');
61
-		if ($a = verifier_action_auteur("$action-$arg", $hash)) {
62
-			return $arg;
63
-		}
64
-		include_spip('inc/minipres');
65
-		echo minipres();
66
-		exit;
67
-	}
55
+    if ($action) {
56
+        return securiser_action_auteur($action, $arg, $redirect, $mode, $att, $public);
57
+    } else {
58
+        $arg = _request('arg');
59
+        $hash = _request('hash');
60
+        $action = _request('action') ?: _request('formulaire_action');
61
+        if ($a = verifier_action_auteur("$action-$arg", $hash)) {
62
+            return $arg;
63
+        }
64
+        include_spip('inc/minipres');
65
+        echo minipres();
66
+        exit;
67
+    }
68 68
 }
69 69
 
70 70
 /**
@@ -83,29 +83,29 @@  discard block
 block discarded – undo
83 83
  */
84 84
 function demander_confirmation_avant_action($titre, $titre_bouton, $url_action = null) {
85 85
 
86
-	if (!$url_action) {
87
-		$url_action = self();
88
-		$action = _request('action');
89
-		$url_action = parametre_url($url_action, 'action', $action, '&');
90
-	}
91
-	else {
92
-		$action = parametre_url($url_action, 'action');
93
-	}
94
-
95
-	$arg = parametre_url($url_action, 'arg');
96
-	$confirm = md5("$action:$arg:" . realpath(__FILE__));
97
-	if (_request('confirm_action') === $confirm) {
98
-		return true;
99
-	}
100
-
101
-	$url_confirm = parametre_url($url_action, 'confirm_action', $confirm, '&');
102
-	include_spip('inc/filtres');
103
-	$bouton_action = bouton_action($titre_bouton, $url_confirm);
104
-	$corps = "<div style='text-align:center;'>$bouton_action</div>";
105
-
106
-	include_spip('inc/minipres');
107
-	echo minipres($titre, $corps);
108
-	exit;
86
+    if (!$url_action) {
87
+        $url_action = self();
88
+        $action = _request('action');
89
+        $url_action = parametre_url($url_action, 'action', $action, '&');
90
+    }
91
+    else {
92
+        $action = parametre_url($url_action, 'action');
93
+    }
94
+
95
+    $arg = parametre_url($url_action, 'arg');
96
+    $confirm = md5("$action:$arg:" . realpath(__FILE__));
97
+    if (_request('confirm_action') === $confirm) {
98
+        return true;
99
+    }
100
+
101
+    $url_confirm = parametre_url($url_action, 'confirm_action', $confirm, '&');
102
+    include_spip('inc/filtres');
103
+    $bouton_action = bouton_action($titre_bouton, $url_confirm);
104
+    $corps = "<div style='text-align:center;'>$bouton_action</div>";
105
+
106
+    include_spip('inc/minipres');
107
+    echo minipres($titre, $corps);
108
+    exit;
109 109
 }
110 110
 
111 111
 /**
@@ -136,34 +136,34 @@  discard block
 block discarded – undo
136 136
  */
137 137
 function securiser_action_auteur($action, $arg, $redirect = '', $mode = false, $att = '', $public = false) {
138 138
 
139
-	// mode URL ou array
140
-	if (!is_string($mode)) {
141
-		$hash = calculer_action_auteur("$action-$arg", is_numeric($att) ? $att : null);
142
-
143
-		$r = rawurlencode($redirect);
144
-		if ($mode === -1) {
145
-			return ['action' => $action, 'arg' => $arg, 'hash' => $hash];
146
-		} else {
147
-			return generer_url_action(
148
-				$action,
149
-				'arg=' . rawurlencode($arg) . "&hash=$hash" . (!$r ? '' : "&redirect=$r"),
150
-				$mode,
151
-				$public
152
-			);
153
-		}
154
-	}
155
-
156
-	// mode formulaire
157
-	$hash = calculer_action_auteur("$action-$arg");
158
-	$att .= " style='margin: 0px; border: 0px'";
159
-	if ($redirect) {
160
-		$redirect = "\n\t\t<input name='redirect' type='hidden' value='" . str_replace("'", '&#39;', $redirect) . "' />";
161
-	}
162
-	$mode .= $redirect . "
139
+    // mode URL ou array
140
+    if (!is_string($mode)) {
141
+        $hash = calculer_action_auteur("$action-$arg", is_numeric($att) ? $att : null);
142
+
143
+        $r = rawurlencode($redirect);
144
+        if ($mode === -1) {
145
+            return ['action' => $action, 'arg' => $arg, 'hash' => $hash];
146
+        } else {
147
+            return generer_url_action(
148
+                $action,
149
+                'arg=' . rawurlencode($arg) . "&hash=$hash" . (!$r ? '' : "&redirect=$r"),
150
+                $mode,
151
+                $public
152
+            );
153
+        }
154
+    }
155
+
156
+    // mode formulaire
157
+    $hash = calculer_action_auteur("$action-$arg");
158
+    $att .= " style='margin: 0px; border: 0px'";
159
+    if ($redirect) {
160
+        $redirect = "\n\t\t<input name='redirect' type='hidden' value='" . str_replace("'", '&#39;', $redirect) . "' />";
161
+    }
162
+    $mode .= $redirect . "
163 163
 <input name='hash' type='hidden' value='$hash' />
164 164
 <input name='arg' type='hidden' value='$arg' />";
165 165
 
166
-	return generer_form_action($action, $mode, $att, $public);
166
+    return generer_form_action($action, $mode, $att, $public);
167 167
 }
168 168
 
169 169
 /**
@@ -173,48 +173,48 @@  discard block
 block discarded – undo
173 173
  * @return array
174 174
  */
175 175
 function caracteriser_auteur($id_auteur = null) {
176
-	static $caracterisation = [];
177
-
178
-	if (is_null($id_auteur) and !isset($GLOBALS['visiteur_session']['id_auteur'])) {
179
-		// si l'auteur courant n'est pas connu alors qu'il peut demander une action
180
-		// c'est une connexion par php_auth ou 1 instal, on se rabat sur le cookie.
181
-		// S'il n'avait pas le droit de realiser cette action, le hash sera faux.
182
-		if (
183
-			isset($_COOKIE['spip_session'])
184
-			and (preg_match('/^(\d+)/', $_COOKIE['spip_session'], $r))
185
-		) {
186
-			return [$r[1], ''];
187
-			// Necessaire aux forums anonymes.
188
-			// Pour le reste, ca echouera.
189
-		} else {
190
-			return ['0', ''];
191
-		}
192
-	}
193
-	// Eviter l'acces SQL si le pass est connu de PHP
194
-	if (is_null($id_auteur)) {
195
-		$id_auteur = $GLOBALS['visiteur_session']['id_auteur'] ?? 0;
196
-		if (isset($GLOBALS['visiteur_session']['pass']) and $GLOBALS['visiteur_session']['pass']) {
197
-			return $caracterisation[$id_auteur] = [$id_auteur, $GLOBALS['visiteur_session']['pass']];
198
-		}
199
-	}
200
-
201
-	if (isset($caracterisation[$id_auteur])) {
202
-		return $caracterisation[$id_auteur];
203
-	}
204
-
205
-	if ($id_auteur) {
206
-		include_spip('base/abstract_sql');
207
-		$t = sql_fetsel('id_auteur, pass', 'spip_auteurs', "id_auteur=$id_auteur");
208
-		if ($t) {
209
-			return $caracterisation[$id_auteur] = [$t['id_auteur'], $t['pass']];
210
-		}
211
-		include_spip('inc/minipres');
212
-		echo minipres();
213
-		exit;
214
-	} // Visiteur anonyme, pour ls forums par exemple
215
-	else {
216
-		return ['0', ''];
217
-	}
176
+    static $caracterisation = [];
177
+
178
+    if (is_null($id_auteur) and !isset($GLOBALS['visiteur_session']['id_auteur'])) {
179
+        // si l'auteur courant n'est pas connu alors qu'il peut demander une action
180
+        // c'est une connexion par php_auth ou 1 instal, on se rabat sur le cookie.
181
+        // S'il n'avait pas le droit de realiser cette action, le hash sera faux.
182
+        if (
183
+            isset($_COOKIE['spip_session'])
184
+            and (preg_match('/^(\d+)/', $_COOKIE['spip_session'], $r))
185
+        ) {
186
+            return [$r[1], ''];
187
+            // Necessaire aux forums anonymes.
188
+            // Pour le reste, ca echouera.
189
+        } else {
190
+            return ['0', ''];
191
+        }
192
+    }
193
+    // Eviter l'acces SQL si le pass est connu de PHP
194
+    if (is_null($id_auteur)) {
195
+        $id_auteur = $GLOBALS['visiteur_session']['id_auteur'] ?? 0;
196
+        if (isset($GLOBALS['visiteur_session']['pass']) and $GLOBALS['visiteur_session']['pass']) {
197
+            return $caracterisation[$id_auteur] = [$id_auteur, $GLOBALS['visiteur_session']['pass']];
198
+        }
199
+    }
200
+
201
+    if (isset($caracterisation[$id_auteur])) {
202
+        return $caracterisation[$id_auteur];
203
+    }
204
+
205
+    if ($id_auteur) {
206
+        include_spip('base/abstract_sql');
207
+        $t = sql_fetsel('id_auteur, pass', 'spip_auteurs', "id_auteur=$id_auteur");
208
+        if ($t) {
209
+            return $caracterisation[$id_auteur] = [$t['id_auteur'], $t['pass']];
210
+        }
211
+        include_spip('inc/minipres');
212
+        echo minipres();
213
+        exit;
214
+    } // Visiteur anonyme, pour ls forums par exemple
215
+    else {
216
+        return ['0', ''];
217
+    }
218 218
 }
219 219
 
220 220
 /**
@@ -229,30 +229,30 @@  discard block
 block discarded – undo
229 229
  * @return string
230 230
  */
231 231
 function _action_auteur(string $action, int $id_auteur, ?string $pass, string $alea): string {
232
-	static $sha = [];
233
-	$pass = $pass ?? '';
234
-	$entry = "$action:$id_auteur:$pass:$alea";
235
-	if (!isset($sha[$entry])) {
236
-		$sha[$entry] = hash_hmac('sha256', "$action::$id_auteur", "$pass::" . _action_get_alea($alea));
237
-	}
238
-
239
-	return $sha[$entry];
232
+    static $sha = [];
233
+    $pass = $pass ?? '';
234
+    $entry = "$action:$id_auteur:$pass:$alea";
235
+    if (!isset($sha[$entry])) {
236
+        $sha[$entry] = hash_hmac('sha256', "$action::$id_auteur", "$pass::" . _action_get_alea($alea));
237
+    }
238
+
239
+    return $sha[$entry];
240 240
 }
241 241
 
242 242
 function _action_get_alea(string $alea): string {
243
-	if (!isset($GLOBALS['meta'][$alea])) {
244
-		if (!$exec = _request('exec') or !autoriser_sans_cookie($exec)) {
245
-			include_spip('inc/acces');
246
-			charger_aleas();
247
-			if (empty($GLOBALS['meta'][$alea])) {
248
-				include_spip('inc/minipres');
249
-				echo minipres();
250
-				spip_log("$alea indisponible");
251
-				exit;
252
-			}
253
-		}
254
-	}
255
-	return $GLOBALS['meta'][$alea] ?? '';
243
+    if (!isset($GLOBALS['meta'][$alea])) {
244
+        if (!$exec = _request('exec') or !autoriser_sans_cookie($exec)) {
245
+            include_spip('inc/acces');
246
+            charger_aleas();
247
+            if (empty($GLOBALS['meta'][$alea])) {
248
+                include_spip('inc/minipres');
249
+                echo minipres();
250
+                spip_log("$alea indisponible");
251
+                exit;
252
+            }
253
+        }
254
+    }
255
+    return $GLOBALS['meta'][$alea] ?? '';
256 256
 }
257 257
 
258 258
 /**
@@ -263,9 +263,9 @@  discard block
 block discarded – undo
263 263
  * @return string
264 264
  */
265 265
 function calculer_action_auteur($action, $id_auteur = null) {
266
-	[$id_auteur, $pass] = caracteriser_auteur($id_auteur);
266
+    [$id_auteur, $pass] = caracteriser_auteur($id_auteur);
267 267
 
268
-	return _action_auteur($action, $id_auteur, $pass, 'alea_ephemere');
268
+    return _action_auteur($action, $id_auteur, $pass, 'alea_ephemere');
269 269
 }
270 270
 
271 271
 
@@ -278,15 +278,15 @@  discard block
 block discarded – undo
278 278
  * @return bool
279 279
  */
280 280
 function verifier_action_auteur($action, $hash) {
281
-	[$id_auteur, $pass] = caracteriser_auteur();
282
-	if (
283
-		hash_equals($hash, _action_auteur($action, $id_auteur, $pass, 'alea_ephemere'))
284
-		or hash_equals($hash, _action_auteur($action, $id_auteur, $pass, 'alea_ephemere_ancien'))
285
-	) {
286
-		return true;
287
-	}
288
-
289
-	return false;
281
+    [$id_auteur, $pass] = caracteriser_auteur();
282
+    if (
283
+        hash_equals($hash, _action_auteur($action, $id_auteur, $pass, 'alea_ephemere'))
284
+        or hash_equals($hash, _action_auteur($action, $id_auteur, $pass, 'alea_ephemere_ancien'))
285
+    ) {
286
+        return true;
287
+    }
288
+
289
+    return false;
290 290
 }
291 291
 
292 292
 //
@@ -301,8 +301,8 @@  discard block
 block discarded – undo
301 301
  * @return string
302 302
  */
303 303
 function secret_du_site() {
304
-	include_spip('inc/chiffrer');
305
-	return SpipCles::secret_du_site();
304
+    include_spip('inc/chiffrer');
305
+    return SpipCles::secret_du_site();
306 306
 }
307 307
 
308 308
 /**
@@ -312,7 +312,7 @@  discard block
 block discarded – undo
312 312
  * @return string
313 313
  */
314 314
 function calculer_cle_action($action) {
315
-	return hash_hmac('sha256', $action, secret_du_site());
315
+    return hash_hmac('sha256', $action, secret_du_site());
316 316
 }
317 317
 
318 318
 /**
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
  * @return bool
324 324
  */
325 325
 function verifier_cle_action($action, $cle) {
326
-	return hash_equals($cle, calculer_cle_action($action));
326
+    return hash_equals($cle, calculer_cle_action($action));
327 327
 }
328 328
 
329 329
 
@@ -340,19 +340,19 @@  discard block
 block discarded – undo
340 340
  * @return string Token, de la forme "{id}*{hash}"
341 341
  */
342 342
 function calculer_token_previsu($url, $id_auteur = null, $alea = 'alea_ephemere') {
343
-	if (is_null($id_auteur)) {
344
-		if (!empty($GLOBALS['visiteur_session']['id_auteur'])) {
345
-			$id_auteur = $GLOBALS['visiteur_session']['id_auteur'];
346
-		}
347
-	}
348
-	if (!$id_auteur = intval($id_auteur)) {
349
-		return '';
350
-	}
351
-	// On nettoie l’URL de tous les var_.
352
-	$url = nettoyer_uri_var($url);
353
-
354
-	$token = _action_auteur('previsualiser-' . $url, $id_auteur, secret_du_site(), $alea);
355
-	return "$id_auteur-$token";
343
+    if (is_null($id_auteur)) {
344
+        if (!empty($GLOBALS['visiteur_session']['id_auteur'])) {
345
+            $id_auteur = $GLOBALS['visiteur_session']['id_auteur'];
346
+        }
347
+    }
348
+    if (!$id_auteur = intval($id_auteur)) {
349
+        return '';
350
+    }
351
+    // On nettoie l’URL de tous les var_.
352
+    $url = nettoyer_uri_var($url);
353
+
354
+    $token = _action_auteur('previsualiser-' . $url, $id_auteur, secret_du_site(), $alea);
355
+    return "$id_auteur-$token";
356 356
 }
357 357
 
358 358
 
@@ -370,31 +370,31 @@  discard block
 block discarded – undo
370 370
  *     + Tableau (id auteur, type d’objet, id_objet) sinon.
371 371
  */
372 372
 function verifier_token_previsu($token) {
373
-	// retrouver auteur / hash
374
-	$e = explode('-', $token, 2);
375
-	if (count($e) == 2 and is_numeric(reset($e))) {
376
-		$id_auteur = intval(reset($e));
377
-	} else {
378
-		return false;
379
-	}
380
-
381
-	// calculer le type et id de l’url actuelle
382
-	include_spip('inc/urls');
383
-	include_spip('inc/filtres_mini');
384
-	$url = url_absolue(self());
385
-
386
-	// verifier le token
387
-	$_token = calculer_token_previsu($url, $id_auteur, 'alea_ephemere');
388
-	if (!$_token or !hash_equals($token, $_token)) {
389
-		$_token = calculer_token_previsu($url, $id_auteur, 'alea_ephemere_ancien');
390
-		if (!$_token or !hash_equals($token, $_token)) {
391
-			return false;
392
-		}
393
-	}
394
-
395
-	return [
396
-		'id_auteur' => $id_auteur,
397
-	];
373
+    // retrouver auteur / hash
374
+    $e = explode('-', $token, 2);
375
+    if (count($e) == 2 and is_numeric(reset($e))) {
376
+        $id_auteur = intval(reset($e));
377
+    } else {
378
+        return false;
379
+    }
380
+
381
+    // calculer le type et id de l’url actuelle
382
+    include_spip('inc/urls');
383
+    include_spip('inc/filtres_mini');
384
+    $url = url_absolue(self());
385
+
386
+    // verifier le token
387
+    $_token = calculer_token_previsu($url, $id_auteur, 'alea_ephemere');
388
+    if (!$_token or !hash_equals($token, $_token)) {
389
+        $_token = calculer_token_previsu($url, $id_auteur, 'alea_ephemere_ancien');
390
+        if (!$_token or !hash_equals($token, $_token)) {
391
+            return false;
392
+        }
393
+    }
394
+
395
+    return [
396
+        'id_auteur' => $id_auteur,
397
+    ];
398 398
 }
399 399
 
400 400
 /**
@@ -403,13 +403,13 @@  discard block
 block discarded – undo
403 403
  * @return bool|array
404 404
  */
405 405
 function decrire_token_previsu() {
406
-	static $desc = null;
407
-	if (is_null($desc)) {
408
-		if ($token = _request('var_previewtoken')) {
409
-			$desc = verifier_token_previsu($token);
410
-		} else {
411
-			$desc = false;
412
-		}
413
-	}
414
-	return $desc;
406
+    static $desc = null;
407
+    if (is_null($desc)) {
408
+        if ($token = _request('var_previewtoken')) {
409
+            $desc = verifier_token_previsu($token);
410
+        } else {
411
+            $desc = false;
412
+        }
413
+    }
414
+    return $desc;
415 415
 }
Please login to merge, or discard this patch.
ecrire/inc/utils.php 1 patch
Indentation   +2258 added lines, -2259 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  **/
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 
@@ -48,71 +48,71 @@  discard block
 block discarded – undo
48 48
  *     Nom de la fonction, ou false.
49 49
  */
50 50
 function charger_fonction($nom, $dossier = 'exec', $continue = false) {
51
-	static $echecs = [];
52
-
53
-	if (strlen($dossier) and substr($dossier, -1) != '/') {
54
-		$dossier .= '/';
55
-	}
56
-	$f = str_replace('/', '_', $dossier) . $nom;
57
-
58
-	if (function_exists($f)) {
59
-		return $f;
60
-	}
61
-	if (function_exists($g = $f . '_dist')) {
62
-		return $g;
63
-	}
64
-
65
-	if (isset($echecs[$f])) {
66
-		return $echecs[$f];
67
-	}
68
-	// Sinon charger le fichier de declaration si plausible
69
-
70
-	if (!preg_match(',^\w+$,', $f)) {
71
-		if ($continue) {
72
-			return false;
73
-		} //appel interne, on passe
74
-		include_spip('inc/minipres');
75
-		echo minipres();
76
-		exit;
77
-	}
78
-
79
-	// passer en minuscules (cf les balises de formulaires)
80
-	// et inclure le fichier
81
-	if (
82
-		!$inc = include_spip($dossier . ($d = strtolower($nom)))
83
-		// si le fichier truc/machin/nom.php n'existe pas,
84
-		// la fonction peut etre definie dans truc/machin.php qui regroupe plusieurs petites fonctions
85
-		and strlen(dirname($dossier)) and dirname($dossier) != '.'
86
-	) {
87
-		include_spip(substr($dossier, 0, -1));
88
-	}
89
-	if (function_exists($f)) {
90
-		return $f;
91
-	}
92
-	if (function_exists($g)) {
93
-		return $g;
94
-	}
95
-
96
-	if ($continue) {
97
-		return $echecs[$f] = false;
98
-	}
99
-
100
-	// Echec : message d'erreur
101
-	spip_log("fonction $nom ($f ou $g) indisponible" .
102
-		($inc ? '' : " (fichier $d absent de $dossier)"));
103
-
104
-	include_spip('inc/minipres');
105
-	echo minipres(
106
-		_T('forum_titre_erreur'),
107
-		$inc ?
108
-			_T('fonction_introuvable', ['fonction' => '<code>' . spip_htmlentities($f) . '</code>'])
109
-			. '<br />'
110
-			. _T('fonction_introuvable', ['fonction' => '<code>' . spip_htmlentities($g) . '</code>'])
111
-			:
112
-			_T('fichier_introuvable', ['fichier' => '<code>' . spip_htmlentities($d) . '</code>']),
113
-		['all_inline' => true,'status' => 404]
114
-	);
115
-	exit;
51
+    static $echecs = [];
52
+
53
+    if (strlen($dossier) and substr($dossier, -1) != '/') {
54
+        $dossier .= '/';
55
+    }
56
+    $f = str_replace('/', '_', $dossier) . $nom;
57
+
58
+    if (function_exists($f)) {
59
+        return $f;
60
+    }
61
+    if (function_exists($g = $f . '_dist')) {
62
+        return $g;
63
+    }
64
+
65
+    if (isset($echecs[$f])) {
66
+        return $echecs[$f];
67
+    }
68
+    // Sinon charger le fichier de declaration si plausible
69
+
70
+    if (!preg_match(',^\w+$,', $f)) {
71
+        if ($continue) {
72
+            return false;
73
+        } //appel interne, on passe
74
+        include_spip('inc/minipres');
75
+        echo minipres();
76
+        exit;
77
+    }
78
+
79
+    // passer en minuscules (cf les balises de formulaires)
80
+    // et inclure le fichier
81
+    if (
82
+        !$inc = include_spip($dossier . ($d = strtolower($nom)))
83
+        // si le fichier truc/machin/nom.php n'existe pas,
84
+        // la fonction peut etre definie dans truc/machin.php qui regroupe plusieurs petites fonctions
85
+        and strlen(dirname($dossier)) and dirname($dossier) != '.'
86
+    ) {
87
+        include_spip(substr($dossier, 0, -1));
88
+    }
89
+    if (function_exists($f)) {
90
+        return $f;
91
+    }
92
+    if (function_exists($g)) {
93
+        return $g;
94
+    }
95
+
96
+    if ($continue) {
97
+        return $echecs[$f] = false;
98
+    }
99
+
100
+    // Echec : message d'erreur
101
+    spip_log("fonction $nom ($f ou $g) indisponible" .
102
+        ($inc ? '' : " (fichier $d absent de $dossier)"));
103
+
104
+    include_spip('inc/minipres');
105
+    echo minipres(
106
+        _T('forum_titre_erreur'),
107
+        $inc ?
108
+            _T('fonction_introuvable', ['fonction' => '<code>' . spip_htmlentities($f) . '</code>'])
109
+            . '<br />'
110
+            . _T('fonction_introuvable', ['fonction' => '<code>' . spip_htmlentities($g) . '</code>'])
111
+            :
112
+            _T('fichier_introuvable', ['fichier' => '<code>' . spip_htmlentities($d) . '</code>']),
113
+        ['all_inline' => true,'status' => 404]
114
+    );
115
+    exit;
116 116
 }
117 117
 
118 118
 /**
@@ -122,17 +122,17 @@  discard block
 block discarded – undo
122 122
  * @return bool
123 123
  */
124 124
 function include_once_check($file) {
125
-	if (file_exists($file)) {
126
-		include_once $file;
125
+    if (file_exists($file)) {
126
+        include_once $file;
127 127
 
128
-		return true;
129
-	}
130
-	$crash = (isset($GLOBALS['meta']['message_crash_plugins']) ? unserialize($GLOBALS['meta']['message_crash_plugins']) : '');
131
-	$crash = ($crash ?: []);
132
-	$crash[$file] = true;
133
-	ecrire_meta('message_crash_plugins', serialize($crash));
128
+        return true;
129
+    }
130
+    $crash = (isset($GLOBALS['meta']['message_crash_plugins']) ? unserialize($GLOBALS['meta']['message_crash_plugins']) : '');
131
+    $crash = ($crash ?: []);
132
+    $crash[$file] = true;
133
+    ecrire_meta('message_crash_plugins', serialize($crash));
134 134
 
135
-	return false;
135
+    return false;
136 136
 }
137 137
 
138 138
 
@@ -156,7 +156,7 @@  discard block
 block discarded – undo
156 156
  *     - string : chemin du fichier trouvé
157 157
  **/
158 158
 function include_spip($f, $include = true) {
159
-	return find_in_path($f . '.php', '', $include);
159
+    return find_in_path($f . '.php', '', $include);
160 160
 }
161 161
 
162 162
 /**
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
  *     - string : chemin du fichier trouvé
177 177
  **/
178 178
 function require_spip($f) {
179
-	return find_in_path($f . '.php', '', 'required');
179
+    return find_in_path($f . '.php', '', 'required');
180 180
 }
181 181
 
182 182
 
@@ -185,27 +185,27 @@  discard block
 block discarded – undo
185 185
  * quand on a besoin dans le PHP de filtres/fonctions qui y sont definis
186 186
  */
187 187
 function include_fichiers_fonctions() {
188
-	static $done = false;
189
-	if (!$done) {
190
-		include_spip('inc/lang');
191
-
192
-		// NB: mes_fonctions peut initialiser $dossier_squelettes (old-style)
193
-		// donc il faut l'inclure "en globals"
194
-		if ($f = find_in_path('mes_fonctions.php')) {
195
-			global $dossier_squelettes;
196
-			include_once(_ROOT_CWD . $f);
197
-		}
198
-
199
-		if (@is_readable(_CACHE_PLUGINS_FCT)) {
200
-			// chargement optimise precompile
201
-			include_once(_CACHE_PLUGINS_FCT);
202
-		}
203
-		if (test_espace_prive()) {
204
-			include_spip('inc/filtres_ecrire');
205
-		}
206
-		include_spip('public/fonctions'); // charger les fichiers fonctions associes aux criteres, balises..
207
-		$done = true;
208
-	}
188
+    static $done = false;
189
+    if (!$done) {
190
+        include_spip('inc/lang');
191
+
192
+        // NB: mes_fonctions peut initialiser $dossier_squelettes (old-style)
193
+        // donc il faut l'inclure "en globals"
194
+        if ($f = find_in_path('mes_fonctions.php')) {
195
+            global $dossier_squelettes;
196
+            include_once(_ROOT_CWD . $f);
197
+        }
198
+
199
+        if (@is_readable(_CACHE_PLUGINS_FCT)) {
200
+            // chargement optimise precompile
201
+            include_once(_CACHE_PLUGINS_FCT);
202
+        }
203
+        if (test_espace_prive()) {
204
+            include_spip('inc/filtres_ecrire');
205
+        }
206
+        include_spip('public/fonctions'); // charger les fichiers fonctions associes aux criteres, balises..
207
+        $done = true;
208
+    }
209 209
 }
210 210
 
211 211
 /**
@@ -231,23 +231,23 @@  discard block
 block discarded – undo
231 231
  *     Les paramètres du pipeline modifiés
232 232
  **/
233 233
 function minipipe($fonc, &$val) {
234
-	// fonction
235
-	if (function_exists($fonc)) {
236
-		$val = $fonc($val);
237
-	} // Class::Methode
238
-	else {
239
-		if (
240
-			preg_match('/^(\w*)::(\w*)$/S', $fonc, $regs)
241
-			and $methode = [$regs[1], $regs[2]]
242
-			and is_callable($methode)
243
-		) {
244
-			$val = $methode($val);
245
-		} else {
246
-			spip_log("Erreur - '$fonc' non definie !");
247
-		}
248
-	}
249
-
250
-	return $val;
234
+    // fonction
235
+    if (function_exists($fonc)) {
236
+        $val = $fonc($val);
237
+    } // Class::Methode
238
+    else {
239
+        if (
240
+            preg_match('/^(\w*)::(\w*)$/S', $fonc, $regs)
241
+            and $methode = [$regs[1], $regs[2]]
242
+            and is_callable($methode)
243
+        ) {
244
+            $val = $methode($val);
245
+        } else {
246
+            spip_log("Erreur - '$fonc' non definie !");
247
+        }
248
+    }
249
+
250
+    return $val;
251 251
 }
252 252
 
253 253
 /**
@@ -278,46 +278,46 @@  discard block
 block discarded – undo
278 278
  *     Résultat
279 279
  */
280 280
 function pipeline($action, $val = null) {
281
-	static $charger;
282
-
283
-	// chargement initial des fonctions mises en cache, ou generation du cache
284
-	if (!$charger) {
285
-		if (!($ok = @is_readable($charger = _CACHE_PIPELINES))) {
286
-			include_spip('inc/plugin');
287
-			// generer les fichiers php precompiles
288
-			// de chargement des plugins et des pipelines
289
-			actualise_plugins_actifs();
290
-			if (!($ok = @is_readable($charger))) {
291
-				spip_log("fichier $charger pas cree");
292
-			}
293
-		}
294
-
295
-		if ($ok) {
296
-			include_once $charger;
297
-		}
298
-	}
299
-
300
-	// appliquer notre fonction si elle existe
301
-	$fonc = 'execute_pipeline_' . strtolower($action);
302
-	if (function_exists($fonc)) {
303
-		$val = $fonc($val);
304
-	} // plantage ?
305
-	else {
306
-		spip_log("fonction $fonc absente : pipeline desactive", _LOG_ERREUR);
307
-	}
308
-
309
-	// si le flux est une table avec 2 cle args&data
310
-	// on ne ressort du pipe que les donnees dans 'data'
311
-	// array_key_exists pour php 4.1.0
312
-	if (
313
-		is_array($val)
314
-		and count($val) == 2
315
-		and (array_key_exists('data', $val))
316
-	) {
317
-		$val = $val['data'];
318
-	}
319
-
320
-	return $val;
281
+    static $charger;
282
+
283
+    // chargement initial des fonctions mises en cache, ou generation du cache
284
+    if (!$charger) {
285
+        if (!($ok = @is_readable($charger = _CACHE_PIPELINES))) {
286
+            include_spip('inc/plugin');
287
+            // generer les fichiers php precompiles
288
+            // de chargement des plugins et des pipelines
289
+            actualise_plugins_actifs();
290
+            if (!($ok = @is_readable($charger))) {
291
+                spip_log("fichier $charger pas cree");
292
+            }
293
+        }
294
+
295
+        if ($ok) {
296
+            include_once $charger;
297
+        }
298
+    }
299
+
300
+    // appliquer notre fonction si elle existe
301
+    $fonc = 'execute_pipeline_' . strtolower($action);
302
+    if (function_exists($fonc)) {
303
+        $val = $fonc($val);
304
+    } // plantage ?
305
+    else {
306
+        spip_log("fonction $fonc absente : pipeline desactive", _LOG_ERREUR);
307
+    }
308
+
309
+    // si le flux est une table avec 2 cle args&data
310
+    // on ne ressort du pipe que les donnees dans 'data'
311
+    // array_key_exists pour php 4.1.0
312
+    if (
313
+        is_array($val)
314
+        and count($val) == 2
315
+        and (array_key_exists('data', $val))
316
+    ) {
317
+        $val = $val['data'];
318
+    }
319
+
320
+    return $val;
321 321
 }
322 322
 
323 323
 /**
@@ -361,38 +361,38 @@  discard block
 block discarded – undo
361 361
  *     paramètre est planté pour cause de compatibilité ascendante.
362 362
  */
363 363
 function spip_log($message = null, $name = null) {
364
-	static $pre = [];
365
-	static $log;
366
-	preg_match('/^([a-z_]*)\.?(\d)?$/iS', (string)$name, $regs);
367
-	if (!isset($regs[1]) or !$logname = $regs[1]) {
368
-		$logname = null;
369
-	}
370
-	if (!isset($regs[2])) {
371
-		$niveau = _LOG_INFO;
372
-	}
373
-	else {
374
-		$niveau = intval($regs[2]);
375
-	}
376
-
377
-	if ($niveau <= (defined('_LOG_FILTRE_GRAVITE') ? _LOG_FILTRE_GRAVITE : _LOG_INFO_IMPORTANTE)) {
378
-		if (!$pre) {
379
-			$pre = [
380
-				_LOG_HS => 'HS:',
381
-				_LOG_ALERTE_ROUGE => 'ALERTE:',
382
-				_LOG_CRITIQUE => 'CRITIQUE:',
383
-				_LOG_ERREUR => 'ERREUR:',
384
-				_LOG_AVERTISSEMENT => 'WARNING:',
385
-				_LOG_INFO_IMPORTANTE => '!INFO:',
386
-				_LOG_INFO => 'info:',
387
-				_LOG_DEBUG => 'debug:'
388
-			];
389
-			$log = charger_fonction('log', 'inc');
390
-		}
391
-		if (!is_string($message)) {
392
-			$message = print_r($message, true);
393
-		}
394
-		$log($pre[$niveau] . ' ' . $message, $logname);
395
-	}
364
+    static $pre = [];
365
+    static $log;
366
+    preg_match('/^([a-z_]*)\.?(\d)?$/iS', (string)$name, $regs);
367
+    if (!isset($regs[1]) or !$logname = $regs[1]) {
368
+        $logname = null;
369
+    }
370
+    if (!isset($regs[2])) {
371
+        $niveau = _LOG_INFO;
372
+    }
373
+    else {
374
+        $niveau = intval($regs[2]);
375
+    }
376
+
377
+    if ($niveau <= (defined('_LOG_FILTRE_GRAVITE') ? _LOG_FILTRE_GRAVITE : _LOG_INFO_IMPORTANTE)) {
378
+        if (!$pre) {
379
+            $pre = [
380
+                _LOG_HS => 'HS:',
381
+                _LOG_ALERTE_ROUGE => 'ALERTE:',
382
+                _LOG_CRITIQUE => 'CRITIQUE:',
383
+                _LOG_ERREUR => 'ERREUR:',
384
+                _LOG_AVERTISSEMENT => 'WARNING:',
385
+                _LOG_INFO_IMPORTANTE => '!INFO:',
386
+                _LOG_INFO => 'info:',
387
+                _LOG_DEBUG => 'debug:'
388
+            ];
389
+            $log = charger_fonction('log', 'inc');
390
+        }
391
+        if (!is_string($message)) {
392
+            $message = print_r($message, true);
393
+        }
394
+        $log($pre[$niveau] . ' ' . $message, $logname);
395
+    }
396 396
 }
397 397
 
398 398
 /**
@@ -403,8 +403,8 @@  discard block
 block discarded – undo
403 403
  * @param array $opt Tableau d'options
404 404
  **/
405 405
 function journal($phrase, $opt = []) {
406
-	$journal = charger_fonction('journal', 'inc');
407
-	$journal($phrase, $opt);
406
+    $journal = charger_fonction('journal', 'inc');
407
+    $journal($phrase, $opt);
408 408
 }
409 409
 
410 410
 
@@ -423,37 +423,37 @@  discard block
 block discarded – undo
423 423
  **/
424 424
 function _request($var, $c = false) {
425 425
 
426
-	if (is_array($c)) {
427
-		return $c[$var] ?? null;
428
-	}
429
-
430
-	if (isset($_GET[$var])) {
431
-		$a = $_GET[$var];
432
-	} elseif (isset($_POST[$var])) {
433
-		$a = $_POST[$var];
434
-	} else {
435
-		return null;
436
-	}
437
-
438
-	// Si on est en ajax et en POST tout a ete encode
439
-	// via encodeURIComponent, il faut donc repasser
440
-	// dans le charset local...
441
-	if (
442
-		defined('_AJAX')
443
-		and _AJAX
444
-		and isset($GLOBALS['meta']['charset'])
445
-		and $GLOBALS['meta']['charset'] != 'utf-8'
446
-		and is_string($a)
447
-		// check rapide mais pas fiable
448
-		and preg_match(',[\x80-\xFF],', $a)
449
-		// check fiable
450
-		and include_spip('inc/charsets')
451
-		and is_utf8($a)
452
-	) {
453
-		return importer_charset($a, 'utf-8');
454
-	}
455
-
456
-	return $a;
426
+    if (is_array($c)) {
427
+        return $c[$var] ?? null;
428
+    }
429
+
430
+    if (isset($_GET[$var])) {
431
+        $a = $_GET[$var];
432
+    } elseif (isset($_POST[$var])) {
433
+        $a = $_POST[$var];
434
+    } else {
435
+        return null;
436
+    }
437
+
438
+    // Si on est en ajax et en POST tout a ete encode
439
+    // via encodeURIComponent, il faut donc repasser
440
+    // dans le charset local...
441
+    if (
442
+        defined('_AJAX')
443
+        and _AJAX
444
+        and isset($GLOBALS['meta']['charset'])
445
+        and $GLOBALS['meta']['charset'] != 'utf-8'
446
+        and is_string($a)
447
+        // check rapide mais pas fiable
448
+        and preg_match(',[\x80-\xFF],', $a)
449
+        // check fiable
450
+        and include_spip('inc/charsets')
451
+        and is_utf8($a)
452
+    ) {
453
+        return importer_charset($a, 'utf-8');
454
+    }
455
+
456
+    return $a;
457 457
 }
458 458
 
459 459
 
@@ -471,22 +471,22 @@  discard block
 block discarded – undo
471 471
  *     - false sinon
472 472
  **/
473 473
 function set_request($var, $val = null, $c = false) {
474
-	if (is_array($c)) {
475
-		unset($c[$var]);
476
-		if ($val !== null) {
477
-			$c[$var] = $val;
478
-		}
474
+    if (is_array($c)) {
475
+        unset($c[$var]);
476
+        if ($val !== null) {
477
+            $c[$var] = $val;
478
+        }
479 479
 
480
-		return $c;
481
-	}
480
+        return $c;
481
+    }
482 482
 
483
-	unset($_GET[$var]);
484
-	unset($_POST[$var]);
485
-	if ($val !== null) {
486
-		$_GET[$var] = $val;
487
-	}
483
+    unset($_GET[$var]);
484
+    unset($_POST[$var]);
485
+    if ($val !== null) {
486
+        $_GET[$var] = $val;
487
+    }
488 488
 
489
-	return false; # n'affecte pas $c
489
+    return false; # n'affecte pas $c
490 490
 }
491 491
 
492 492
 /**
@@ -506,25 +506,25 @@  discard block
 block discarded – undo
506 506
  * @return array|mixed|string
507 507
  */
508 508
 function spip_sanitize_from_request($value, $key, $sanitize_function = 'entites_html') {
509
-	if (is_array($value)) {
510
-		if ($key == '*') {
511
-			$key = array_keys($value);
512
-		}
513
-		if (!is_array($key)) {
514
-			$key = [$key];
515
-		}
516
-		foreach ($key as $k) {
517
-			if (!empty($value[$k])) {
518
-				$value[$k] = spip_sanitize_from_request($value[$k], $k, $sanitize_function);
519
-			}
520
-		}
521
-		return $value;
522
-	}
523
-	// si la valeur vient des GET ou POST on la sanitize
524
-	if (!empty($value) and $value == _request($key)) {
525
-		$value = $sanitize_function($value);
526
-	}
527
-	return $value;
509
+    if (is_array($value)) {
510
+        if ($key == '*') {
511
+            $key = array_keys($value);
512
+        }
513
+        if (!is_array($key)) {
514
+            $key = [$key];
515
+        }
516
+        foreach ($key as $k) {
517
+            if (!empty($value[$k])) {
518
+                $value[$k] = spip_sanitize_from_request($value[$k], $k, $sanitize_function);
519
+            }
520
+        }
521
+        return $value;
522
+    }
523
+    // si la valeur vient des GET ou POST on la sanitize
524
+    if (!empty($value) and $value == _request($key)) {
525
+        $value = $sanitize_function($value);
526
+    }
527
+    return $value;
528 528
 }
529 529
 
530 530
 /**
@@ -532,23 +532,22 @@  discard block
 block discarded – undo
532 532
  *
533 533
  * On est sur le web, on exclut certains protocoles,
534 534
  * notamment 'file://', 'php://' et d'autres…
535
-
536 535
  * @param string $url
537 536
  * @return bool
538 537
  */
539 538
 function tester_url_absolue($url) {
540
-	$url = trim($url ?? '');
541
-	if ($url && preg_match(';^([a-z]{3,7}:)?//;Uims', $url, $m)) {
542
-		if (
543
-			isset($m[1])
544
-			and $p = strtolower(rtrim($m[1], ':'))
545
-			and in_array($p, ['file', 'php', 'zlib', 'glob', 'phar', 'ssh2', 'rar', 'ogg', 'expect', 'zip'])
546
-		) {
547
-			return false;
548
-		}
549
-		return true;
550
-	}
551
-	return false;
539
+    $url = trim($url ?? '');
540
+    if ($url && preg_match(';^([a-z]{3,7}:)?//;Uims', $url, $m)) {
541
+        if (
542
+            isset($m[1])
543
+            and $p = strtolower(rtrim($m[1], ':'))
544
+            and in_array($p, ['file', 'php', 'zlib', 'glob', 'phar', 'ssh2', 'rar', 'ogg', 'expect', 'zip'])
545
+        ) {
546
+            return false;
547
+        }
548
+        return true;
549
+    }
550
+    return false;
552 551
 }
553 552
 
554 553
 /**
@@ -570,95 +569,95 @@  discard block
 block discarded – undo
570 569
  * @return string URL
571 570
  */
572 571
 function parametre_url($url, $c, $v = null, $sep = '&amp;') {
573
-	// requete erronnee : plusieurs variable dans $c et aucun $v
574
-	if (strpos($c, '|') !== false and is_null($v)) {
575
-		return null;
576
-	}
577
-
578
-	// lever l'#ancre
579
-	if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
580
-		$url = $r[1];
581
-		$ancre = $r[2];
582
-	} else {
583
-		$ancre = '';
584
-	}
585
-
586
-	// eclater
587
-	$url = preg_split(',[?]|&amp;|&,', $url);
588
-
589
-	// recuperer la base
590
-	$a = array_shift($url);
591
-	if (!$a) {
592
-		$a = './';
593
-	}
594
-
595
-	$regexp = ',^(' . str_replace('[]', '\[\]', $c) . '[[]?[]]?)(=.*)?$,';
596
-	$ajouts = array_flip(explode('|', $c));
597
-	$u = is_array($v) ? $v : rawurlencode((string) $v);
598
-	$testv = (is_array($v) ? count($v) : strlen((string) $v));
599
-	$v_read = null;
600
-	// lire les variables et agir
601
-	foreach ($url as $n => $val) {
602
-		if (preg_match($regexp, urldecode($val), $r)) {
603
-			$r = array_pad($r, 3, null);
604
-			if ($v === null) {
605
-				// c'est un tableau, on memorise les valeurs
606
-				if (substr($r[1], -2) == '[]') {
607
-					if (!$v_read) {
608
-						$v_read = [];
609
-					}
610
-					$v_read[] = $r[2] ? substr($r[2], 1) : '';
611
-				} // c'est un scalaire, on retourne direct
612
-				else {
613
-					return $r[2] ? substr($r[2], 1) : '';
614
-				}
615
-			} // suppression
616
-			elseif (!$testv) {
617
-				unset($url[$n]);
618
-			}
619
-			// Ajout. Pour une variable, remplacer au meme endroit,
620
-			// pour un tableau ce sera fait dans la prochaine boucle
621
-			elseif (substr($r[1], -2) != '[]') {
622
-				$url[$n] = $r[1] . '=' . $u;
623
-				unset($ajouts[$r[1]]);
624
-			}
625
-			// Pour les tableaux on laisse tomber les valeurs de
626
-			// départ, on remplira à l'étape suivante
627
-			else {
628
-				unset($url[$n]);
629
-			}
630
-		}
631
-	}
632
-
633
-	// traiter les parametres pas encore trouves
634
-	if (
635
-		$v === null
636
-		and $args = func_get_args()
637
-		and count($args) == 2
638
-	) {
639
-		return $v_read; // rien trouve ou un tableau
640
-	} elseif ($testv) {
641
-		foreach ($ajouts as $k => $n) {
642
-			if (!is_array($v)) {
643
-				$url[] = $k . '=' . $u;
644
-			} else {
645
-				$id = (substr($k, -2) == '[]') ? $k : ($k . '[]');
646
-				foreach ($v as $w) {
647
-					$url[] = $id . '=' . (is_array($w) ? 'Array' : rawurlencode($w));
648
-				}
649
-			}
650
-		}
651
-	}
652
-
653
-	// eliminer les vides
654
-	$url = array_filter($url);
655
-
656
-	// recomposer l'adresse
657
-	if ($url) {
658
-		$a .= '?' . join($sep, $url);
659
-	}
660
-
661
-	return $a . $ancre;
572
+    // requete erronnee : plusieurs variable dans $c et aucun $v
573
+    if (strpos($c, '|') !== false and is_null($v)) {
574
+        return null;
575
+    }
576
+
577
+    // lever l'#ancre
578
+    if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
579
+        $url = $r[1];
580
+        $ancre = $r[2];
581
+    } else {
582
+        $ancre = '';
583
+    }
584
+
585
+    // eclater
586
+    $url = preg_split(',[?]|&amp;|&,', $url);
587
+
588
+    // recuperer la base
589
+    $a = array_shift($url);
590
+    if (!$a) {
591
+        $a = './';
592
+    }
593
+
594
+    $regexp = ',^(' . str_replace('[]', '\[\]', $c) . '[[]?[]]?)(=.*)?$,';
595
+    $ajouts = array_flip(explode('|', $c));
596
+    $u = is_array($v) ? $v : rawurlencode((string) $v);
597
+    $testv = (is_array($v) ? count($v) : strlen((string) $v));
598
+    $v_read = null;
599
+    // lire les variables et agir
600
+    foreach ($url as $n => $val) {
601
+        if (preg_match($regexp, urldecode($val), $r)) {
602
+            $r = array_pad($r, 3, null);
603
+            if ($v === null) {
604
+                // c'est un tableau, on memorise les valeurs
605
+                if (substr($r[1], -2) == '[]') {
606
+                    if (!$v_read) {
607
+                        $v_read = [];
608
+                    }
609
+                    $v_read[] = $r[2] ? substr($r[2], 1) : '';
610
+                } // c'est un scalaire, on retourne direct
611
+                else {
612
+                    return $r[2] ? substr($r[2], 1) : '';
613
+                }
614
+            } // suppression
615
+            elseif (!$testv) {
616
+                unset($url[$n]);
617
+            }
618
+            // Ajout. Pour une variable, remplacer au meme endroit,
619
+            // pour un tableau ce sera fait dans la prochaine boucle
620
+            elseif (substr($r[1], -2) != '[]') {
621
+                $url[$n] = $r[1] . '=' . $u;
622
+                unset($ajouts[$r[1]]);
623
+            }
624
+            // Pour les tableaux on laisse tomber les valeurs de
625
+            // départ, on remplira à l'étape suivante
626
+            else {
627
+                unset($url[$n]);
628
+            }
629
+        }
630
+    }
631
+
632
+    // traiter les parametres pas encore trouves
633
+    if (
634
+        $v === null
635
+        and $args = func_get_args()
636
+        and count($args) == 2
637
+    ) {
638
+        return $v_read; // rien trouve ou un tableau
639
+    } elseif ($testv) {
640
+        foreach ($ajouts as $k => $n) {
641
+            if (!is_array($v)) {
642
+                $url[] = $k . '=' . $u;
643
+            } else {
644
+                $id = (substr($k, -2) == '[]') ? $k : ($k . '[]');
645
+                foreach ($v as $w) {
646
+                    $url[] = $id . '=' . (is_array($w) ? 'Array' : rawurlencode($w));
647
+                }
648
+            }
649
+        }
650
+    }
651
+
652
+    // eliminer les vides
653
+    $url = array_filter($url);
654
+
655
+    // recomposer l'adresse
656
+    if ($url) {
657
+        $a .= '?' . join($sep, $url);
658
+    }
659
+
660
+    return $a . $ancre;
662 661
 }
663 662
 
664 663
 /**
@@ -676,21 +675,21 @@  discard block
 block discarded – undo
676 675
  * @return string
677 676
  */
678 677
 function ancre_url($url, $ancre) {
679
-	// lever l'#ancre
680
-	if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
681
-		$url = $r[1];
682
-	}
683
-	if (preg_match('/[^-_a-zA-Z0-9]+/S', $ancre)) {
684
-		if (!function_exists('translitteration')) {
685
-			include_spip('inc/charsets');
686
-		}
687
-		$ancre = preg_replace(
688
-			['/^[^-_a-zA-Z0-9]+/', '/[^-_a-zA-Z0-9]/'],
689
-			['', '-'],
690
-			translitteration($ancre)
691
-		);
692
-	}
693
-	return $url . (strlen($ancre) ? '#' . $ancre : '');
678
+    // lever l'#ancre
679
+    if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
680
+        $url = $r[1];
681
+    }
682
+    if (preg_match('/[^-_a-zA-Z0-9]+/S', $ancre)) {
683
+        if (!function_exists('translitteration')) {
684
+            include_spip('inc/charsets');
685
+        }
686
+        $ancre = preg_replace(
687
+            ['/^[^-_a-zA-Z0-9]+/', '/[^-_a-zA-Z0-9]/'],
688
+            ['', '-'],
689
+            translitteration($ancre)
690
+        );
691
+    }
692
+    return $url . (strlen($ancre) ? '#' . $ancre : '');
694 693
 }
695 694
 
696 695
 /**
@@ -700,16 +699,16 @@  discard block
 block discarded – undo
700 699
  * @return string
701 700
  */
702 701
 function nettoyer_uri($reset = null) {
703
-	static $done = false;
704
-	static $propre = '';
705
-	if (!is_null($reset)) {
706
-		return $propre = $reset;
707
-	}
708
-	if ($done) {
709
-		return $propre;
710
-	}
711
-	$done = true;
712
-	return $propre = nettoyer_uri_var($GLOBALS['REQUEST_URI']);
702
+    static $done = false;
703
+    static $propre = '';
704
+    if (!is_null($reset)) {
705
+        return $propre = $reset;
706
+    }
707
+    if ($done) {
708
+        return $propre;
709
+    }
710
+    $done = true;
711
+    return $propre = nettoyer_uri_var($GLOBALS['REQUEST_URI']);
713 712
 }
714 713
 
715 714
 /**
@@ -721,16 +720,16 @@  discard block
 block discarded – undo
721 720
  * @return string
722 721
  */
723 722
 function nettoyer_uri_var($request_uri) {
724
-	$uri1 = $request_uri;
725
-	do {
726
-		$uri = $uri1;
727
-		$uri1 = preg_replace(
728
-			',([?&])(var_[^=&]*|PHPSESSID|fbclid|utm_[^=&]*)=[^&]*(&|$),i',
729
-			'\1',
730
-			$uri
731
-		);
732
-	} while ($uri <> $uri1);
733
-	return preg_replace(',[?&]$,', '', $uri1);
723
+    $uri1 = $request_uri;
724
+    do {
725
+        $uri = $uri1;
726
+        $uri1 = preg_replace(
727
+            ',([?&])(var_[^=&]*|PHPSESSID|fbclid|utm_[^=&]*)=[^&]*(&|$),i',
728
+            '\1',
729
+            $uri
730
+        );
731
+    } while ($uri <> $uri1);
732
+    return preg_replace(',[?&]$,', '', $uri1);
734 733
 }
735 734
 
736 735
 
@@ -744,48 +743,48 @@  discard block
 block discarded – undo
744 743
  *    URL vers soi-même
745 744
  **/
746 745
 function self($amp = '&amp;', $root = false) {
747
-	$url = nettoyer_uri();
748
-	if (
749
-		!$root
750
-		and (
751
-			// si pas de profondeur on peut tronquer
752
-			$GLOBALS['profondeur_url'] < (_DIR_RESTREINT ? 1 : 2)
753
-			// sinon c'est OK si _SET_HTML_BASE a ete force a false
754
-			or (defined('_SET_HTML_BASE') and !_SET_HTML_BASE))
755
-	) {
756
-		$url = preg_replace(',^[^?]*/,', '', $url);
757
-	}
758
-	// ajouter le cas echeant les variables _POST['id_...']
759
-	foreach ($_POST as $v => $c) {
760
-		if (substr($v, 0, 3) == 'id_') {
761
-			$url = parametre_url($url, $v, $c, '&');
762
-		}
763
-	}
764
-
765
-	// supprimer les variables sans interet
766
-	if (test_espace_prive()) {
767
-		$url = preg_replace(',([?&])('
768
-			. 'lang|show_docs|'
769
-			. 'changer_lang|var_lang|action)=[^&]*,i', '\1', $url);
770
-		$url = preg_replace(',([?&])[&]+,', '\1', $url);
771
-		$url = preg_replace(',[&]$,', '\1', $url);
772
-	}
773
-
774
-	// eviter les hacks
775
-	include_spip('inc/filtres_mini');
776
-	$url = spip_htmlspecialchars($url);
777
-
778
-	$url = str_replace(["'", '"', '<', '[', ']', ':'], ['%27', '%22', '%3C', '%5B', '%5D', '%3A'], $url);
779
-
780
-	// &amp; ?
781
-	if ($amp != '&amp;') {
782
-		$url = str_replace('&amp;', $amp, $url);
783
-	}
784
-
785
-	// Si ca demarre par ? ou vide, donner './'
786
-	$url = preg_replace(',^([?].*)?$,', './\1', $url);
787
-
788
-	return $url;
746
+    $url = nettoyer_uri();
747
+    if (
748
+        !$root
749
+        and (
750
+            // si pas de profondeur on peut tronquer
751
+            $GLOBALS['profondeur_url'] < (_DIR_RESTREINT ? 1 : 2)
752
+            // sinon c'est OK si _SET_HTML_BASE a ete force a false
753
+            or (defined('_SET_HTML_BASE') and !_SET_HTML_BASE))
754
+    ) {
755
+        $url = preg_replace(',^[^?]*/,', '', $url);
756
+    }
757
+    // ajouter le cas echeant les variables _POST['id_...']
758
+    foreach ($_POST as $v => $c) {
759
+        if (substr($v, 0, 3) == 'id_') {
760
+            $url = parametre_url($url, $v, $c, '&');
761
+        }
762
+    }
763
+
764
+    // supprimer les variables sans interet
765
+    if (test_espace_prive()) {
766
+        $url = preg_replace(',([?&])('
767
+            . 'lang|show_docs|'
768
+            . 'changer_lang|var_lang|action)=[^&]*,i', '\1', $url);
769
+        $url = preg_replace(',([?&])[&]+,', '\1', $url);
770
+        $url = preg_replace(',[&]$,', '\1', $url);
771
+    }
772
+
773
+    // eviter les hacks
774
+    include_spip('inc/filtres_mini');
775
+    $url = spip_htmlspecialchars($url);
776
+
777
+    $url = str_replace(["'", '"', '<', '[', ']', ':'], ['%27', '%22', '%3C', '%5B', '%5D', '%3A'], $url);
778
+
779
+    // &amp; ?
780
+    if ($amp != '&amp;') {
781
+        $url = str_replace('&amp;', $amp, $url);
782
+    }
783
+
784
+    // Si ca demarre par ? ou vide, donner './'
785
+    $url = preg_replace(',^([?].*)?$,', './\1', $url);
786
+
787
+    return $url;
789 788
 }
790 789
 
791 790
 
@@ -796,7 +795,7 @@  discard block
 block discarded – undo
796 795
  *     true si c'est le cas, false sinon.
797 796
  */
798 797
 function test_espace_prive() {
799
-	return defined('_ESPACE_PRIVE') ? _ESPACE_PRIVE : false;
798
+    return defined('_ESPACE_PRIVE') ? _ESPACE_PRIVE : false;
800 799
 }
801 800
 
802 801
 /**
@@ -806,7 +805,7 @@  discard block
 block discarded – undo
806 805
  * @return bool
807 806
  */
808 807
 function test_plugin_actif($plugin) {
809
-	return ($plugin and defined('_DIR_PLUGIN_' . strtoupper($plugin))) ? true : false;
808
+    return ($plugin and defined('_DIR_PLUGIN_' . strtoupper($plugin))) ? true : false;
810 809
 }
811 810
 
812 811
 /**
@@ -837,52 +836,52 @@  discard block
 block discarded – undo
837 836
  *     Texte
838 837
  */
839 838
 function _T($texte, $args = [], $options = []) {
840
-	static $traduire = false;
841
-	$o = ['class' => '', 'force' => true, 'sanitize' => true];
842
-	if ($options) {
843
-		// support de l'ancien argument $class
844
-		if (is_string($options)) {
845
-			$options = ['class' => $options];
846
-		}
847
-		$o = array_merge($o, $options);
848
-	}
849
-
850
-	if (!$traduire) {
851
-		$traduire = charger_fonction('traduire', 'inc');
852
-		include_spip('inc/lang');
853
-	}
854
-
855
-	// On peut passer explicitement la langue dans le tableau
856
-	// On utilise le même nom de variable que la globale
857
-	if (isset($args['spip_lang'])) {
858
-		$lang = $args['spip_lang'];
859
-		// On l'enleve pour ne pas le passer au remplacement
860
-		unset($args['spip_lang']);
861
-	} // Sinon on prend la langue du contexte
862
-	else {
863
-		$lang = $GLOBALS['spip_lang'];
864
-	}
865
-	$text = $traduire($texte, $lang);
866
-
867
-	if ($text === null || !strlen($text)) {
868
-		if (!$o['force']) {
869
-			return '';
870
-		}
871
-
872
-		$text = $texte;
873
-
874
-		// pour les chaines non traduites, assurer un service minimum
875
-		if (!$GLOBALS['test_i18n'] and (_request('var_mode') != 'traduction')) {
876
-			$n = strpos($text, ':');
877
-			if ($n !== false) {
878
-				$text = substr($text, $n + 1);
879
-			}
880
-			$text = str_replace('_', ' ', $text);
881
-		}
882
-		$o['class'] = null;
883
-	}
884
-
885
-	return _L($text, $args, $o);
839
+    static $traduire = false;
840
+    $o = ['class' => '', 'force' => true, 'sanitize' => true];
841
+    if ($options) {
842
+        // support de l'ancien argument $class
843
+        if (is_string($options)) {
844
+            $options = ['class' => $options];
845
+        }
846
+        $o = array_merge($o, $options);
847
+    }
848
+
849
+    if (!$traduire) {
850
+        $traduire = charger_fonction('traduire', 'inc');
851
+        include_spip('inc/lang');
852
+    }
853
+
854
+    // On peut passer explicitement la langue dans le tableau
855
+    // On utilise le même nom de variable que la globale
856
+    if (isset($args['spip_lang'])) {
857
+        $lang = $args['spip_lang'];
858
+        // On l'enleve pour ne pas le passer au remplacement
859
+        unset($args['spip_lang']);
860
+    } // Sinon on prend la langue du contexte
861
+    else {
862
+        $lang = $GLOBALS['spip_lang'];
863
+    }
864
+    $text = $traduire($texte, $lang);
865
+
866
+    if ($text === null || !strlen($text)) {
867
+        if (!$o['force']) {
868
+            return '';
869
+        }
870
+
871
+        $text = $texte;
872
+
873
+        // pour les chaines non traduites, assurer un service minimum
874
+        if (!$GLOBALS['test_i18n'] and (_request('var_mode') != 'traduction')) {
875
+            $n = strpos($text, ':');
876
+            if ($n !== false) {
877
+                $text = substr($text, $n + 1);
878
+            }
879
+            $text = str_replace('_', ' ', $text);
880
+        }
881
+        $o['class'] = null;
882
+    }
883
+
884
+    return _L($text, $args, $o);
886 885
 }
887 886
 
888 887
 
@@ -909,53 +908,53 @@  discard block
 block discarded – undo
909 908
  *     Texte
910 909
  */
911 910
 function _L($text, $args = [], $options = []) {
912
-	$f = $text;
913
-	$defaut_options = [
914
-		'class' => null,
915
-		'sanitize' => true,
916
-	];
917
-	// support de l'ancien argument $class
918
-	if ($options and is_string($options)) {
919
-		$options = ['class' => $options];
920
-	}
921
-	if (is_array($options)) {
922
-		$options += $defaut_options;
923
-	} else {
924
-		$options = $defaut_options;
925
-	}
926
-
927
-	if (is_array($args) and count($args)) {
928
-		if (!function_exists('interdire_scripts')) {
929
-			include_spip('inc/texte');
930
-		}
931
-		if (!function_exists('echapper_html_suspect')) {
932
-			include_spip('inc/texte_mini');
933
-		}
934
-		foreach ($args as $name => $value) {
935
-			if (strpos($text, (string) "@$name@") !== false) {
936
-				if ($options['sanitize']) {
937
-					$value = echapper_html_suspect($value);
938
-					$value = interdire_scripts($value, -1);
939
-				}
940
-				if (!empty($options['class'])) {
941
-					$value = "<span class='" . $options['class'] . "'>$value</span>";
942
-				}
943
-				$text = str_replace("@$name@", $value, $text);
944
-				unset($args[$name]);
945
-			}
946
-		}
947
-		// Si des variables n'ont pas ete inserees, le signaler
948
-		// (chaines de langues pas a jour)
949
-		if ($args) {
950
-			spip_log("$f:  variables inutilisees " . join(', ', array_keys($args)), _LOG_DEBUG);
951
-		}
952
-	}
953
-
954
-	if (($GLOBALS['test_i18n'] or (_request('var_mode') == 'traduction')) and is_null($options['class'])) {
955
-		return "<span class='debug-traduction-erreur'>$text</span>";
956
-	} else {
957
-		return $text;
958
-	}
911
+    $f = $text;
912
+    $defaut_options = [
913
+        'class' => null,
914
+        'sanitize' => true,
915
+    ];
916
+    // support de l'ancien argument $class
917
+    if ($options and is_string($options)) {
918
+        $options = ['class' => $options];
919
+    }
920
+    if (is_array($options)) {
921
+        $options += $defaut_options;
922
+    } else {
923
+        $options = $defaut_options;
924
+    }
925
+
926
+    if (is_array($args) and count($args)) {
927
+        if (!function_exists('interdire_scripts')) {
928
+            include_spip('inc/texte');
929
+        }
930
+        if (!function_exists('echapper_html_suspect')) {
931
+            include_spip('inc/texte_mini');
932
+        }
933
+        foreach ($args as $name => $value) {
934
+            if (strpos($text, (string) "@$name@") !== false) {
935
+                if ($options['sanitize']) {
936
+                    $value = echapper_html_suspect($value);
937
+                    $value = interdire_scripts($value, -1);
938
+                }
939
+                if (!empty($options['class'])) {
940
+                    $value = "<span class='" . $options['class'] . "'>$value</span>";
941
+                }
942
+                $text = str_replace("@$name@", $value, $text);
943
+                unset($args[$name]);
944
+            }
945
+        }
946
+        // Si des variables n'ont pas ete inserees, le signaler
947
+        // (chaines de langues pas a jour)
948
+        if ($args) {
949
+            spip_log("$f:  variables inutilisees " . join(', ', array_keys($args)), _LOG_DEBUG);
950
+        }
951
+    }
952
+
953
+    if (($GLOBALS['test_i18n'] or (_request('var_mode') == 'traduction')) and is_null($options['class'])) {
954
+        return "<span class='debug-traduction-erreur'>$text</span>";
955
+    } else {
956
+        return $text;
957
+    }
959 958
 }
960 959
 
961 960
 
@@ -969,13 +968,13 @@  discard block
 block discarded – undo
969 968
  * @return string
970 969
  */
971 970
 function joli_repertoire($rep) {
972
-	$a = substr($rep, 0, 1);
973
-	if ($a <> '.' and $a <> '/') {
974
-		$rep = (_DIR_RESTREINT ? '' : _DIR_RESTREINT_ABS) . $rep;
975
-	}
976
-	$rep = preg_replace(',(^\.\.\/),', '', $rep);
971
+    $a = substr($rep, 0, 1);
972
+    if ($a <> '.' and $a <> '/') {
973
+        $rep = (_DIR_RESTREINT ? '' : _DIR_RESTREINT_ABS) . $rep;
974
+    }
975
+    $rep = preg_replace(',(^\.\.\/),', '', $rep);
977 976
 
978
-	return $rep;
977
+    return $rep;
979 978
 }
980 979
 
981 980
 
@@ -1000,54 +999,54 @@  discard block
 block discarded – undo
1000 999
  * @return float|int|string|void
1001 1000
  */
1002 1001
 function spip_timer($t = 'rien', $raw = false) {
1003
-	static $time;
1004
-	$a = time();
1005
-	$b = microtime();
1006
-	// microtime peut contenir les microsecondes et le temps
1007
-	$b = explode(' ', $b);
1008
-	if (count($b) == 2) {
1009
-		$a = end($b);
1010
-	} // plus precis !
1011
-	$b = reset($b);
1012
-	if (!isset($time[$t])) {
1013
-		$time[$t] = $a + $b;
1014
-	} else {
1015
-		$p = ($a + $b - $time[$t]) * 1000;
1016
-		unset($time[$t]);
1002
+    static $time;
1003
+    $a = time();
1004
+    $b = microtime();
1005
+    // microtime peut contenir les microsecondes et le temps
1006
+    $b = explode(' ', $b);
1007
+    if (count($b) == 2) {
1008
+        $a = end($b);
1009
+    } // plus precis !
1010
+    $b = reset($b);
1011
+    if (!isset($time[$t])) {
1012
+        $time[$t] = $a + $b;
1013
+    } else {
1014
+        $p = ($a + $b - $time[$t]) * 1000;
1015
+        unset($time[$t]);
1017 1016
 #			echo "'$p'";exit;
1018
-		if ($raw) {
1019
-			return $p;
1020
-		}
1021
-		if ($p < 1000) {
1022
-			$s = '';
1023
-		} else {
1024
-			$s = sprintf('%d ', $x = floor($p / 1000));
1025
-			$p -= ($x * 1000);
1026
-		}
1017
+        if ($raw) {
1018
+            return $p;
1019
+        }
1020
+        if ($p < 1000) {
1021
+            $s = '';
1022
+        } else {
1023
+            $s = sprintf('%d ', $x = floor($p / 1000));
1024
+            $p -= ($x * 1000);
1025
+        }
1027 1026
 
1028
-		return $s . sprintf($s ? '%07.3f ms' : '%.3f ms', $p);
1029
-	}
1027
+        return $s . sprintf($s ? '%07.3f ms' : '%.3f ms', $p);
1028
+    }
1030 1029
 }
1031 1030
 
1032 1031
 
1033 1032
 // Renvoie False si un fichier n'est pas plus vieux que $duree secondes,
1034 1033
 // sinon renvoie True et le date sauf si ca n'est pas souhaite
1035 1034
 function spip_touch($fichier, $duree = 0, $touch = true) {
1036
-	if ($duree) {
1037
-		clearstatcache();
1038
-		if ((@$f = filemtime($fichier)) and ($f >= time() - $duree)) {
1039
-			return false;
1040
-		}
1041
-	}
1042
-	if ($touch !== false) {
1043
-		if (!@touch($fichier)) {
1044
-			spip_unlink($fichier);
1045
-			@touch($fichier);
1046
-		};
1047
-		@chmod($fichier, _SPIP_CHMOD & ~0111);
1048
-	}
1035
+    if ($duree) {
1036
+        clearstatcache();
1037
+        if ((@$f = filemtime($fichier)) and ($f >= time() - $duree)) {
1038
+            return false;
1039
+        }
1040
+    }
1041
+    if ($touch !== false) {
1042
+        if (!@touch($fichier)) {
1043
+            spip_unlink($fichier);
1044
+            @touch($fichier);
1045
+        };
1046
+        @chmod($fichier, _SPIP_CHMOD & ~0111);
1047
+    }
1049 1048
 
1050
-	return true;
1049
+    return true;
1051 1050
 }
1052 1051
 
1053 1052
 
@@ -1058,11 +1057,11 @@  discard block
 block discarded – undo
1058 1057
  * @uses cron()
1059 1058
  **/
1060 1059
 function action_cron() {
1061
-	include_spip('inc/headers');
1062
-	http_response_code(204); // No Content
1063
-	header('Connection: close');
1064
-	define('_DIRECT_CRON_FORCE', true);
1065
-	cron();
1060
+    include_spip('inc/headers');
1061
+    http_response_code(204); // No Content
1062
+    header('Connection: close');
1063
+    define('_DIRECT_CRON_FORCE', true);
1064
+    cron();
1066 1065
 }
1067 1066
 
1068 1067
 /**
@@ -1078,26 +1077,26 @@  discard block
 block discarded – undo
1078 1077
  *     True si la tache a pu être effectuée
1079 1078
  */
1080 1079
 function cron($taches = [], $taches_old = []) {
1081
-	// si pas en mode cron force, laisser tomber.
1082
-	if (!defined('_DIRECT_CRON_FORCE')) {
1083
-		return false;
1084
-	}
1085
-	if (!is_array($taches)) {
1086
-		$taches = $taches_old;
1087
-	} // compat anciens appels
1088
-	// si taches a inserer en base et base inaccessible, laisser tomber
1089
-	// sinon on ne verifie pas la connexion tout de suite, car si ca se trouve
1090
-	// queue_sleep_time_to_next_job() dira qu'il n'y a rien a faire
1091
-	// et on evite d'ouvrir une connexion pour rien (utilisation de _DIRECT_CRON_FORCE dans mes_options.php)
1092
-	if ($taches and count($taches) and !spip_connect()) {
1093
-		return false;
1094
-	}
1095
-	spip_log('cron !', 'jq' . _LOG_DEBUG);
1096
-	if ($genie = charger_fonction('genie', 'inc', true)) {
1097
-		return $genie($taches);
1098
-	}
1099
-
1100
-	return false;
1080
+    // si pas en mode cron force, laisser tomber.
1081
+    if (!defined('_DIRECT_CRON_FORCE')) {
1082
+        return false;
1083
+    }
1084
+    if (!is_array($taches)) {
1085
+        $taches = $taches_old;
1086
+    } // compat anciens appels
1087
+    // si taches a inserer en base et base inaccessible, laisser tomber
1088
+    // sinon on ne verifie pas la connexion tout de suite, car si ca se trouve
1089
+    // queue_sleep_time_to_next_job() dira qu'il n'y a rien a faire
1090
+    // et on evite d'ouvrir une connexion pour rien (utilisation de _DIRECT_CRON_FORCE dans mes_options.php)
1091
+    if ($taches and count($taches) and !spip_connect()) {
1092
+        return false;
1093
+    }
1094
+    spip_log('cron !', 'jq' . _LOG_DEBUG);
1095
+    if ($genie = charger_fonction('genie', 'inc', true)) {
1096
+        return $genie($taches);
1097
+    }
1098
+
1099
+    return false;
1101 1100
 }
1102 1101
 
1103 1102
 /**
@@ -1129,17 +1128,17 @@  discard block
 block discarded – undo
1129 1128
  *     Le numéro de travail ajouté ou `0` si aucun travail n’a été ajouté.
1130 1129
  */
1131 1130
 function job_queue_add(
1132
-	$function,
1133
-	$description,
1134
-	$arguments = [],
1135
-	$file = '',
1136
-	$no_duplicate = false,
1137
-	$time = 0,
1138
-	$priority = 0
1131
+    $function,
1132
+    $description,
1133
+    $arguments = [],
1134
+    $file = '',
1135
+    $no_duplicate = false,
1136
+    $time = 0,
1137
+    $priority = 0
1139 1138
 ) {
1140
-	include_spip('inc/queue');
1139
+    include_spip('inc/queue');
1141 1140
 
1142
-	return queue_add_job($function, $description, $arguments, $file, $no_duplicate, $time, $priority);
1141
+    return queue_add_job($function, $description, $arguments, $file, $no_duplicate, $time, $priority);
1143 1142
 }
1144 1143
 
1145 1144
 /**
@@ -1150,9 +1149,9 @@  discard block
 block discarded – undo
1150 1149
  * @return bool
1151 1150
  */
1152 1151
 function job_queue_remove($id_job) {
1153
-	include_spip('inc/queue');
1152
+    include_spip('inc/queue');
1154 1153
 
1155
-	return queue_remove_job($id_job);
1154
+    return queue_remove_job($id_job);
1156 1155
 }
1157 1156
 
1158 1157
 /**
@@ -1165,9 +1164,9 @@  discard block
 block discarded – undo
1165 1164
  *     or an array of simple array to link multiples objet in one time
1166 1165
  */
1167 1166
 function job_queue_link($id_job, $objets) {
1168
-	include_spip('inc/queue');
1167
+    include_spip('inc/queue');
1169 1168
 
1170
-	return queue_link_job($id_job, $objets);
1169
+    return queue_link_job($id_job, $objets);
1171 1170
 }
1172 1171
 
1173 1172
 
@@ -1187,36 +1186,36 @@  discard block
 block discarded – undo
1187 1186
  *  - `null` si la queue n'est pas encore initialisée
1188 1187
  */
1189 1188
 function queue_sleep_time_to_next_job($force = null) {
1190
-	static $queue_next_job_time = -1;
1191
-	if ($force === true) {
1192
-		$queue_next_job_time = -1;
1193
-	} elseif ($force) {
1194
-		$queue_next_job_time = $force;
1195
-	}
1196
-
1197
-	if ($queue_next_job_time == -1) {
1198
-		if (!defined('_JQ_NEXT_JOB_TIME_FILENAME')) {
1199
-			define('_JQ_NEXT_JOB_TIME_FILENAME', _DIR_TMP . 'job_queue_next.txt');
1200
-		}
1201
-		// utiliser un cache memoire si dispo
1202
-		if (function_exists('cache_get') and defined('_MEMOIZE_MEMORY') and _MEMOIZE_MEMORY) {
1203
-			$queue_next_job_time = cache_get(_JQ_NEXT_JOB_TIME_FILENAME);
1204
-		} else {
1205
-			$queue_next_job_time = null;
1206
-			if (lire_fichier(_JQ_NEXT_JOB_TIME_FILENAME, $contenu)) {
1207
-				$queue_next_job_time = intval($contenu);
1208
-			}
1209
-		}
1210
-	}
1211
-
1212
-	if (is_null($queue_next_job_time)) {
1213
-		return null;
1214
-	}
1215
-	if (!$_SERVER['REQUEST_TIME']) {
1216
-		$_SERVER['REQUEST_TIME'] = time();
1217
-	}
1218
-
1219
-	return $queue_next_job_time - $_SERVER['REQUEST_TIME'];
1189
+    static $queue_next_job_time = -1;
1190
+    if ($force === true) {
1191
+        $queue_next_job_time = -1;
1192
+    } elseif ($force) {
1193
+        $queue_next_job_time = $force;
1194
+    }
1195
+
1196
+    if ($queue_next_job_time == -1) {
1197
+        if (!defined('_JQ_NEXT_JOB_TIME_FILENAME')) {
1198
+            define('_JQ_NEXT_JOB_TIME_FILENAME', _DIR_TMP . 'job_queue_next.txt');
1199
+        }
1200
+        // utiliser un cache memoire si dispo
1201
+        if (function_exists('cache_get') and defined('_MEMOIZE_MEMORY') and _MEMOIZE_MEMORY) {
1202
+            $queue_next_job_time = cache_get(_JQ_NEXT_JOB_TIME_FILENAME);
1203
+        } else {
1204
+            $queue_next_job_time = null;
1205
+            if (lire_fichier(_JQ_NEXT_JOB_TIME_FILENAME, $contenu)) {
1206
+                $queue_next_job_time = intval($contenu);
1207
+            }
1208
+        }
1209
+    }
1210
+
1211
+    if (is_null($queue_next_job_time)) {
1212
+        return null;
1213
+    }
1214
+    if (!$_SERVER['REQUEST_TIME']) {
1215
+        $_SERVER['REQUEST_TIME'] = time();
1216
+    }
1217
+
1218
+    return $queue_next_job_time - $_SERVER['REQUEST_TIME'];
1220 1219
 }
1221 1220
 
1222 1221
 
@@ -1228,11 +1227,11 @@  discard block
 block discarded – undo
1228 1227
  * @return string
1229 1228
  */
1230 1229
 function quote_amp($u) {
1231
-	return preg_replace(
1232
-		'/&(?![a-z]{0,4}\w{2,3};|#x?[0-9a-f]{2,6};)/i',
1233
-		'&amp;',
1234
-		$u
1235
-	);
1230
+    return preg_replace(
1231
+        '/&(?![a-z]{0,4}\w{2,3};|#x?[0-9a-f]{2,6};)/i',
1232
+        '&amp;',
1233
+        $u
1234
+    );
1236 1235
 }
1237 1236
 
1238 1237
 
@@ -1255,27 +1254,27 @@  discard block
 block discarded – undo
1255 1254
  *     Balise HTML `<script>` et son contenu
1256 1255
  **/
1257 1256
 function http_script($script, $src = '', $noscript = '') {
1258
-	static $done = [];
1257
+    static $done = [];
1259 1258
 
1260
-	if ($src && !isset($done[$src])) {
1261
-		$done[$src] = true;
1262
-		$src = find_in_path($src, _JAVASCRIPT);
1263
-		$src = " src='$src'";
1264
-	} else {
1265
-		$src = '';
1266
-	}
1267
-	if ($script) {
1268
-		$script = ("/*<![CDATA[*/\n" .
1269
-			preg_replace(',</([^>]*)>,', '<\/\1>', $script) .
1270
-			'/*]]>*/');
1271
-	}
1272
-	if ($noscript) {
1273
-		$noscript = "<noscript>\n\t$noscript\n</noscript>\n";
1274
-	}
1259
+    if ($src && !isset($done[$src])) {
1260
+        $done[$src] = true;
1261
+        $src = find_in_path($src, _JAVASCRIPT);
1262
+        $src = " src='$src'";
1263
+    } else {
1264
+        $src = '';
1265
+    }
1266
+    if ($script) {
1267
+        $script = ("/*<![CDATA[*/\n" .
1268
+            preg_replace(',</([^>]*)>,', '<\/\1>', $script) .
1269
+            '/*]]>*/');
1270
+    }
1271
+    if ($noscript) {
1272
+        $noscript = "<noscript>\n\t$noscript\n</noscript>\n";
1273
+    }
1275 1274
 
1276
-	return ($src or $script or $noscript)
1277
-		? "<script type='text/javascript'$src>$script</script>$noscript"
1278
-		: '';
1275
+    return ($src or $script or $noscript)
1276
+        ? "<script type='text/javascript'$src>$script</script>$noscript"
1277
+        : '';
1279 1278
 }
1280 1279
 
1281 1280
 
@@ -1310,7 +1309,7 @@  discard block
 block discarded – undo
1310 1309
  *     Texte échappé
1311 1310
  **/
1312 1311
 function texte_script(string $texte): string {
1313
-	return str_replace('\'', '\\\'', str_replace('\\', '\\\\', $texte));
1312
+    return str_replace('\'', '\\\'', str_replace('\\', '\\\\', $texte));
1314 1313
 }
1315 1314
 
1316 1315
 
@@ -1347,68 +1346,68 @@  discard block
 block discarded – undo
1347 1346
  *     Liste des chemins, par ordre de priorité.
1348 1347
  **/
1349 1348
 function _chemin($dir_path = null) {
1350
-	static $path_base = null;
1351
-	static $path_full = null;
1352
-	if ($path_base == null) {
1353
-		// Chemin standard depuis l'espace public
1354
-		$path = defined('_SPIP_PATH') ? _SPIP_PATH :
1355
-			_DIR_RACINE . ':' .
1356
-			_DIR_RACINE . 'squelettes-dist/:' .
1357
-			_DIR_RACINE . 'prive/:' .
1358
-			_DIR_RESTREINT;
1359
-		// Ajouter squelettes/
1360
-		if (@is_dir(_DIR_RACINE . 'squelettes')) {
1361
-			$path = _DIR_RACINE . 'squelettes/:' . $path;
1362
-		}
1363
-		foreach (explode(':', $path) as $dir) {
1364
-			if (strlen($dir) and substr($dir, -1) != '/') {
1365
-				$dir .= '/';
1366
-			}
1367
-			$path_base[] = $dir;
1368
-		}
1369
-		$path_full = $path_base;
1370
-		// Et le(s) dossier(s) des squelettes nommes
1371
-		if (strlen($GLOBALS['dossier_squelettes'])) {
1372
-			foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d) {
1373
-				array_unshift($path_full, ($d[0] == '/' ? '' : _DIR_RACINE) . $d . '/');
1374
-			}
1375
-		}
1376
-		$GLOBALS['path_sig'] = md5(serialize($path_full));
1377
-	}
1378
-	if ($dir_path === null) {
1379
-		return $path_full;
1380
-	}
1381
-
1382
-	if (is_array($dir_path) or strlen($dir_path)) {
1383
-		$tete = '';
1384
-		if (reset($path_base) == _DIR_RACINE . 'squelettes/') {
1385
-			$tete = array_shift($path_base);
1386
-		}
1387
-		$dirs = (is_array($dir_path) ? $dir_path : explode(':', $dir_path));
1388
-		$dirs = array_reverse($dirs);
1389
-		foreach ($dirs as $dir_path) {
1390
-			if (substr($dir_path, -1) != '/') {
1391
-				$dir_path .= '/';
1392
-			}
1393
-			if (!in_array($dir_path, $path_base)) {
1394
-				array_unshift($path_base, $dir_path);
1395
-			}
1396
-		}
1397
-		if (strlen($tete)) {
1398
-			array_unshift($path_base, $tete);
1399
-		}
1400
-	}
1401
-	$path_full = $path_base;
1402
-	// Et le(s) dossier(s) des squelettes nommes
1403
-	if (strlen($GLOBALS['dossier_squelettes'])) {
1404
-		foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d) {
1405
-			array_unshift($path_full, ((isset($d[0]) and $d[0] == '/') ? '' : _DIR_RACINE) . $d . '/');
1406
-		}
1407
-	}
1408
-
1409
-	$GLOBALS['path_sig'] = md5(serialize($path_full));
1410
-
1411
-	return $path_full;
1349
+    static $path_base = null;
1350
+    static $path_full = null;
1351
+    if ($path_base == null) {
1352
+        // Chemin standard depuis l'espace public
1353
+        $path = defined('_SPIP_PATH') ? _SPIP_PATH :
1354
+            _DIR_RACINE . ':' .
1355
+            _DIR_RACINE . 'squelettes-dist/:' .
1356
+            _DIR_RACINE . 'prive/:' .
1357
+            _DIR_RESTREINT;
1358
+        // Ajouter squelettes/
1359
+        if (@is_dir(_DIR_RACINE . 'squelettes')) {
1360
+            $path = _DIR_RACINE . 'squelettes/:' . $path;
1361
+        }
1362
+        foreach (explode(':', $path) as $dir) {
1363
+            if (strlen($dir) and substr($dir, -1) != '/') {
1364
+                $dir .= '/';
1365
+            }
1366
+            $path_base[] = $dir;
1367
+        }
1368
+        $path_full = $path_base;
1369
+        // Et le(s) dossier(s) des squelettes nommes
1370
+        if (strlen($GLOBALS['dossier_squelettes'])) {
1371
+            foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d) {
1372
+                array_unshift($path_full, ($d[0] == '/' ? '' : _DIR_RACINE) . $d . '/');
1373
+            }
1374
+        }
1375
+        $GLOBALS['path_sig'] = md5(serialize($path_full));
1376
+    }
1377
+    if ($dir_path === null) {
1378
+        return $path_full;
1379
+    }
1380
+
1381
+    if (is_array($dir_path) or strlen($dir_path)) {
1382
+        $tete = '';
1383
+        if (reset($path_base) == _DIR_RACINE . 'squelettes/') {
1384
+            $tete = array_shift($path_base);
1385
+        }
1386
+        $dirs = (is_array($dir_path) ? $dir_path : explode(':', $dir_path));
1387
+        $dirs = array_reverse($dirs);
1388
+        foreach ($dirs as $dir_path) {
1389
+            if (substr($dir_path, -1) != '/') {
1390
+                $dir_path .= '/';
1391
+            }
1392
+            if (!in_array($dir_path, $path_base)) {
1393
+                array_unshift($path_base, $dir_path);
1394
+            }
1395
+        }
1396
+        if (strlen($tete)) {
1397
+            array_unshift($path_base, $tete);
1398
+        }
1399
+    }
1400
+    $path_full = $path_base;
1401
+    // Et le(s) dossier(s) des squelettes nommes
1402
+    if (strlen($GLOBALS['dossier_squelettes'])) {
1403
+        foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d) {
1404
+            array_unshift($path_full, ((isset($d[0]) and $d[0] == '/') ? '' : _DIR_RACINE) . $d . '/');
1405
+        }
1406
+    }
1407
+
1408
+    $GLOBALS['path_sig'] = md5(serialize($path_full));
1409
+
1410
+    return $path_full;
1412 1411
 }
1413 1412
 
1414 1413
 /**
@@ -1421,78 +1420,78 @@  discard block
 block discarded – undo
1421 1420
  * @return array Liste de chemins
1422 1421
  **/
1423 1422
 function creer_chemin() {
1424
-	$path_a = _chemin();
1425
-	static $c = '';
1423
+    $path_a = _chemin();
1424
+    static $c = '';
1426 1425
 
1427
-	// on calcule le chemin si le dossier skel a change
1428
-	if ($c != $GLOBALS['dossier_squelettes']) {
1429
-		// assurer le non plantage lors de la montee de version :
1430
-		$c = $GLOBALS['dossier_squelettes'];
1431
-		$path_a = _chemin(''); // forcer un recalcul du chemin
1432
-	}
1426
+    // on calcule le chemin si le dossier skel a change
1427
+    if ($c != $GLOBALS['dossier_squelettes']) {
1428
+        // assurer le non plantage lors de la montee de version :
1429
+        $c = $GLOBALS['dossier_squelettes'];
1430
+        $path_a = _chemin(''); // forcer un recalcul du chemin
1431
+    }
1433 1432
 
1434
-	return $path_a;
1433
+    return $path_a;
1435 1434
 }
1436 1435
 
1437 1436
 
1438 1437
 function lister_themes_prives() {
1439
-	static $themes = null;
1440
-	if (is_null($themes)) {
1441
-		// si pas encore definie
1442
-		if (!defined('_SPIP_THEME_PRIVE')) {
1443
-			define('_SPIP_THEME_PRIVE', 'spip');
1444
-		}
1445
-		$themes = [_SPIP_THEME_PRIVE];
1446
-		// lors d'une installation neuve, prefs n'est pas definie.
1447
-		if (isset($GLOBALS['visiteur_session']['prefs'])) {
1448
-			$prefs = $GLOBALS['visiteur_session']['prefs'];
1449
-		} else {
1450
-			$prefs = [];
1451
-		}
1452
-		if (is_string($prefs)) {
1453
-			$prefs = unserialize($GLOBALS['visiteur_session']['prefs']);
1454
-		}
1455
-		if (
1456
-			((isset($prefs['theme']) and $theme = $prefs['theme'])
1457
-				or (isset($GLOBALS['theme_prive_defaut']) and $theme = $GLOBALS['theme_prive_defaut']))
1458
-			and $theme != _SPIP_THEME_PRIVE
1459
-		) {
1460
-			array_unshift($themes, $theme);
1461
-		} // placer le theme choisi en tete
1462
-	}
1463
-
1464
-	return $themes;
1438
+    static $themes = null;
1439
+    if (is_null($themes)) {
1440
+        // si pas encore definie
1441
+        if (!defined('_SPIP_THEME_PRIVE')) {
1442
+            define('_SPIP_THEME_PRIVE', 'spip');
1443
+        }
1444
+        $themes = [_SPIP_THEME_PRIVE];
1445
+        // lors d'une installation neuve, prefs n'est pas definie.
1446
+        if (isset($GLOBALS['visiteur_session']['prefs'])) {
1447
+            $prefs = $GLOBALS['visiteur_session']['prefs'];
1448
+        } else {
1449
+            $prefs = [];
1450
+        }
1451
+        if (is_string($prefs)) {
1452
+            $prefs = unserialize($GLOBALS['visiteur_session']['prefs']);
1453
+        }
1454
+        if (
1455
+            ((isset($prefs['theme']) and $theme = $prefs['theme'])
1456
+                or (isset($GLOBALS['theme_prive_defaut']) and $theme = $GLOBALS['theme_prive_defaut']))
1457
+            and $theme != _SPIP_THEME_PRIVE
1458
+        ) {
1459
+            array_unshift($themes, $theme);
1460
+        } // placer le theme choisi en tete
1461
+    }
1462
+
1463
+    return $themes;
1465 1464
 }
1466 1465
 
1467 1466
 function find_in_theme($file, $subdir = '', $include = false) {
1468
-	static $themefiles = [];
1469
-	if (isset($themefiles["$subdir$file"])) {
1470
-		return $themefiles["$subdir$file"];
1471
-	}
1472
-	// on peut fournir une icone generique -xx.svg qui fera le job dans toutes les tailles, et qui est prioritaire sur le png
1473
-	// si il y a un .svg a la bonne taille (-16.svg) a cote, on l'utilise en remplacement du -16.png
1474
-	if (
1475
-		preg_match(',-(\d+)[.](png|gif|svg)$,', $file, $m)
1476
-		and $file_svg_generique = substr($file, 0, -strlen($m[0])) . '-xx.svg'
1477
-		and $f = find_in_theme("$file_svg_generique")
1478
-	) {
1479
-		if ($fsize = substr($f, 0, -6) . $m[1] . '.svg' and file_exists($fsize)) {
1480
-			return $themefiles["$subdir$file"] = $fsize;
1481
-		}
1482
-		else {
1483
-			return $themefiles["$subdir$file"] = "$f?" . $m[1] . 'px';
1484
-		}
1485
-	}
1486
-
1487
-	$themes = lister_themes_prives();
1488
-	foreach ($themes as $theme) {
1489
-		if ($f = find_in_path($file, "prive/themes/$theme/$subdir", $include)) {
1490
-			return $themefiles["$subdir$file"] = $f;
1491
-		}
1492
-	}
1493
-	spip_log("$file introuvable dans le theme prive " . reset($themes), 'theme');
1494
-
1495
-	return $themefiles["$subdir$file"] = '';
1467
+    static $themefiles = [];
1468
+    if (isset($themefiles["$subdir$file"])) {
1469
+        return $themefiles["$subdir$file"];
1470
+    }
1471
+    // on peut fournir une icone generique -xx.svg qui fera le job dans toutes les tailles, et qui est prioritaire sur le png
1472
+    // si il y a un .svg a la bonne taille (-16.svg) a cote, on l'utilise en remplacement du -16.png
1473
+    if (
1474
+        preg_match(',-(\d+)[.](png|gif|svg)$,', $file, $m)
1475
+        and $file_svg_generique = substr($file, 0, -strlen($m[0])) . '-xx.svg'
1476
+        and $f = find_in_theme("$file_svg_generique")
1477
+    ) {
1478
+        if ($fsize = substr($f, 0, -6) . $m[1] . '.svg' and file_exists($fsize)) {
1479
+            return $themefiles["$subdir$file"] = $fsize;
1480
+        }
1481
+        else {
1482
+            return $themefiles["$subdir$file"] = "$f?" . $m[1] . 'px';
1483
+        }
1484
+    }
1485
+
1486
+    $themes = lister_themes_prives();
1487
+    foreach ($themes as $theme) {
1488
+        if ($f = find_in_path($file, "prive/themes/$theme/$subdir", $include)) {
1489
+            return $themefiles["$subdir$file"] = $f;
1490
+        }
1491
+    }
1492
+    spip_log("$file introuvable dans le theme prive " . reset($themes), 'theme');
1493
+
1494
+    return $themefiles["$subdir$file"] = '';
1496 1495
 }
1497 1496
 
1498 1497
 
@@ -1516,31 +1515,31 @@  discard block
 block discarded – undo
1516 1515
  *     sinon chaîne vide.
1517 1516
  **/
1518 1517
 function chemin_image($icone) {
1519
-	static $icone_renommer;
1520
-	if ($p = strpos($icone, '?')) {
1521
-		$icone = substr($icone, 0, $p);
1522
-	}
1523
-	// gerer le cas d'un double appel en evitant de refaire le travail inutilement
1524
-	if (strpos($icone, '/') !== false and file_exists($icone)) {
1525
-		return $icone;
1526
-	}
1527
-
1528
-	// si c'est un nom d'image complet (article-24.png) essayer de le renvoyer direct
1529
-	if (preg_match(',[.](png|gif|jpg|webp|svg)$,', $icone) and $f = find_in_theme("images/$icone")) {
1530
-		return $f;
1531
-	}
1532
-	// sinon passer par le module de renommage
1533
-	if (is_null($icone_renommer)) {
1534
-		$icone_renommer = charger_fonction('icone_renommer', 'inc', true);
1535
-	}
1536
-	if ($icone_renommer) {
1537
-		[$icone, $fonction] = $icone_renommer($icone, '');
1538
-		if (file_exists($icone)) {
1539
-			return $icone;
1540
-		}
1541
-	}
1542
-
1543
-	return find_in_path($icone, _NOM_IMG_PACK);
1518
+    static $icone_renommer;
1519
+    if ($p = strpos($icone, '?')) {
1520
+        $icone = substr($icone, 0, $p);
1521
+    }
1522
+    // gerer le cas d'un double appel en evitant de refaire le travail inutilement
1523
+    if (strpos($icone, '/') !== false and file_exists($icone)) {
1524
+        return $icone;
1525
+    }
1526
+
1527
+    // si c'est un nom d'image complet (article-24.png) essayer de le renvoyer direct
1528
+    if (preg_match(',[.](png|gif|jpg|webp|svg)$,', $icone) and $f = find_in_theme("images/$icone")) {
1529
+        return $f;
1530
+    }
1531
+    // sinon passer par le module de renommage
1532
+    if (is_null($icone_renommer)) {
1533
+        $icone_renommer = charger_fonction('icone_renommer', 'inc', true);
1534
+    }
1535
+    if ($icone_renommer) {
1536
+        [$icone, $fonction] = $icone_renommer($icone, '');
1537
+        if (file_exists($icone)) {
1538
+            return $icone;
1539
+        }
1540
+    }
1541
+
1542
+    return find_in_path($icone, _NOM_IMG_PACK);
1544 1543
 }
1545 1544
 
1546 1545
 //
@@ -1578,128 +1577,128 @@  discard block
 block discarded – undo
1578 1577
  *     - false : fichier introuvable
1579 1578
  **/
1580 1579
 function find_in_path($file, $dirname = '', $include = false) {
1581
-	static $dirs = [];
1582
-	static $inc = []; # cf https://git.spip.net/spip/spip/commit/42e4e028e38c839121efaee84308d08aee307eec
1583
-	static $c = '';
1584
-
1585
-	if (!$file and !strlen($file)) {
1586
-		return false;
1587
-	}
1588
-
1589
-	// on calcule le chemin si le dossier skel a change
1590
-	if ($c != $GLOBALS['dossier_squelettes']) {
1591
-		// assurer le non plantage lors de la montee de version :
1592
-		$c = $GLOBALS['dossier_squelettes'];
1593
-		creer_chemin(); // forcer un recalcul du chemin et la mise a jour de path_sig
1594
-	}
1595
-
1596
-	if (isset($GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file])) {
1597
-		if (!$GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file]) {
1598
-			return false;
1599
-		}
1600
-		if ($include and !isset($inc[$dirname][$file])) {
1601
-			include_once _ROOT_CWD . $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
1602
-			$inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
1603
-		}
1604
-
1605
-		return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
1606
-	}
1607
-
1608
-	$a = strrpos($file, '/');
1609
-	if ($a !== false) {
1610
-		$dirname .= substr($file, 0, ++$a);
1611
-		$file = substr($file, $a);
1612
-	}
1613
-
1614
-	foreach (creer_chemin() as $dir) {
1615
-		if (!isset($dirs[$a = $dir . $dirname])) {
1616
-			$dirs[$a] = (is_dir(_ROOT_CWD . $a) || !$a);
1617
-		}
1618
-		if ($dirs[$a]) {
1619
-			if (file_exists(_ROOT_CWD . ($a .= $file))) {
1620
-				if ($include and !isset($inc[$dirname][$file])) {
1621
-					include_once _ROOT_CWD . $a;
1622
-					$inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
1623
-				}
1624
-				if (!defined('_SAUVER_CHEMIN')) {
1625
-					// si le chemin n'a pas encore ete charge, ne pas lever le flag, ne pas cacher
1626
-					if (is_null($GLOBALS['path_files'])) {
1627
-						return $a;
1628
-					}
1629
-					define('_SAUVER_CHEMIN', true);
1630
-				}
1631
-
1632
-				return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = $a;
1633
-			}
1634
-		}
1635
-	}
1636
-
1637
-	if ($include) {
1638
-		spip_log("include_spip $dirname$file non trouve");
1639
-		if ($include === 'required') {
1640
-			echo '<pre>',
1641
-			'<strong>Erreur Fatale</strong><br />';
1642
-			if (function_exists('debug_print_backtrace')) {
1643
-				echo debug_print_backtrace();
1644
-			}
1645
-			echo '</pre>';
1646
-			die("Erreur interne: ne peut inclure $dirname$file");
1647
-		}
1648
-	}
1649
-
1650
-	if (!defined('_SAUVER_CHEMIN')) {
1651
-		// si le chemin n'a pas encore ete charge, ne pas lever le flag, ne pas cacher
1652
-		if (is_null($GLOBALS['path_files'])) {
1653
-			return false;
1654
-		}
1655
-		define('_SAUVER_CHEMIN', true);
1656
-	}
1657
-
1658
-	return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = false;
1580
+    static $dirs = [];
1581
+    static $inc = []; # cf https://git.spip.net/spip/spip/commit/42e4e028e38c839121efaee84308d08aee307eec
1582
+    static $c = '';
1583
+
1584
+    if (!$file and !strlen($file)) {
1585
+        return false;
1586
+    }
1587
+
1588
+    // on calcule le chemin si le dossier skel a change
1589
+    if ($c != $GLOBALS['dossier_squelettes']) {
1590
+        // assurer le non plantage lors de la montee de version :
1591
+        $c = $GLOBALS['dossier_squelettes'];
1592
+        creer_chemin(); // forcer un recalcul du chemin et la mise a jour de path_sig
1593
+    }
1594
+
1595
+    if (isset($GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file])) {
1596
+        if (!$GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file]) {
1597
+            return false;
1598
+        }
1599
+        if ($include and !isset($inc[$dirname][$file])) {
1600
+            include_once _ROOT_CWD . $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
1601
+            $inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
1602
+        }
1603
+
1604
+        return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
1605
+    }
1606
+
1607
+    $a = strrpos($file, '/');
1608
+    if ($a !== false) {
1609
+        $dirname .= substr($file, 0, ++$a);
1610
+        $file = substr($file, $a);
1611
+    }
1612
+
1613
+    foreach (creer_chemin() as $dir) {
1614
+        if (!isset($dirs[$a = $dir . $dirname])) {
1615
+            $dirs[$a] = (is_dir(_ROOT_CWD . $a) || !$a);
1616
+        }
1617
+        if ($dirs[$a]) {
1618
+            if (file_exists(_ROOT_CWD . ($a .= $file))) {
1619
+                if ($include and !isset($inc[$dirname][$file])) {
1620
+                    include_once _ROOT_CWD . $a;
1621
+                    $inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
1622
+                }
1623
+                if (!defined('_SAUVER_CHEMIN')) {
1624
+                    // si le chemin n'a pas encore ete charge, ne pas lever le flag, ne pas cacher
1625
+                    if (is_null($GLOBALS['path_files'])) {
1626
+                        return $a;
1627
+                    }
1628
+                    define('_SAUVER_CHEMIN', true);
1629
+                }
1630
+
1631
+                return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = $a;
1632
+            }
1633
+        }
1634
+    }
1635
+
1636
+    if ($include) {
1637
+        spip_log("include_spip $dirname$file non trouve");
1638
+        if ($include === 'required') {
1639
+            echo '<pre>',
1640
+            '<strong>Erreur Fatale</strong><br />';
1641
+            if (function_exists('debug_print_backtrace')) {
1642
+                echo debug_print_backtrace();
1643
+            }
1644
+            echo '</pre>';
1645
+            die("Erreur interne: ne peut inclure $dirname$file");
1646
+        }
1647
+    }
1648
+
1649
+    if (!defined('_SAUVER_CHEMIN')) {
1650
+        // si le chemin n'a pas encore ete charge, ne pas lever le flag, ne pas cacher
1651
+        if (is_null($GLOBALS['path_files'])) {
1652
+            return false;
1653
+        }
1654
+        define('_SAUVER_CHEMIN', true);
1655
+    }
1656
+
1657
+    return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = false;
1659 1658
 }
1660 1659
 
1661 1660
 function clear_path_cache() {
1662
-	$GLOBALS['path_files'] = [];
1663
-	spip_unlink(_CACHE_CHEMIN);
1661
+    $GLOBALS['path_files'] = [];
1662
+    spip_unlink(_CACHE_CHEMIN);
1664 1663
 }
1665 1664
 
1666 1665
 function load_path_cache() {
1667
-	// charger le path des plugins
1668
-	if (@is_readable(_CACHE_PLUGINS_PATH)) {
1669
-		include_once(_CACHE_PLUGINS_PATH);
1670
-	}
1671
-	$GLOBALS['path_files'] = [];
1672
-	// si le visiteur est admin,
1673
-	// on ne recharge pas le cache pour forcer sa mise a jour
1674
-	if (
1675
-		// la session n'est pas encore chargee a ce moment, on ne peut donc pas s'y fier
1676
-		//AND (!isset($GLOBALS['visiteur_session']['statut']) OR $GLOBALS['visiteur_session']['statut']!='0minirezo')
1677
-		// utiliser le cookie est un pis aller qui marche 'en general'
1678
-		// on blinde par un second test au moment de la lecture de la session
1679
-		// !isset($_COOKIE[$GLOBALS['cookie_prefix'].'_admin'])
1680
-		// et en ignorant ce cache en cas de recalcul explicite
1681
-		!_request('var_mode')
1682
-	) {
1683
-		// on essaye de lire directement sans verrou pour aller plus vite
1684
-		if ($contenu = spip_file_get_contents(_CACHE_CHEMIN)) {
1685
-			// mais si semble corrompu on relit avec un verrou
1686
-			if (!$GLOBALS['path_files'] = unserialize($contenu)) {
1687
-				lire_fichier(_CACHE_CHEMIN, $contenu);
1688
-				if (!$GLOBALS['path_files'] = unserialize($contenu)) {
1689
-					$GLOBALS['path_files'] = [];
1690
-				}
1691
-			}
1692
-		}
1693
-	}
1666
+    // charger le path des plugins
1667
+    if (@is_readable(_CACHE_PLUGINS_PATH)) {
1668
+        include_once(_CACHE_PLUGINS_PATH);
1669
+    }
1670
+    $GLOBALS['path_files'] = [];
1671
+    // si le visiteur est admin,
1672
+    // on ne recharge pas le cache pour forcer sa mise a jour
1673
+    if (
1674
+        // la session n'est pas encore chargee a ce moment, on ne peut donc pas s'y fier
1675
+        //AND (!isset($GLOBALS['visiteur_session']['statut']) OR $GLOBALS['visiteur_session']['statut']!='0minirezo')
1676
+        // utiliser le cookie est un pis aller qui marche 'en general'
1677
+        // on blinde par un second test au moment de la lecture de la session
1678
+        // !isset($_COOKIE[$GLOBALS['cookie_prefix'].'_admin'])
1679
+        // et en ignorant ce cache en cas de recalcul explicite
1680
+        !_request('var_mode')
1681
+    ) {
1682
+        // on essaye de lire directement sans verrou pour aller plus vite
1683
+        if ($contenu = spip_file_get_contents(_CACHE_CHEMIN)) {
1684
+            // mais si semble corrompu on relit avec un verrou
1685
+            if (!$GLOBALS['path_files'] = unserialize($contenu)) {
1686
+                lire_fichier(_CACHE_CHEMIN, $contenu);
1687
+                if (!$GLOBALS['path_files'] = unserialize($contenu)) {
1688
+                    $GLOBALS['path_files'] = [];
1689
+                }
1690
+            }
1691
+        }
1692
+    }
1694 1693
 }
1695 1694
 
1696 1695
 function save_path_cache() {
1697
-	if (
1698
-		defined('_SAUVER_CHEMIN')
1699
-		and _SAUVER_CHEMIN
1700
-	) {
1701
-		ecrire_fichier(_CACHE_CHEMIN, serialize($GLOBALS['path_files']));
1702
-	}
1696
+    if (
1697
+        defined('_SAUVER_CHEMIN')
1698
+        and _SAUVER_CHEMIN
1699
+    ) {
1700
+        ecrire_fichier(_CACHE_CHEMIN, serialize($GLOBALS['path_files']));
1701
+    }
1703 1702
 }
1704 1703
 
1705 1704
 
@@ -1719,33 +1718,33 @@  discard block
 block discarded – undo
1719 1718
  * @return array
1720 1719
  */
1721 1720
 function find_all_in_path($dir, $pattern, $recurs = false) {
1722
-	$liste_fichiers = [];
1723
-	$maxfiles = 10000;
1724
-
1725
-	// cas borderline si dans mes_options on appelle redirige_par_entete qui utilise _T et charge un fichier de langue
1726
-	// on a pas encore inclus flock.php
1727
-	if (!function_exists('preg_files')) {
1728
-		include_once _ROOT_RESTREINT . 'inc/flock.php';
1729
-	}
1730
-
1731
-	// Parcourir le chemin
1732
-	foreach (creer_chemin() as $d) {
1733
-		$f = $d . $dir;
1734
-		if (@is_dir($f)) {
1735
-			$liste = preg_files($f, $pattern, $maxfiles - count($liste_fichiers), $recurs === true ? [] : $recurs);
1736
-			foreach ($liste as $chemin) {
1737
-				$nom = basename($chemin);
1738
-				// ne prendre que les fichiers pas deja trouves
1739
-				// car find_in_path prend le premier qu'il trouve,
1740
-				// les autres sont donc masques
1741
-				if (!isset($liste_fichiers[$nom])) {
1742
-					$liste_fichiers[$nom] = $chemin;
1743
-				}
1744
-			}
1745
-		}
1746
-	}
1747
-
1748
-	return $liste_fichiers;
1721
+    $liste_fichiers = [];
1722
+    $maxfiles = 10000;
1723
+
1724
+    // cas borderline si dans mes_options on appelle redirige_par_entete qui utilise _T et charge un fichier de langue
1725
+    // on a pas encore inclus flock.php
1726
+    if (!function_exists('preg_files')) {
1727
+        include_once _ROOT_RESTREINT . 'inc/flock.php';
1728
+    }
1729
+
1730
+    // Parcourir le chemin
1731
+    foreach (creer_chemin() as $d) {
1732
+        $f = $d . $dir;
1733
+        if (@is_dir($f)) {
1734
+            $liste = preg_files($f, $pattern, $maxfiles - count($liste_fichiers), $recurs === true ? [] : $recurs);
1735
+            foreach ($liste as $chemin) {
1736
+                $nom = basename($chemin);
1737
+                // ne prendre que les fichiers pas deja trouves
1738
+                // car find_in_path prend le premier qu'il trouve,
1739
+                // les autres sont donc masques
1740
+                if (!isset($liste_fichiers[$nom])) {
1741
+                    $liste_fichiers[$nom] = $chemin;
1742
+                }
1743
+            }
1744
+        }
1745
+    }
1746
+
1747
+    return $liste_fichiers;
1749 1748
 }
1750 1749
 
1751 1750
 /**
@@ -1757,17 +1756,17 @@  discard block
 block discarded – undo
1757 1756
  * @return bool
1758 1757
  */
1759 1758
 function autoriser_sans_cookie($nom, $strict = false) {
1760
-	static $autsanscookie = ['install', 'base_repair'];
1759
+    static $autsanscookie = ['install', 'base_repair'];
1761 1760
 
1762
-	if (in_array($nom, $autsanscookie)) {
1763
-		if (test_espace_prive()) {
1764
-			include_spip('base/connect_sql');
1765
-			if (!$strict or !spip_connect()) {
1766
-				return true;
1767
-			}
1768
-		}
1769
-	}
1770
-	return false;
1761
+    if (in_array($nom, $autsanscookie)) {
1762
+        if (test_espace_prive()) {
1763
+            include_spip('base/connect_sql');
1764
+            if (!$strict or !spip_connect()) {
1765
+                return true;
1766
+            }
1767
+        }
1768
+    }
1769
+    return false;
1771 1770
 }
1772 1771
 
1773 1772
 /**
@@ -1777,60 +1776,60 @@  discard block
 block discarded – undo
1777 1776
  * @return string
1778 1777
  */
1779 1778
 function charger_fonction_url(string $quoi, string $type = '') {
1780
-	if ($type === 'defaut') {
1781
-		$objet = objet_type($quoi);
1782
-		if (
1783
-			$f = charger_fonction('generer_' . $objet . '_url', 'urls', true)
1784
-			// deprecated
1785
-			or $f = charger_fonction('generer_url_' . $objet, 'urls', true)
1786
-		) {
1787
-			return $f;
1788
-		}
1789
-		return '';
1790
-	}
1791
-
1792
-	$url_type = $type;
1793
-	if (!$url_type) {
1794
-		$url_type = $GLOBALS['type_urls'] ?? $GLOBALS['meta']['type_urls'] ?? 'page'; // sinon type "page" par défaut
1795
-	}
1796
-
1797
-	// inclure le module d'url
1798
-	include_spip('urls/' . $url_type);
1799
-
1800
-	switch ($quoi) {
1801
-		case 'page':
1802
-			if (
1803
-				 function_exists($f = "urls_{$url_type}_generer_url_page")
1804
-				or function_exists($f .= '_dist')
1805
-				// ou une fonction custom utilisateur independante du type d'url
1806
-				or function_exists($f = 'generer_url_page')
1807
-				or function_exists($f .= '_dist')
1808
-			) {
1809
-				return $f;
1810
-			}
1811
-			// pas de compat ancienne version ici, c'est une nouvelle feature
1812
-			return '';
1813
-		case 'objet':
1814
-		case 'decoder':
1815
-		default:
1816
-			$fquoi = ($quoi === 'objet' ? 'generer_url_objet' : 'decoder_url');
1817
-			if (
1818
-				function_exists($f = "urls_{$url_type}_{$fquoi}")
1819
-				or function_exists($f .= '_dist')
1820
-			) {
1821
-				return $f;
1822
-			}
1823
-			// est-ce qu'on a une ancienne fonction urls_xxx_dist() ?
1824
-			// c'est un ancien module d'url, on appelle l'ancienne fonction qui fait tout
1825
-			if ($f = charger_fonction($url_type, 'urls', true)) {
1826
-				return $f;
1827
-			}
1828
-			// sinon on se rabat sur les urls page si ce n'est pas un type demande explicitement
1829
-			if (!$type and $url_type !== 'page') {
1830
-				return charger_fonction_url($quoi, 'page');
1831
-			}
1832
-			return '';
1833
-	}
1779
+    if ($type === 'defaut') {
1780
+        $objet = objet_type($quoi);
1781
+        if (
1782
+            $f = charger_fonction('generer_' . $objet . '_url', 'urls', true)
1783
+            // deprecated
1784
+            or $f = charger_fonction('generer_url_' . $objet, 'urls', true)
1785
+        ) {
1786
+            return $f;
1787
+        }
1788
+        return '';
1789
+    }
1790
+
1791
+    $url_type = $type;
1792
+    if (!$url_type) {
1793
+        $url_type = $GLOBALS['type_urls'] ?? $GLOBALS['meta']['type_urls'] ?? 'page'; // sinon type "page" par défaut
1794
+    }
1795
+
1796
+    // inclure le module d'url
1797
+    include_spip('urls/' . $url_type);
1798
+
1799
+    switch ($quoi) {
1800
+        case 'page':
1801
+            if (
1802
+                    function_exists($f = "urls_{$url_type}_generer_url_page")
1803
+                or function_exists($f .= '_dist')
1804
+                // ou une fonction custom utilisateur independante du type d'url
1805
+                or function_exists($f = 'generer_url_page')
1806
+                or function_exists($f .= '_dist')
1807
+            ) {
1808
+                return $f;
1809
+            }
1810
+            // pas de compat ancienne version ici, c'est une nouvelle feature
1811
+            return '';
1812
+        case 'objet':
1813
+        case 'decoder':
1814
+        default:
1815
+            $fquoi = ($quoi === 'objet' ? 'generer_url_objet' : 'decoder_url');
1816
+            if (
1817
+                function_exists($f = "urls_{$url_type}_{$fquoi}")
1818
+                or function_exists($f .= '_dist')
1819
+            ) {
1820
+                return $f;
1821
+            }
1822
+            // est-ce qu'on a une ancienne fonction urls_xxx_dist() ?
1823
+            // c'est un ancien module d'url, on appelle l'ancienne fonction qui fait tout
1824
+            if ($f = charger_fonction($url_type, 'urls', true)) {
1825
+                return $f;
1826
+            }
1827
+            // sinon on se rabat sur les urls page si ce n'est pas un type demande explicitement
1828
+            if (!$type and $url_type !== 'page') {
1829
+                return charger_fonction_url($quoi, 'page');
1830
+            }
1831
+            return '';
1832
+    }
1834 1833
 }
1835 1834
 
1836 1835
 
@@ -1859,48 +1858,48 @@  discard block
 block discarded – undo
1859 1858
  *           (cas des raccourcis personalises [->spip20] : il faut implementer une fonction generer_spip_url et une fonction generer_spip_url_ecrire)
1860 1859
  */
1861 1860
 function generer_objet_url($id, string $entite, string $args = '', string $ancre = '', ?bool $public = null, string $type = '', string $connect = ''): string {
1862
-	if ($public === null) {
1863
-		$public = !test_espace_prive();
1864
-	}
1865
-	$id = intval($id);
1866
-	$entite = objet_type($entite); // cas particulier d'appels sur objet/id_objet...
1867
-
1868
-	if (!$public) {
1869
-		if (!$entite) {
1870
-			return '';
1871
-		}
1872
-		if (!function_exists('generer_objet_url_ecrire')) {
1873
-			include_spip('inc/urls');
1874
-		}
1875
-		$res = generer_objet_url_ecrire($id, $entite, $args, $ancre, false, $connect);
1876
-	} else {
1877
-		$f = charger_fonction_url('objet', $type ?? '');
1878
-
1879
-		// @deprecated si $entite='', on veut la fonction de passage URL ==> id
1880
-		// @see charger_fonction_url
1881
-		if (!$entite) {
1882
-			return $f;
1883
-		}
1884
-
1885
-		// mais d'abord il faut tester le cas des urls sur une
1886
-		// base distante
1887
-		if (
1888
-			$connect
1889
-			and $g = charger_fonction('connect', 'urls', true)
1890
-		) {
1891
-			$f = $g;
1892
-		}
1893
-
1894
-		$res = $f(intval($id), $entite, $args ?: '', $ancre ?: '', $connect);
1895
-	}
1896
-	if ($res) {
1897
-		return $res;
1898
-	}
1899
-
1900
-	// On a ete gentil mais la ....
1901
-	spip_log("generer_objet_url: entite $entite ($f) inconnue $type $public $connect", _LOG_ERREUR);
1902
-
1903
-	return '';
1861
+    if ($public === null) {
1862
+        $public = !test_espace_prive();
1863
+    }
1864
+    $id = intval($id);
1865
+    $entite = objet_type($entite); // cas particulier d'appels sur objet/id_objet...
1866
+
1867
+    if (!$public) {
1868
+        if (!$entite) {
1869
+            return '';
1870
+        }
1871
+        if (!function_exists('generer_objet_url_ecrire')) {
1872
+            include_spip('inc/urls');
1873
+        }
1874
+        $res = generer_objet_url_ecrire($id, $entite, $args, $ancre, false, $connect);
1875
+    } else {
1876
+        $f = charger_fonction_url('objet', $type ?? '');
1877
+
1878
+        // @deprecated si $entite='', on veut la fonction de passage URL ==> id
1879
+        // @see charger_fonction_url
1880
+        if (!$entite) {
1881
+            return $f;
1882
+        }
1883
+
1884
+        // mais d'abord il faut tester le cas des urls sur une
1885
+        // base distante
1886
+        if (
1887
+            $connect
1888
+            and $g = charger_fonction('connect', 'urls', true)
1889
+        ) {
1890
+            $f = $g;
1891
+        }
1892
+
1893
+        $res = $f(intval($id), $entite, $args ?: '', $ancre ?: '', $connect);
1894
+    }
1895
+    if ($res) {
1896
+        return $res;
1897
+    }
1898
+
1899
+    // On a ete gentil mais la ....
1900
+    spip_log("generer_objet_url: entite $entite ($f) inconnue $type $public $connect", _LOG_ERREUR);
1901
+
1902
+    return '';
1904 1903
 }
1905 1904
 
1906 1905
 /**
@@ -1908,10 +1907,10 @@  discard block
 block discarded – undo
1908 1907
  * @see generer_objet_url
1909 1908
  */
1910 1909
 function generer_url_entite($id = 0, $entite = '', $args = '', $ancre = '', $public = null, $type = null) {
1911
-	if ($public and is_string($public)) {
1912
-		return generer_objet_url(intval($id), $entite, $args ?: '', $ancre ?: '', true, $type ?? '', $public);
1913
-	}
1914
-	return generer_objet_url(intval($id), $entite, $args ?: '', $ancre ?: '', $public, $type ?? '');
1910
+    if ($public and is_string($public)) {
1911
+        return generer_objet_url(intval($id), $entite, $args ?: '', $ancre ?: '', true, $type ?? '', $public);
1912
+    }
1913
+    return generer_objet_url(intval($id), $entite, $args ?: '', $ancre ?: '', $public, $type ?? '');
1915 1914
 }
1916 1915
 
1917 1916
 /**
@@ -1923,19 +1922,19 @@  discard block
 block discarded – undo
1923 1922
  * @return string
1924 1923
  */
1925 1924
 function generer_objet_url_ecrire_edit($id, string $entite, string $args = '', string $ancre = ''): string {
1926
-	$id = intval($id);
1927
-	$exec = objet_info($entite, 'url_edit');
1928
-	$url = generer_url_ecrire($exec, $args);
1929
-	if (intval($id)) {
1930
-		$url = parametre_url($url, id_table_objet($entite), $id);
1931
-	} else {
1932
-		$url = parametre_url($url, 'new', 'oui');
1933
-	}
1934
-	if ($ancre) {
1935
-		$url = ancre_url($url, $ancre);
1936
-	}
1925
+    $id = intval($id);
1926
+    $exec = objet_info($entite, 'url_edit');
1927
+    $url = generer_url_ecrire($exec, $args);
1928
+    if (intval($id)) {
1929
+        $url = parametre_url($url, id_table_objet($entite), $id);
1930
+    } else {
1931
+        $url = parametre_url($url, 'new', 'oui');
1932
+    }
1933
+    if ($ancre) {
1934
+        $url = ancre_url($url, $ancre);
1935
+    }
1937 1936
 
1938
-	return $url;
1937
+    return $url;
1939 1938
 }
1940 1939
 
1941 1940
 /**
@@ -1943,18 +1942,18 @@  discard block
 block discarded – undo
1943 1942
  * @see generer_objet_url_ecrire_edit
1944 1943
  */
1945 1944
 function generer_url_ecrire_entite_edit($id, $entite, $args = '', $ancre = '') {
1946
-	return generer_objet_url_ecrire_edit(intval($id), $entite, $args, $ancre);
1945
+    return generer_objet_url_ecrire_edit(intval($id), $entite, $args, $ancre);
1947 1946
 }
1948 1947
 
1949 1948
 
1950 1949
 function urls_connect_dist($i, &$entite, $args = '', $ancre = '', $public = null) {
1951
-	include_spip('base/connect_sql');
1952
-	$id_type = id_table_objet($entite, $public);
1950
+    include_spip('base/connect_sql');
1951
+    $id_type = id_table_objet($entite, $public);
1953 1952
 
1954
-	return _DIR_RACINE . get_spip_script('./')
1955
-	. '?' . _SPIP_PAGE . "=$entite&$id_type=$i&connect=$public"
1956
-	. (!$args ? '' : "&$args")
1957
-	. (!$ancre ? '' : "#$ancre");
1953
+    return _DIR_RACINE . get_spip_script('./')
1954
+    . '?' . _SPIP_PAGE . "=$entite&$id_type=$i&connect=$public"
1955
+    . (!$args ? '' : "&$args")
1956
+    . (!$ancre ? '' : "#$ancre");
1958 1957
 }
1959 1958
 
1960 1959
 
@@ -1965,18 +1964,18 @@  discard block
 block discarded – undo
1965 1964
  * @return string
1966 1965
  */
1967 1966
 function urlencode_1738($url) {
1968
-	if (preg_match(',[^\x00-\x7E],sS', $url)) {
1969
-		$uri = '';
1970
-		for ($i = 0; $i < strlen($url); $i++) {
1971
-			if (ord($a = $url[$i]) > 127) {
1972
-				$a = rawurlencode($a);
1973
-			}
1974
-			$uri .= $a;
1975
-		}
1976
-		$url = $uri;
1977
-	}
1967
+    if (preg_match(',[^\x00-\x7E],sS', $url)) {
1968
+        $uri = '';
1969
+        for ($i = 0; $i < strlen($url); $i++) {
1970
+            if (ord($a = $url[$i]) > 127) {
1971
+                $a = rawurlencode($a);
1972
+            }
1973
+            $uri .= $a;
1974
+        }
1975
+        $url = $uri;
1976
+    }
1978 1977
 
1979
-	return quote_amp($url);
1978
+    return quote_amp($url);
1980 1979
 }
1981 1980
 
1982 1981
 /**
@@ -1992,14 +1991,14 @@  discard block
 block discarded – undo
1992 1991
  * @return string
1993 1992
  */
1994 1993
 function generer_objet_url_absolue($id = 0, string $entite = '', string $args = '', string $ancre = '', ?bool $public = null, string $type = '', string $connect = ''): string {
1995
-	$id = intval($id);
1996
-	$h = generer_objet_url($id, $entite, $args, $ancre, $public, $type, $connect);
1997
-	if (!preg_match(',^\w+:,', $h)) {
1998
-		include_spip('inc/filtres_mini');
1999
-		$h = url_absolue($h);
2000
-	}
1994
+    $id = intval($id);
1995
+    $h = generer_objet_url($id, $entite, $args, $ancre, $public, $type, $connect);
1996
+    if (!preg_match(',^\w+:,', $h)) {
1997
+        include_spip('inc/filtres_mini');
1998
+        $h = url_absolue($h);
1999
+    }
2001 2000
 
2002
-	return $h;
2001
+    return $h;
2003 2002
 }
2004 2003
 
2005 2004
 /**
@@ -2007,7 +2006,7 @@  discard block
 block discarded – undo
2007 2006
  * @see  generer_objet_url_absolue
2008 2007
  */
2009 2008
 function generer_url_entite_absolue($id = 0, $entite = '', $args = '', $ancre = '', $connect = null) {
2010
-	return generer_objet_url_absolue(intval($id), $entite, $args, $ancre, true, '', $connect);
2009
+    return generer_objet_url_absolue(intval($id), $entite, $args, $ancre, true, '', $connect);
2011 2010
 }
2012 2011
 
2013 2012
 
@@ -2023,11 +2022,11 @@  discard block
 block discarded – undo
2023 2022
  *     true si la valeur est considérée active ; false sinon.
2024 2023
  **/
2025 2024
 function test_valeur_serveur($truc) {
2026
-	if (!$truc) {
2027
-		return false;
2028
-	}
2025
+    if (!$truc) {
2026
+        return false;
2027
+    }
2029 2028
 
2030
-	return (strtolower($truc) !== 'off');
2029
+    return (strtolower($truc) !== 'off');
2031 2030
 }
2032 2031
 
2033 2032
 //
@@ -2055,82 +2054,82 @@  discard block
 block discarded – undo
2055 2054
  */
2056 2055
 function url_de_base($profondeur = null) {
2057 2056
 
2058
-	static $url = [];
2059
-	if (is_array($profondeur)) {
2060
-		return $url = $profondeur;
2061
-	}
2062
-	if ($profondeur === false) {
2063
-		return $url;
2064
-	}
2065
-
2066
-	if (is_null($profondeur)) {
2067
-		$profondeur = $GLOBALS['profondeur_url'] ?? (_DIR_RESTREINT ? 0 : 1);
2068
-	}
2069
-
2070
-	if (isset($url[$profondeur])) {
2071
-		return $url[$profondeur];
2072
-	}
2073
-
2074
-	$http = 'http';
2075
-
2076
-	if (
2077
-		isset($_SERVER['SCRIPT_URI'])
2078
-		and substr($_SERVER['SCRIPT_URI'], 0, 5) == 'https'
2079
-	) {
2080
-		$http = 'https';
2081
-	} elseif (
2082
-		isset($_SERVER['HTTPS'])
2083
-		and test_valeur_serveur($_SERVER['HTTPS'])
2084
-	) {
2085
-		$http = 'https';
2086
-	}
2087
-
2088
-	// note : HTTP_HOST contient le :port si necessaire
2089
-	$host = $_SERVER['HTTP_HOST'] ?? null;
2090
-	// si on n'a pas trouvé d'hôte du tout, en dernier recours on utilise adresse_site comme fallback
2091
-	if (is_null($host) and isset($GLOBALS['meta']['adresse_site'])) {
2092
-		$host = $GLOBALS['meta']['adresse_site'];
2093
-		if ($scheme = parse_url($host, PHP_URL_SCHEME)) {
2094
-			$http = $scheme;
2095
-			$host = str_replace("{$scheme}://", '', $host);
2096
-		}
2097
-	}
2098
-	if (
2099
-		isset($_SERVER['SERVER_PORT'])
2100
-		and $port = $_SERVER['SERVER_PORT']
2101
-		and strpos($host, ':') == false
2102
-	) {
2103
-		if (!defined('_PORT_HTTP_STANDARD')) {
2104
-			define('_PORT_HTTP_STANDARD', '80');
2105
-		}
2106
-		if (!defined('_PORT_HTTPS_STANDARD')) {
2107
-			define('_PORT_HTTPS_STANDARD', '443');
2108
-		}
2109
-		if ($http == 'http' and !in_array($port, explode(',', _PORT_HTTP_STANDARD))) {
2110
-			$host .= ":$port";
2111
-		}
2112
-		if ($http == 'https' and !in_array($port, explode(',', _PORT_HTTPS_STANDARD))) {
2113
-			$host .= ":$port";
2114
-		}
2115
-	}
2116
-
2117
-	if (!$GLOBALS['REQUEST_URI']) {
2118
-		if (isset($_SERVER['REQUEST_URI'])) {
2119
-			$GLOBALS['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
2120
-		} else {
2121
-			$GLOBALS['REQUEST_URI'] = (php_sapi_name() !== 'cli') ? $_SERVER['PHP_SELF'] : '';
2122
-			if (
2123
-				!empty($_SERVER['QUERY_STRING'])
2124
-				and !strpos($_SERVER['REQUEST_URI'], '?')
2125
-			) {
2126
-				$GLOBALS['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
2127
-			}
2128
-		}
2129
-	}
2130
-
2131
-	$url[$profondeur] = url_de_($http, $host, $GLOBALS['REQUEST_URI'], $profondeur);
2132
-
2133
-	return $url[$profondeur];
2057
+    static $url = [];
2058
+    if (is_array($profondeur)) {
2059
+        return $url = $profondeur;
2060
+    }
2061
+    if ($profondeur === false) {
2062
+        return $url;
2063
+    }
2064
+
2065
+    if (is_null($profondeur)) {
2066
+        $profondeur = $GLOBALS['profondeur_url'] ?? (_DIR_RESTREINT ? 0 : 1);
2067
+    }
2068
+
2069
+    if (isset($url[$profondeur])) {
2070
+        return $url[$profondeur];
2071
+    }
2072
+
2073
+    $http = 'http';
2074
+
2075
+    if (
2076
+        isset($_SERVER['SCRIPT_URI'])
2077
+        and substr($_SERVER['SCRIPT_URI'], 0, 5) == 'https'
2078
+    ) {
2079
+        $http = 'https';
2080
+    } elseif (
2081
+        isset($_SERVER['HTTPS'])
2082
+        and test_valeur_serveur($_SERVER['HTTPS'])
2083
+    ) {
2084
+        $http = 'https';
2085
+    }
2086
+
2087
+    // note : HTTP_HOST contient le :port si necessaire
2088
+    $host = $_SERVER['HTTP_HOST'] ?? null;
2089
+    // si on n'a pas trouvé d'hôte du tout, en dernier recours on utilise adresse_site comme fallback
2090
+    if (is_null($host) and isset($GLOBALS['meta']['adresse_site'])) {
2091
+        $host = $GLOBALS['meta']['adresse_site'];
2092
+        if ($scheme = parse_url($host, PHP_URL_SCHEME)) {
2093
+            $http = $scheme;
2094
+            $host = str_replace("{$scheme}://", '', $host);
2095
+        }
2096
+    }
2097
+    if (
2098
+        isset($_SERVER['SERVER_PORT'])
2099
+        and $port = $_SERVER['SERVER_PORT']
2100
+        and strpos($host, ':') == false
2101
+    ) {
2102
+        if (!defined('_PORT_HTTP_STANDARD')) {
2103
+            define('_PORT_HTTP_STANDARD', '80');
2104
+        }
2105
+        if (!defined('_PORT_HTTPS_STANDARD')) {
2106
+            define('_PORT_HTTPS_STANDARD', '443');
2107
+        }
2108
+        if ($http == 'http' and !in_array($port, explode(',', _PORT_HTTP_STANDARD))) {
2109
+            $host .= ":$port";
2110
+        }
2111
+        if ($http == 'https' and !in_array($port, explode(',', _PORT_HTTPS_STANDARD))) {
2112
+            $host .= ":$port";
2113
+        }
2114
+    }
2115
+
2116
+    if (!$GLOBALS['REQUEST_URI']) {
2117
+        if (isset($_SERVER['REQUEST_URI'])) {
2118
+            $GLOBALS['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
2119
+        } else {
2120
+            $GLOBALS['REQUEST_URI'] = (php_sapi_name() !== 'cli') ? $_SERVER['PHP_SELF'] : '';
2121
+            if (
2122
+                !empty($_SERVER['QUERY_STRING'])
2123
+                and !strpos($_SERVER['REQUEST_URI'], '?')
2124
+            ) {
2125
+                $GLOBALS['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
2126
+            }
2127
+        }
2128
+    }
2129
+
2130
+    $url[$profondeur] = url_de_($http, $host, $GLOBALS['REQUEST_URI'], $profondeur);
2131
+
2132
+    return $url[$profondeur];
2134 2133
 }
2135 2134
 
2136 2135
 /**
@@ -2143,26 +2142,26 @@  discard block
 block discarded – undo
2143 2142
  * @return string
2144 2143
  */
2145 2144
 function url_de_($http, $host, $request, $prof = 0) {
2146
-	$prof = max($prof, 0);
2145
+    $prof = max($prof, 0);
2147 2146
 
2148
-	$myself = ltrim($request, '/');
2149
-	# supprimer la chaine de GET
2150
-	[$myself] = explode('?', $myself);
2151
-	// vieux mode HTTP qui envoie après le nom de la methode l'URL compléte
2152
-	// protocole, "://", nom du serveur avant le path dans _SERVER["REQUEST_URI"]
2153
-	if (strpos($myself, '://') !== false) {
2154
-		$myself = explode('://', $myself);
2155
-		array_shift($myself);
2156
-		$myself = implode('://', $myself);
2157
-		$myself = explode('/', $myself);
2158
-		array_shift($myself);
2159
-		$myself = implode('/', $myself);
2160
-	}
2161
-	$url = join('/', array_slice(explode('/', $myself), 0, -1 - $prof)) . '/';
2147
+    $myself = ltrim($request, '/');
2148
+    # supprimer la chaine de GET
2149
+    [$myself] = explode('?', $myself);
2150
+    // vieux mode HTTP qui envoie après le nom de la methode l'URL compléte
2151
+    // protocole, "://", nom du serveur avant le path dans _SERVER["REQUEST_URI"]
2152
+    if (strpos($myself, '://') !== false) {
2153
+        $myself = explode('://', $myself);
2154
+        array_shift($myself);
2155
+        $myself = implode('://', $myself);
2156
+        $myself = explode('/', $myself);
2157
+        array_shift($myself);
2158
+        $myself = implode('/', $myself);
2159
+    }
2160
+    $url = join('/', array_slice(explode('/', $myself), 0, -1 - $prof)) . '/';
2162 2161
 
2163
-	$url = $http . '://' . rtrim($host, '/') . '/' . ltrim($url, '/');
2162
+    $url = $http . '://' . rtrim($host, '/') . '/' . ltrim($url, '/');
2164 2163
 
2165
-	return $url;
2164
+    return $url;
2166 2165
 }
2167 2166
 
2168 2167
 
@@ -2197,26 +2196,26 @@  discard block
 block discarded – undo
2197 2196
  * @return string URL
2198 2197
  **/
2199 2198
 function generer_url_ecrire(?string $script = '', $args = '', $no_entities = false, $rel = false) {
2200
-	$script ??= '';
2201
-	if (!$rel) {
2202
-		$rel = url_de_base() . _DIR_RESTREINT_ABS . _SPIP_ECRIRE_SCRIPT;
2203
-	} else {
2204
-		if (!is_string($rel)) {
2205
-			$rel = _DIR_RESTREINT ?: './' . _SPIP_ECRIRE_SCRIPT;
2206
-		}
2207
-	}
2208
-
2209
-	[$script, $ancre] = array_pad(explode('#', $script), 2, null);
2210
-	if ($script and ($script <> 'accueil' or $rel)) {
2211
-		$args = "?exec=$script" . (!$args ? '' : "&$args");
2212
-	} elseif ($args) {
2213
-		$args = "?$args";
2214
-	}
2215
-	if ($ancre) {
2216
-		$args .= "#$ancre";
2217
-	}
2218
-
2219
-	return $rel . ($no_entities ? $args : str_replace('&', '&amp;', $args));
2199
+    $script ??= '';
2200
+    if (!$rel) {
2201
+        $rel = url_de_base() . _DIR_RESTREINT_ABS . _SPIP_ECRIRE_SCRIPT;
2202
+    } else {
2203
+        if (!is_string($rel)) {
2204
+            $rel = _DIR_RESTREINT ?: './' . _SPIP_ECRIRE_SCRIPT;
2205
+        }
2206
+    }
2207
+
2208
+    [$script, $ancre] = array_pad(explode('#', $script), 2, null);
2209
+    if ($script and ($script <> 'accueil' or $rel)) {
2210
+        $args = "?exec=$script" . (!$args ? '' : "&$args");
2211
+    } elseif ($args) {
2212
+        $args = "?$args";
2213
+    }
2214
+    if ($ancre) {
2215
+        $args .= "#$ancre";
2216
+    }
2217
+
2218
+    return $rel . ($no_entities ? $args : str_replace('&', '&amp;', $args));
2220 2219
 }
2221 2220
 
2222 2221
 //
@@ -2238,15 +2237,15 @@  discard block
 block discarded – undo
2238 2237
  *     Nom du fichier (constante _SPIP_SCRIPT), sinon nom par défaut
2239 2238
  **/
2240 2239
 function get_spip_script($default = '') {
2241
-	if (!defined('_SPIP_SCRIPT')) {
2242
-		return 'spip.php';
2243
-	}
2244
-	# cas define('_SPIP_SCRIPT', '');
2245
-	if (_SPIP_SCRIPT) {
2246
-		return _SPIP_SCRIPT;
2247
-	} else {
2248
-		return $default;
2249
-	}
2240
+    if (!defined('_SPIP_SCRIPT')) {
2241
+        return 'spip.php';
2242
+    }
2243
+    # cas define('_SPIP_SCRIPT', '');
2244
+    if (_SPIP_SCRIPT) {
2245
+        return _SPIP_SCRIPT;
2246
+    } else {
2247
+        return $default;
2248
+    }
2250 2249
 }
2251 2250
 
2252 2251
 /**
@@ -2275,45 +2274,45 @@  discard block
 block discarded – undo
2275 2274
  * @return string URL
2276 2275
  **/
2277 2276
 function generer_url_public($script = '', $args = '', $no_entities = false, $rel = true, $action = '') {
2278
-	// si le script est une action (spip_pass, spip_inscription),
2279
-	// standardiser vers la nouvelle API
2280
-
2281
-	if (is_array($args)) {
2282
-		$args = http_build_query($args);
2283
-	}
2284
-
2285
-	$url = '';
2286
-	if ($f = charger_fonction_url('page')) {
2287
-		$url = $f($script, $args);
2288
-		if ($url and !$rel) {
2289
-			include_spip('inc/filtres_mini');
2290
-			$url = url_absolue($url);
2291
-		}
2292
-	}
2293
-	if (!$url) {
2294
-		if (!$action) {
2295
-			$action = get_spip_script();
2296
-		}
2297
-		if ($script) {
2298
-			$action = parametre_url($action, _SPIP_PAGE, $script, '&');
2299
-		}
2300
-		if ($args) {
2301
-			$action .= (strpos($action, '?') !== false ? '&' : '?') . $args;
2302
-		}
2303
-		// ne pas generer une url avec /./?page= en cas d'url absolue et de _SPIP_SCRIPT vide
2304
-		$url = ($rel ? _DIR_RACINE . $action : rtrim(url_de_base(), '/') . preg_replace(',^/[.]/,', '/', "/$action"));
2305
-	}
2306
-
2307
-	if (!$no_entities) {
2308
-		$url = quote_amp($url);
2309
-	}
2310
-
2311
-	return $url;
2277
+    // si le script est une action (spip_pass, spip_inscription),
2278
+    // standardiser vers la nouvelle API
2279
+
2280
+    if (is_array($args)) {
2281
+        $args = http_build_query($args);
2282
+    }
2283
+
2284
+    $url = '';
2285
+    if ($f = charger_fonction_url('page')) {
2286
+        $url = $f($script, $args);
2287
+        if ($url and !$rel) {
2288
+            include_spip('inc/filtres_mini');
2289
+            $url = url_absolue($url);
2290
+        }
2291
+    }
2292
+    if (!$url) {
2293
+        if (!$action) {
2294
+            $action = get_spip_script();
2295
+        }
2296
+        if ($script) {
2297
+            $action = parametre_url($action, _SPIP_PAGE, $script, '&');
2298
+        }
2299
+        if ($args) {
2300
+            $action .= (strpos($action, '?') !== false ? '&' : '?') . $args;
2301
+        }
2302
+        // ne pas generer une url avec /./?page= en cas d'url absolue et de _SPIP_SCRIPT vide
2303
+        $url = ($rel ? _DIR_RACINE . $action : rtrim(url_de_base(), '/') . preg_replace(',^/[.]/,', '/', "/$action"));
2304
+    }
2305
+
2306
+    if (!$no_entities) {
2307
+        $url = quote_amp($url);
2308
+    }
2309
+
2310
+    return $url;
2312 2311
 }
2313 2312
 
2314 2313
 function generer_url_prive($script, $args = '', $no_entities = false) {
2315 2314
 
2316
-	return generer_url_public($script, $args, $no_entities, false, _DIR_RESTREINT_ABS . 'prive.php');
2315
+    return generer_url_public($script, $args, $no_entities, false, _DIR_RESTREINT_ABS . 'prive.php');
2317 2316
 }
2318 2317
 
2319 2318
 // Pour les formulaires en methode POST,
@@ -2338,19 +2337,19 @@  discard block
 block discarded – undo
2338 2337
  **/
2339 2338
 function generer_form_ecrire($script, $corps, $atts = '', $submit = '') {
2340 2339
 
2341
-	$script1 = explode('&', $script);
2342
-	$script1 = reset($script1);
2340
+    $script1 = explode('&', $script);
2341
+    $script1 = reset($script1);
2343 2342
 
2344
-	return "<form action='"
2345
-	. ($script ? generer_url_ecrire($script) : '')
2346
-	. "' "
2347
-	. ($atts ?: " method='post'")
2348
-	. "><div>\n"
2349
-	. "<input type='hidden' name='exec' value='$script1' />"
2350
-	. $corps
2351
-	. (!$submit ? '' :
2352
-		("<div style='text-align: " . $GLOBALS['spip_lang_right'] . "'><input class='fondo submit btn' type='submit' value=\"" . entites_html($submit) . '" /></div>'))
2353
-	. "</div></form>\n";
2343
+    return "<form action='"
2344
+    . ($script ? generer_url_ecrire($script) : '')
2345
+    . "' "
2346
+    . ($atts ?: " method='post'")
2347
+    . "><div>\n"
2348
+    . "<input type='hidden' name='exec' value='$script1' />"
2349
+    . $corps
2350
+    . (!$submit ? '' :
2351
+        ("<div style='text-align: " . $GLOBALS['spip_lang_right'] . "'><input class='fondo submit btn' type='submit' value=\"" . entites_html($submit) . '" /></div>'))
2352
+    . "</div></form>\n";
2354 2353
 }
2355 2354
 
2356 2355
 /**
@@ -2367,22 +2366,22 @@  discard block
 block discarded – undo
2367 2366
  * @return string
2368 2367
  */
2369 2368
 function generer_form_action($script, $corps, $atts = '', $public = false) {
2370
-	// si l'on est dans l'espace prive, on garde dans l'url
2371
-	// l'exec a l'origine de l'action, qui permet de savoir si il est necessaire
2372
-	// ou non de proceder a l'authentification (cas typique de l'install par exemple)
2373
-	$h = (_DIR_RACINE and !$public)
2374
-		? generer_url_ecrire(_request('exec'))
2375
-		: generer_url_public();
2369
+    // si l'on est dans l'espace prive, on garde dans l'url
2370
+    // l'exec a l'origine de l'action, qui permet de savoir si il est necessaire
2371
+    // ou non de proceder a l'authentification (cas typique de l'install par exemple)
2372
+    $h = (_DIR_RACINE and !$public)
2373
+        ? generer_url_ecrire(_request('exec'))
2374
+        : generer_url_public();
2376 2375
 
2377
-	return "\n<form action='" .
2378
-	$h .
2379
-	"'" .
2380
-	$atts .
2381
-	">\n" .
2382
-	'<div>' .
2383
-	"\n<input type='hidden' name='action' value='$script' />" .
2384
-	$corps .
2385
-	'</div></form>';
2376
+    return "\n<form action='" .
2377
+    $h .
2378
+    "'" .
2379
+    $atts .
2380
+    ">\n" .
2381
+    '<div>' .
2382
+    "\n<input type='hidden' name='action' value='$script' />" .
2383
+    $corps .
2384
+    '</div></form>';
2386 2385
 }
2387 2386
 
2388 2387
 /**
@@ -2401,22 +2400,22 @@  discard block
 block discarded – undo
2401 2400
  *     URL
2402 2401
  */
2403 2402
 function generer_url_action($script, $args = '', $no_entities = false, $public = false) {
2404
-	// si l'on est dans l'espace prive, on garde dans l'url
2405
-	// l'exec a l'origine de l'action, qui permet de savoir si il est necessaire
2406
-	// ou non de proceder a l'authentification (cas typique de l'install par exemple)
2407
-	$url = (_DIR_RACINE and !$public)
2408
-		? generer_url_ecrire(_request('exec'))
2409
-		: generer_url_public('', '', false, false);
2410
-	$url = parametre_url($url, 'action', $script);
2411
-	if ($args) {
2412
-		$url .= quote_amp('&' . $args);
2413
-	}
2403
+    // si l'on est dans l'espace prive, on garde dans l'url
2404
+    // l'exec a l'origine de l'action, qui permet de savoir si il est necessaire
2405
+    // ou non de proceder a l'authentification (cas typique de l'install par exemple)
2406
+    $url = (_DIR_RACINE and !$public)
2407
+        ? generer_url_ecrire(_request('exec'))
2408
+        : generer_url_public('', '', false, false);
2409
+    $url = parametre_url($url, 'action', $script);
2410
+    if ($args) {
2411
+        $url .= quote_amp('&' . $args);
2412
+    }
2414 2413
 
2415
-	if ($no_entities) {
2416
-		$url = str_replace('&amp;', '&', $url);
2417
-	}
2414
+    if ($no_entities) {
2415
+        $url = str_replace('&amp;', '&', $url);
2416
+    }
2418 2417
 
2419
-	return $url;
2418
+    return $url;
2420 2419
 }
2421 2420
 
2422 2421
 
@@ -2435,23 +2434,23 @@  discard block
 block discarded – undo
2435 2434
  *     URL
2436 2435
  */
2437 2436
 function generer_url_api(string $script, string $path, string $args, bool $no_entities = false, ?bool $public = null) {
2438
-	if (is_null($public)) {
2439
-		$public = (_DIR_RACINE ? false : '');
2440
-	}
2441
-	if (substr($script, -4) !== '.api') {
2442
-		$script .= '.api';
2443
-	}
2444
-	$url =
2445
-		(($public ? _DIR_RACINE : _DIR_RESTREINT) ?: './')
2446
-	. $script . '/'
2447
-	. ($path ? trim($path, '/') : '')
2448
-	. ($args ? '?' . quote_amp($args) : '');
2437
+    if (is_null($public)) {
2438
+        $public = (_DIR_RACINE ? false : '');
2439
+    }
2440
+    if (substr($script, -4) !== '.api') {
2441
+        $script .= '.api';
2442
+    }
2443
+    $url =
2444
+        (($public ? _DIR_RACINE : _DIR_RESTREINT) ?: './')
2445
+    . $script . '/'
2446
+    . ($path ? trim($path, '/') : '')
2447
+    . ($args ? '?' . quote_amp($args) : '');
2449 2448
 
2450
-	if ($no_entities) {
2451
-		$url = str_replace('&amp;', '&', $url);
2452
-	}
2449
+    if ($no_entities) {
2450
+        $url = str_replace('&amp;', '&', $url);
2451
+    }
2453 2452
 
2454
-	return $url;
2453
+    return $url;
2455 2454
 }
2456 2455
 
2457 2456
 
@@ -2464,8 +2463,8 @@  discard block
 block discarded – undo
2464 2463
  * @param string $ta Répertoire temporaire accessible
2465 2464
  */
2466 2465
 function spip_initialisation($pi = null, $pa = null, $ti = null, $ta = null) {
2467
-	spip_initialisation_core($pi, $pa, $ti, $ta);
2468
-	spip_initialisation_suite();
2466
+    spip_initialisation_core($pi, $pa, $ti, $ta);
2467
+    spip_initialisation_suite();
2469 2468
 }
2470 2469
 
2471 2470
 /**
@@ -2485,322 +2484,322 @@  discard block
 block discarded – undo
2485 2484
  * @param string $ta Répertoire temporaire accessible
2486 2485
  */
2487 2486
 function spip_initialisation_core($pi = null, $pa = null, $ti = null, $ta = null) {
2488
-	static $too_late = 0;
2489
-	if ($too_late++) {
2490
-		return;
2491
-	}
2492
-
2493
-	// Declaration des repertoires
2494
-
2495
-	// le nom du repertoire plugins/ activables/desactivables
2496
-	if (!defined('_DIR_PLUGINS')) {
2497
-		define('_DIR_PLUGINS', _DIR_RACINE . 'plugins/');
2498
-	}
2499
-
2500
-	// le nom du repertoire des extensions/ permanentes du core, toujours actives
2501
-	if (!defined('_DIR_PLUGINS_DIST')) {
2502
-		define('_DIR_PLUGINS_DIST', _DIR_RACINE . 'plugins-dist/');
2503
-	}
2504
-
2505
-	// le nom du repertoire des librairies
2506
-	if (!defined('_DIR_LIB')) {
2507
-		define('_DIR_LIB', _DIR_RACINE . 'lib/');
2508
-	}
2509
-
2510
-	if (!defined('_DIR_IMG')) {
2511
-		define('_DIR_IMG', $pa);
2512
-	}
2513
-	if (!defined('_DIR_LOGOS')) {
2514
-		define('_DIR_LOGOS', $pa);
2515
-	}
2516
-	if (!defined('_DIR_IMG_ICONES')) {
2517
-		define('_DIR_IMG_ICONES', _DIR_LOGOS . 'icones/');
2518
-	}
2519
-
2520
-	if (!defined('_DIR_DUMP')) {
2521
-		define('_DIR_DUMP', $ti . 'dump/');
2522
-	}
2523
-	if (!defined('_DIR_SESSIONS')) {
2524
-		define('_DIR_SESSIONS', $ti . 'sessions/');
2525
-	}
2526
-	if (!defined('_DIR_TRANSFERT')) {
2527
-		define('_DIR_TRANSFERT', $ti . 'upload/');
2528
-	}
2529
-	if (!defined('_DIR_CACHE')) {
2530
-		define('_DIR_CACHE', $ti . 'cache/');
2531
-	}
2532
-	if (!defined('_DIR_CACHE_XML')) {
2533
-		define('_DIR_CACHE_XML', _DIR_CACHE . 'xml/');
2534
-	}
2535
-	if (!defined('_DIR_SKELS')) {
2536
-		define('_DIR_SKELS', _DIR_CACHE . 'skel/');
2537
-	}
2538
-	if (!defined('_DIR_AIDE')) {
2539
-		define('_DIR_AIDE', _DIR_CACHE . 'aide/');
2540
-	}
2541
-	if (!defined('_DIR_TMP')) {
2542
-		define('_DIR_TMP', $ti);
2543
-	}
2544
-
2545
-	if (!defined('_DIR_VAR')) {
2546
-		define('_DIR_VAR', $ta);
2547
-	}
2548
-
2549
-	if (!defined('_DIR_ETC')) {
2550
-		define('_DIR_ETC', $pi);
2551
-	}
2552
-	if (!defined('_DIR_CONNECT')) {
2553
-		define('_DIR_CONNECT', $pi);
2554
-	}
2555
-	if (!defined('_DIR_CHMOD')) {
2556
-		define('_DIR_CHMOD', $pi);
2557
-	}
2558
-
2559
-	if (!isset($GLOBALS['test_dirs'])) {
2560
-		// Pas $pi car il est bon de le mettre hors ecriture apres intstall
2561
-		// il sera rajoute automatiquement si besoin a l'etape 2 de l'install
2562
-	$GLOBALS['test_dirs'] = [$pa, $ti, $ta];
2563
-	}
2564
-
2565
-	// Declaration des fichiers
2566
-
2567
-	if (!defined('_CACHE_PLUGINS_PATH')) {
2568
-		define('_CACHE_PLUGINS_PATH', _DIR_CACHE . 'charger_plugins_chemins.php');
2569
-	}
2570
-	if (!defined('_CACHE_PLUGINS_OPT')) {
2571
-		define('_CACHE_PLUGINS_OPT', _DIR_CACHE . 'charger_plugins_options.php');
2572
-	}
2573
-	if (!defined('_CACHE_PLUGINS_FCT')) {
2574
-		define('_CACHE_PLUGINS_FCT', _DIR_CACHE . 'charger_plugins_fonctions.php');
2575
-	}
2576
-	if (!defined('_CACHE_PIPELINES')) {
2577
-		define('_CACHE_PIPELINES', _DIR_CACHE . 'charger_pipelines.php');
2578
-	}
2579
-	if (!defined('_CACHE_CHEMIN')) {
2580
-		define('_CACHE_CHEMIN', _DIR_CACHE . 'chemin.txt');
2581
-	}
2582
-
2583
-	# attention .php obligatoire pour ecrire_fichier_securise
2584
-	if (!defined('_FILE_META')) {
2585
-		define('_FILE_META', $ti . 'meta_cache.php');
2586
-	}
2587
-	if (!defined('_DIR_LOG')) {
2588
-		define('_DIR_LOG', _DIR_TMP . 'log/');
2589
-	}
2590
-	if (!defined('_FILE_LOG')) {
2591
-		define('_FILE_LOG', 'spip');
2592
-	}
2593
-	if (!defined('_FILE_LOG_SUFFIX')) {
2594
-		define('_FILE_LOG_SUFFIX', '.log');
2595
-	}
2596
-
2597
-	// Le fichier de connexion a la base de donnees
2598
-	// tient compte des anciennes versions (inc_connect...)
2599
-	if (!defined('_FILE_CONNECT_INS')) {
2600
-		define('_FILE_CONNECT_INS', 'connect');
2601
-	}
2602
-	if (!defined('_FILE_CONNECT')) {
2603
-		define(
2604
-			'_FILE_CONNECT',
2605
-			(@is_readable($f = _DIR_CONNECT . _FILE_CONNECT_INS . '.php') ? $f
2606
-			: (@is_readable($f = _DIR_RESTREINT . 'inc_connect.php') ? $f
2607
-			: false))
2608
-		);
2609
-	}
2610
-
2611
-	// Le fichier de reglages des droits
2612
-	if (!defined('_FILE_CHMOD_INS')) {
2613
-		define('_FILE_CHMOD_INS', 'chmod');
2614
-	}
2615
-	if (!defined('_FILE_CHMOD')) {
2616
-		define(
2617
-			'_FILE_CHMOD',
2618
-			(@is_readable($f = _DIR_CHMOD . _FILE_CHMOD_INS . '.php') ? $f
2619
-			: false)
2620
-		);
2621
-	}
2622
-
2623
-	if (!defined('_FILE_LDAP')) {
2624
-		define('_FILE_LDAP', 'ldap.php');
2625
-	}
2626
-
2627
-	if (!defined('_FILE_TMP_SUFFIX')) {
2628
-		define('_FILE_TMP_SUFFIX', '.tmp.php');
2629
-	}
2630
-	if (!defined('_FILE_CONNECT_TMP')) {
2631
-		define('_FILE_CONNECT_TMP', _DIR_CONNECT . _FILE_CONNECT_INS . _FILE_TMP_SUFFIX);
2632
-	}
2633
-	if (!defined('_FILE_CHMOD_TMP')) {
2634
-		define('_FILE_CHMOD_TMP', _DIR_CHMOD . _FILE_CHMOD_INS . _FILE_TMP_SUFFIX);
2635
-	}
2636
-
2637
-	// Definition des droits d'acces en ecriture
2638
-	if (!defined('_SPIP_CHMOD') and _FILE_CHMOD) {
2639
-		include_once _FILE_CHMOD;
2640
-	}
2641
-
2642
-	// Se mefier des fichiers mal remplis!
2643
-	if (!defined('_SPIP_CHMOD')) {
2644
-		define('_SPIP_CHMOD', 0777);
2645
-	}
2646
-
2647
-	if (!defined('_DEFAULT_CHARSET')) {
2648
-		/** Le charset par défaut lors de l'installation */
2649
-		define('_DEFAULT_CHARSET', 'utf-8');
2650
-	}
2651
-	if (!defined('_ROOT_PLUGINS')) {
2652
-		define('_ROOT_PLUGINS', _ROOT_RACINE . 'plugins/');
2653
-	}
2654
-	if (!defined('_ROOT_PLUGINS_DIST')) {
2655
-		define('_ROOT_PLUGINS_DIST', _ROOT_RACINE . 'plugins-dist/');
2656
-	}
2657
-	if (!defined('_ROOT_PLUGINS_SUPPL') && defined('_DIR_PLUGINS_SUPPL') && _DIR_PLUGINS_SUPPL) {
2658
-		define('_ROOT_PLUGINS_SUPPL', _ROOT_RACINE . str_replace(_DIR_RACINE, '', _DIR_PLUGINS_SUPPL));
2659
-	}
2660
-
2661
-	// La taille des Log
2662
-	if (!defined('_MAX_LOG')) {
2663
-		define('_MAX_LOG', 100);
2664
-	}
2665
-
2666
-	// Sommes-nous dans l'empire du Mal ?
2667
-	// (ou sous le signe du Pingouin, ascendant GNU ?)
2668
-	if (isset($_SERVER['SERVER_SOFTWARE']) and strpos($_SERVER['SERVER_SOFTWARE'], '(Win') !== false) {
2669
-		if (!defined('_OS_SERVEUR')) {
2670
-			define('_OS_SERVEUR', 'windows');
2671
-		}
2672
-		if (!defined('_SPIP_LOCK_MODE')) {
2673
-			define('_SPIP_LOCK_MODE', 1);
2674
-		} // utiliser le flock php
2675
-	} else {
2676
-		if (!defined('_OS_SERVEUR')) {
2677
-			define('_OS_SERVEUR', '');
2678
-		}
2679
-		if (!defined('_SPIP_LOCK_MODE')) {
2680
-			define('_SPIP_LOCK_MODE', 1);
2681
-		} // utiliser le flock php
2682
-		#if (!defined('_SPIP_LOCK_MODE')) define('_SPIP_LOCK_MODE',2); // utiliser le nfslock de spip mais link() est tres souvent interdite
2683
-	}
2684
-
2685
-	// Langue par defaut
2686
-	if (!defined('_LANGUE_PAR_DEFAUT')) {
2687
-		define('_LANGUE_PAR_DEFAUT', 'fr');
2688
-	}
2689
-
2690
-	//
2691
-	// Module de lecture/ecriture/suppression de fichiers utilisant flock()
2692
-	// (non surchargeable en l'etat ; attention si on utilise include_spip()
2693
-	// pour le rendre surchargeable, on va provoquer un reecriture
2694
-	// systematique du noyau ou une baisse de perfs => a etudier)
2695
-	include_once _ROOT_RESTREINT . 'inc/flock.php';
2696
-
2697
-	// charger tout de suite le path et son cache
2698
-	load_path_cache();
2699
-
2700
-	// *********** traiter les variables ************
2701
-
2702
-	//
2703
-	// Securite
2704
-	//
2705
-
2706
-	// Ne pas se faire manger par un bug php qui accepte ?GLOBALS[truc]=toto
2707
-	if (isset($_REQUEST['GLOBALS'])) {
2708
-		die();
2709
-	}
2710
-	// nettoyer les magic quotes \' et les caracteres nuls %00
2711
-	spip_desinfecte($_GET);
2712
-	spip_desinfecte($_POST);
2713
-	spip_desinfecte($_COOKIE);
2714
-	spip_desinfecte($_REQUEST);
2715
-
2716
-	// appliquer le cookie_prefix
2717
-	if ($GLOBALS['cookie_prefix'] != 'spip') {
2718
-		include_spip('inc/cookie');
2719
-		recuperer_cookies_spip($GLOBALS['cookie_prefix']);
2720
-	}
2721
-
2722
-	//
2723
-	// Capacites php (en fonction de la version)
2724
-	//
2725
-	$GLOBALS['flag_ob'] = (function_exists('ob_start')
2726
-		&& function_exists('ini_get')
2727
-		&& !strstr(@ini_get('disable_functions'), 'ob_'));
2728
-	$GLOBALS['flag_sapi_name'] = function_exists('php_sapi_name');
2729
-	$GLOBALS['flag_get_cfg_var'] = (@get_cfg_var('error_reporting') != '');
2730
-	$GLOBALS['flag_upload'] = (!$GLOBALS['flag_get_cfg_var'] ||
2731
-		(get_cfg_var('upload_max_filesize') > 0));
2732
-
2733
-
2734
-	// Compatibilite avec serveurs ne fournissant pas $REQUEST_URI
2735
-	if (isset($_SERVER['REQUEST_URI'])) {
2736
-		$GLOBALS['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
2737
-	} else {
2738
-		$GLOBALS['REQUEST_URI'] = (php_sapi_name() !== 'cli') ? $_SERVER['PHP_SELF'] : '';
2739
-		if (
2740
-			!empty($_SERVER['QUERY_STRING'])
2741
-			and !strpos($_SERVER['REQUEST_URI'], '?')
2742
-		) {
2743
-			$GLOBALS['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
2744
-		}
2745
-	}
2746
-
2747
-	// Duree de validite de l'alea pour les cookies et ce qui s'ensuit.
2748
-	if (!defined('_RENOUVELLE_ALEA')) {
2749
-		define('_RENOUVELLE_ALEA', 12 * 3600);
2750
-	}
2751
-	if (!defined('_DUREE_COOKIE_ADMIN')) {
2752
-		define('_DUREE_COOKIE_ADMIN', 14 * 24 * 3600);
2753
-	}
2754
-
2755
-	// charger les meta si possible et renouveller l'alea au besoin
2756
-	// charge aussi effacer_meta et ecrire_meta
2757
-	$inc_meta = charger_fonction('meta', 'inc');
2758
-	$inc_meta();
2759
-
2760
-	// nombre de repertoires depuis la racine
2761
-	// on compare a l'adresse de spip.php : $_SERVER["SCRIPT_NAME"]
2762
-	// ou a defaut celle donnee en meta ; (mais si celle-ci est fausse
2763
-	// le calcul est faux)
2764
-	if (!_DIR_RESTREINT) {
2765
-		$GLOBALS['profondeur_url'] = 1;
2766
-	} else {
2767
-		$uri = isset($_SERVER['REQUEST_URI']) ? explode('?', $_SERVER['REQUEST_URI']) : '';
2768
-		$uri_ref = $_SERVER['SCRIPT_NAME'];
2769
-		if (
2770
-			!$uri_ref
2771
-			// si on est appele avec un autre ti, on est sans doute en mutu
2772
-			// si jamais c'est de la mutu avec sous rep, on est perdu si on se fie
2773
-			// a spip.php qui est a la racine du spip, et vue qu'on sait pas se reperer
2774
-			// s'en remettre a l'adresse du site. alea jacta est.
2775
-			or $ti !== _NOM_TEMPORAIRES_INACCESSIBLES
2776
-		) {
2777
-			if (isset($GLOBALS['meta']['adresse_site'])) {
2778
-				$uri_ref = parse_url($GLOBALS['meta']['adresse_site']);
2779
-				$uri_ref = ($uri_ref['path'] ?? '') . '/';
2780
-			} else {
2781
-				$uri_ref = '';
2782
-			}
2783
-		}
2784
-		if (!$uri or !$uri_ref) {
2785
-			$GLOBALS['profondeur_url'] = 0;
2786
-		} else {
2787
-			$GLOBALS['profondeur_url'] = max(
2788
-				0,
2789
-				substr_count($uri[0], '/')
2790
-				- substr_count($uri_ref, '/')
2791
-			);
2792
-		}
2793
-	}
2794
-	// s'il y a un cookie ou PHP_AUTH, initialiser visiteur_session
2795
-	if (_FILE_CONNECT) {
2796
-		if (
2797
-			verifier_visiteur() == '0minirezo'
2798
-			// si c'est un admin sans cookie admin, il faut ignorer le cache chemin !
2799
-			and !isset($_COOKIE['spip_admin'])
2800
-		) {
2801
-			clear_path_cache();
2802
-		}
2803
-	}
2487
+    static $too_late = 0;
2488
+    if ($too_late++) {
2489
+        return;
2490
+    }
2491
+
2492
+    // Declaration des repertoires
2493
+
2494
+    // le nom du repertoire plugins/ activables/desactivables
2495
+    if (!defined('_DIR_PLUGINS')) {
2496
+        define('_DIR_PLUGINS', _DIR_RACINE . 'plugins/');
2497
+    }
2498
+
2499
+    // le nom du repertoire des extensions/ permanentes du core, toujours actives
2500
+    if (!defined('_DIR_PLUGINS_DIST')) {
2501
+        define('_DIR_PLUGINS_DIST', _DIR_RACINE . 'plugins-dist/');
2502
+    }
2503
+
2504
+    // le nom du repertoire des librairies
2505
+    if (!defined('_DIR_LIB')) {
2506
+        define('_DIR_LIB', _DIR_RACINE . 'lib/');
2507
+    }
2508
+
2509
+    if (!defined('_DIR_IMG')) {
2510
+        define('_DIR_IMG', $pa);
2511
+    }
2512
+    if (!defined('_DIR_LOGOS')) {
2513
+        define('_DIR_LOGOS', $pa);
2514
+    }
2515
+    if (!defined('_DIR_IMG_ICONES')) {
2516
+        define('_DIR_IMG_ICONES', _DIR_LOGOS . 'icones/');
2517
+    }
2518
+
2519
+    if (!defined('_DIR_DUMP')) {
2520
+        define('_DIR_DUMP', $ti . 'dump/');
2521
+    }
2522
+    if (!defined('_DIR_SESSIONS')) {
2523
+        define('_DIR_SESSIONS', $ti . 'sessions/');
2524
+    }
2525
+    if (!defined('_DIR_TRANSFERT')) {
2526
+        define('_DIR_TRANSFERT', $ti . 'upload/');
2527
+    }
2528
+    if (!defined('_DIR_CACHE')) {
2529
+        define('_DIR_CACHE', $ti . 'cache/');
2530
+    }
2531
+    if (!defined('_DIR_CACHE_XML')) {
2532
+        define('_DIR_CACHE_XML', _DIR_CACHE . 'xml/');
2533
+    }
2534
+    if (!defined('_DIR_SKELS')) {
2535
+        define('_DIR_SKELS', _DIR_CACHE . 'skel/');
2536
+    }
2537
+    if (!defined('_DIR_AIDE')) {
2538
+        define('_DIR_AIDE', _DIR_CACHE . 'aide/');
2539
+    }
2540
+    if (!defined('_DIR_TMP')) {
2541
+        define('_DIR_TMP', $ti);
2542
+    }
2543
+
2544
+    if (!defined('_DIR_VAR')) {
2545
+        define('_DIR_VAR', $ta);
2546
+    }
2547
+
2548
+    if (!defined('_DIR_ETC')) {
2549
+        define('_DIR_ETC', $pi);
2550
+    }
2551
+    if (!defined('_DIR_CONNECT')) {
2552
+        define('_DIR_CONNECT', $pi);
2553
+    }
2554
+    if (!defined('_DIR_CHMOD')) {
2555
+        define('_DIR_CHMOD', $pi);
2556
+    }
2557
+
2558
+    if (!isset($GLOBALS['test_dirs'])) {
2559
+        // Pas $pi car il est bon de le mettre hors ecriture apres intstall
2560
+        // il sera rajoute automatiquement si besoin a l'etape 2 de l'install
2561
+    $GLOBALS['test_dirs'] = [$pa, $ti, $ta];
2562
+    }
2563
+
2564
+    // Declaration des fichiers
2565
+
2566
+    if (!defined('_CACHE_PLUGINS_PATH')) {
2567
+        define('_CACHE_PLUGINS_PATH', _DIR_CACHE . 'charger_plugins_chemins.php');
2568
+    }
2569
+    if (!defined('_CACHE_PLUGINS_OPT')) {
2570
+        define('_CACHE_PLUGINS_OPT', _DIR_CACHE . 'charger_plugins_options.php');
2571
+    }
2572
+    if (!defined('_CACHE_PLUGINS_FCT')) {
2573
+        define('_CACHE_PLUGINS_FCT', _DIR_CACHE . 'charger_plugins_fonctions.php');
2574
+    }
2575
+    if (!defined('_CACHE_PIPELINES')) {
2576
+        define('_CACHE_PIPELINES', _DIR_CACHE . 'charger_pipelines.php');
2577
+    }
2578
+    if (!defined('_CACHE_CHEMIN')) {
2579
+        define('_CACHE_CHEMIN', _DIR_CACHE . 'chemin.txt');
2580
+    }
2581
+
2582
+    # attention .php obligatoire pour ecrire_fichier_securise
2583
+    if (!defined('_FILE_META')) {
2584
+        define('_FILE_META', $ti . 'meta_cache.php');
2585
+    }
2586
+    if (!defined('_DIR_LOG')) {
2587
+        define('_DIR_LOG', _DIR_TMP . 'log/');
2588
+    }
2589
+    if (!defined('_FILE_LOG')) {
2590
+        define('_FILE_LOG', 'spip');
2591
+    }
2592
+    if (!defined('_FILE_LOG_SUFFIX')) {
2593
+        define('_FILE_LOG_SUFFIX', '.log');
2594
+    }
2595
+
2596
+    // Le fichier de connexion a la base de donnees
2597
+    // tient compte des anciennes versions (inc_connect...)
2598
+    if (!defined('_FILE_CONNECT_INS')) {
2599
+        define('_FILE_CONNECT_INS', 'connect');
2600
+    }
2601
+    if (!defined('_FILE_CONNECT')) {
2602
+        define(
2603
+            '_FILE_CONNECT',
2604
+            (@is_readable($f = _DIR_CONNECT . _FILE_CONNECT_INS . '.php') ? $f
2605
+            : (@is_readable($f = _DIR_RESTREINT . 'inc_connect.php') ? $f
2606
+            : false))
2607
+        );
2608
+    }
2609
+
2610
+    // Le fichier de reglages des droits
2611
+    if (!defined('_FILE_CHMOD_INS')) {
2612
+        define('_FILE_CHMOD_INS', 'chmod');
2613
+    }
2614
+    if (!defined('_FILE_CHMOD')) {
2615
+        define(
2616
+            '_FILE_CHMOD',
2617
+            (@is_readable($f = _DIR_CHMOD . _FILE_CHMOD_INS . '.php') ? $f
2618
+            : false)
2619
+        );
2620
+    }
2621
+
2622
+    if (!defined('_FILE_LDAP')) {
2623
+        define('_FILE_LDAP', 'ldap.php');
2624
+    }
2625
+
2626
+    if (!defined('_FILE_TMP_SUFFIX')) {
2627
+        define('_FILE_TMP_SUFFIX', '.tmp.php');
2628
+    }
2629
+    if (!defined('_FILE_CONNECT_TMP')) {
2630
+        define('_FILE_CONNECT_TMP', _DIR_CONNECT . _FILE_CONNECT_INS . _FILE_TMP_SUFFIX);
2631
+    }
2632
+    if (!defined('_FILE_CHMOD_TMP')) {
2633
+        define('_FILE_CHMOD_TMP', _DIR_CHMOD . _FILE_CHMOD_INS . _FILE_TMP_SUFFIX);
2634
+    }
2635
+
2636
+    // Definition des droits d'acces en ecriture
2637
+    if (!defined('_SPIP_CHMOD') and _FILE_CHMOD) {
2638
+        include_once _FILE_CHMOD;
2639
+    }
2640
+
2641
+    // Se mefier des fichiers mal remplis!
2642
+    if (!defined('_SPIP_CHMOD')) {
2643
+        define('_SPIP_CHMOD', 0777);
2644
+    }
2645
+
2646
+    if (!defined('_DEFAULT_CHARSET')) {
2647
+        /** Le charset par défaut lors de l'installation */
2648
+        define('_DEFAULT_CHARSET', 'utf-8');
2649
+    }
2650
+    if (!defined('_ROOT_PLUGINS')) {
2651
+        define('_ROOT_PLUGINS', _ROOT_RACINE . 'plugins/');
2652
+    }
2653
+    if (!defined('_ROOT_PLUGINS_DIST')) {
2654
+        define('_ROOT_PLUGINS_DIST', _ROOT_RACINE . 'plugins-dist/');
2655
+    }
2656
+    if (!defined('_ROOT_PLUGINS_SUPPL') && defined('_DIR_PLUGINS_SUPPL') && _DIR_PLUGINS_SUPPL) {
2657
+        define('_ROOT_PLUGINS_SUPPL', _ROOT_RACINE . str_replace(_DIR_RACINE, '', _DIR_PLUGINS_SUPPL));
2658
+    }
2659
+
2660
+    // La taille des Log
2661
+    if (!defined('_MAX_LOG')) {
2662
+        define('_MAX_LOG', 100);
2663
+    }
2664
+
2665
+    // Sommes-nous dans l'empire du Mal ?
2666
+    // (ou sous le signe du Pingouin, ascendant GNU ?)
2667
+    if (isset($_SERVER['SERVER_SOFTWARE']) and strpos($_SERVER['SERVER_SOFTWARE'], '(Win') !== false) {
2668
+        if (!defined('_OS_SERVEUR')) {
2669
+            define('_OS_SERVEUR', 'windows');
2670
+        }
2671
+        if (!defined('_SPIP_LOCK_MODE')) {
2672
+            define('_SPIP_LOCK_MODE', 1);
2673
+        } // utiliser le flock php
2674
+    } else {
2675
+        if (!defined('_OS_SERVEUR')) {
2676
+            define('_OS_SERVEUR', '');
2677
+        }
2678
+        if (!defined('_SPIP_LOCK_MODE')) {
2679
+            define('_SPIP_LOCK_MODE', 1);
2680
+        } // utiliser le flock php
2681
+        #if (!defined('_SPIP_LOCK_MODE')) define('_SPIP_LOCK_MODE',2); // utiliser le nfslock de spip mais link() est tres souvent interdite
2682
+    }
2683
+
2684
+    // Langue par defaut
2685
+    if (!defined('_LANGUE_PAR_DEFAUT')) {
2686
+        define('_LANGUE_PAR_DEFAUT', 'fr');
2687
+    }
2688
+
2689
+    //
2690
+    // Module de lecture/ecriture/suppression de fichiers utilisant flock()
2691
+    // (non surchargeable en l'etat ; attention si on utilise include_spip()
2692
+    // pour le rendre surchargeable, on va provoquer un reecriture
2693
+    // systematique du noyau ou une baisse de perfs => a etudier)
2694
+    include_once _ROOT_RESTREINT . 'inc/flock.php';
2695
+
2696
+    // charger tout de suite le path et son cache
2697
+    load_path_cache();
2698
+
2699
+    // *********** traiter les variables ************
2700
+
2701
+    //
2702
+    // Securite
2703
+    //
2704
+
2705
+    // Ne pas se faire manger par un bug php qui accepte ?GLOBALS[truc]=toto
2706
+    if (isset($_REQUEST['GLOBALS'])) {
2707
+        die();
2708
+    }
2709
+    // nettoyer les magic quotes \' et les caracteres nuls %00
2710
+    spip_desinfecte($_GET);
2711
+    spip_desinfecte($_POST);
2712
+    spip_desinfecte($_COOKIE);
2713
+    spip_desinfecte($_REQUEST);
2714
+
2715
+    // appliquer le cookie_prefix
2716
+    if ($GLOBALS['cookie_prefix'] != 'spip') {
2717
+        include_spip('inc/cookie');
2718
+        recuperer_cookies_spip($GLOBALS['cookie_prefix']);
2719
+    }
2720
+
2721
+    //
2722
+    // Capacites php (en fonction de la version)
2723
+    //
2724
+    $GLOBALS['flag_ob'] = (function_exists('ob_start')
2725
+        && function_exists('ini_get')
2726
+        && !strstr(@ini_get('disable_functions'), 'ob_'));
2727
+    $GLOBALS['flag_sapi_name'] = function_exists('php_sapi_name');
2728
+    $GLOBALS['flag_get_cfg_var'] = (@get_cfg_var('error_reporting') != '');
2729
+    $GLOBALS['flag_upload'] = (!$GLOBALS['flag_get_cfg_var'] ||
2730
+        (get_cfg_var('upload_max_filesize') > 0));
2731
+
2732
+
2733
+    // Compatibilite avec serveurs ne fournissant pas $REQUEST_URI
2734
+    if (isset($_SERVER['REQUEST_URI'])) {
2735
+        $GLOBALS['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
2736
+    } else {
2737
+        $GLOBALS['REQUEST_URI'] = (php_sapi_name() !== 'cli') ? $_SERVER['PHP_SELF'] : '';
2738
+        if (
2739
+            !empty($_SERVER['QUERY_STRING'])
2740
+            and !strpos($_SERVER['REQUEST_URI'], '?')
2741
+        ) {
2742
+            $GLOBALS['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
2743
+        }
2744
+    }
2745
+
2746
+    // Duree de validite de l'alea pour les cookies et ce qui s'ensuit.
2747
+    if (!defined('_RENOUVELLE_ALEA')) {
2748
+        define('_RENOUVELLE_ALEA', 12 * 3600);
2749
+    }
2750
+    if (!defined('_DUREE_COOKIE_ADMIN')) {
2751
+        define('_DUREE_COOKIE_ADMIN', 14 * 24 * 3600);
2752
+    }
2753
+
2754
+    // charger les meta si possible et renouveller l'alea au besoin
2755
+    // charge aussi effacer_meta et ecrire_meta
2756
+    $inc_meta = charger_fonction('meta', 'inc');
2757
+    $inc_meta();
2758
+
2759
+    // nombre de repertoires depuis la racine
2760
+    // on compare a l'adresse de spip.php : $_SERVER["SCRIPT_NAME"]
2761
+    // ou a defaut celle donnee en meta ; (mais si celle-ci est fausse
2762
+    // le calcul est faux)
2763
+    if (!_DIR_RESTREINT) {
2764
+        $GLOBALS['profondeur_url'] = 1;
2765
+    } else {
2766
+        $uri = isset($_SERVER['REQUEST_URI']) ? explode('?', $_SERVER['REQUEST_URI']) : '';
2767
+        $uri_ref = $_SERVER['SCRIPT_NAME'];
2768
+        if (
2769
+            !$uri_ref
2770
+            // si on est appele avec un autre ti, on est sans doute en mutu
2771
+            // si jamais c'est de la mutu avec sous rep, on est perdu si on se fie
2772
+            // a spip.php qui est a la racine du spip, et vue qu'on sait pas se reperer
2773
+            // s'en remettre a l'adresse du site. alea jacta est.
2774
+            or $ti !== _NOM_TEMPORAIRES_INACCESSIBLES
2775
+        ) {
2776
+            if (isset($GLOBALS['meta']['adresse_site'])) {
2777
+                $uri_ref = parse_url($GLOBALS['meta']['adresse_site']);
2778
+                $uri_ref = ($uri_ref['path'] ?? '') . '/';
2779
+            } else {
2780
+                $uri_ref = '';
2781
+            }
2782
+        }
2783
+        if (!$uri or !$uri_ref) {
2784
+            $GLOBALS['profondeur_url'] = 0;
2785
+        } else {
2786
+            $GLOBALS['profondeur_url'] = max(
2787
+                0,
2788
+                substr_count($uri[0], '/')
2789
+                - substr_count($uri_ref, '/')
2790
+            );
2791
+        }
2792
+    }
2793
+    // s'il y a un cookie ou PHP_AUTH, initialiser visiteur_session
2794
+    if (_FILE_CONNECT) {
2795
+        if (
2796
+            verifier_visiteur() == '0minirezo'
2797
+            // si c'est un admin sans cookie admin, il faut ignorer le cache chemin !
2798
+            and !isset($_COOKIE['spip_admin'])
2799
+        ) {
2800
+            clear_path_cache();
2801
+        }
2802
+    }
2804 2803
 }
2805 2804
 
2806 2805
 /**
@@ -2809,157 +2808,157 @@  discard block
 block discarded – undo
2809 2808
  *
2810 2809
  */
2811 2810
 function spip_initialisation_suite() {
2812
-	static $too_late = 0;
2813
-	if ($too_late++) {
2814
-		return;
2815
-	}
2816
-
2817
-	// taille mini des login
2818
-	if (!defined('_LOGIN_TROP_COURT')) {
2819
-		define('_LOGIN_TROP_COURT', 4);
2820
-	}
2821
-
2822
-	// la taille maxi des logos (0 : pas de limite) (pas de define par defaut, ce n'est pas utile)
2823
-	#if (!defined('_LOGO_MAX_SIZE')) define('_LOGO_MAX_SIZE', 0); # poids en ko
2824
-	#if (!defined('_LOGO_MAX_WIDTH')) define('_LOGO_MAX_WIDTH', 0); # largeur en pixels
2825
-	#if (!defined('_LOGO_MAX_HEIGHT')) define('_LOGO_MAX_HEIGHT', 0); # hauteur en pixels
2826
-
2827
-	// la taille maxi des images (0 : pas de limite) (pas de define par defaut, ce n'est pas utile)
2828
-	#if (!defined('_DOC_MAX_SIZE')) define('_DOC_MAX_SIZE', 0); # poids en ko
2829
-	#if (!defined('_IMG_MAX_SIZE')) define('_IMG_MAX_SIZE', 0); # poids en ko
2830
-	#if (!defined('_IMG_MAX_WIDTH')) define('_IMG_MAX_WIDTH', 0); # largeur en pixels
2831
-	#if (!defined('_IMG_MAX_HEIGHT')) define('_IMG_MAX_HEIGHT', 0); # hauteur en pixels
2832
-
2833
-	if (!defined('_PASS_LONGUEUR_MINI')) {
2834
-		define('_PASS_LONGUEUR_MINI', 6);
2835
-	}
2836
-
2837
-	// largeur maximale des images dans l'administration
2838
-	if (!defined('_IMG_ADMIN_MAX_WIDTH')) {
2839
-		define('_IMG_ADMIN_MAX_WIDTH', 768);
2840
-	}
2841
-
2842
-	// Qualite des images calculees automatiquement. C'est un nombre entre 0 et 100, meme pour imagick (on ramene a 0..1 par la suite)
2843
-	if (!defined('_IMG_QUALITE')) {
2844
-		define('_IMG_QUALITE', 85);
2845
-	} # valeur par defaut
2846
-	if (!defined('_IMG_GD_QUALITE')) {
2847
-		define('_IMG_GD_QUALITE', _IMG_QUALITE);
2848
-	} # surcharge pour la lib GD
2849
-	if (!defined('_IMG_CONVERT_QUALITE')) {
2850
-		define('_IMG_CONVERT_QUALITE', _IMG_QUALITE);
2851
-	} # surcharge pour imagick en ligne de commande
2852
-	// Historiquement la valeur pour imagick semble differente. Si ca n'est pas necessaire, il serait preferable de garder _IMG_QUALITE
2853
-	if (!defined('_IMG_IMAGICK_QUALITE')) {
2854
-		define('_IMG_IMAGICK_QUALITE', 75);
2855
-	} # surcharge pour imagick en PHP
2856
-
2857
-	if (!defined('_COPIE_LOCALE_MAX_SIZE')) {
2858
-		define('_COPIE_LOCALE_MAX_SIZE', 33_554_432);
2859
-	} // poids en octet
2860
-
2861
-	// qq chaines standard
2862
-	if (!defined('_ACCESS_FILE_NAME')) {
2863
-		define('_ACCESS_FILE_NAME', '.htaccess');
2864
-	}
2865
-	if (!defined('_AUTH_USER_FILE')) {
2866
-		define('_AUTH_USER_FILE', '.htpasswd');
2867
-	}
2868
-	if (!defined('_SPIP_DUMP')) {
2869
-		define('_SPIP_DUMP', 'dump@nom_site@@[email protected]');
2870
-	}
2871
-	if (!defined('_CACHE_RUBRIQUES')) {
2872
-		/** Fichier cache pour le navigateur de rubrique du bandeau */
2873
-		define('_CACHE_RUBRIQUES', _DIR_TMP . 'menu-rubriques-cache.txt');
2874
-	}
2875
-	if (!defined('_CACHE_RUBRIQUES_MAX')) {
2876
-		/** Nombre maxi de rubriques enfants affichées pour chaque rubrique du navigateur de rubrique du bandeau */
2877
-		define('_CACHE_RUBRIQUES_MAX', 500);
2878
-	}
2879
-
2880
-	if (!defined('_CACHE_CONTEXTES_AJAX_SUR_LONGUEUR')) {
2881
-		/**
2882
-		 * Basculer les contextes ajax en fichier si la longueur d’url est trop grande
2883
-		 * @var int Nombre de caractères */
2884
-		define('_CACHE_CONTEXTES_AJAX_SUR_LONGUEUR', 2000);
2885
-	}
2886
-
2887
-	if (!defined('_EXTENSION_SQUELETTES')) {
2888
-		define('_EXTENSION_SQUELETTES', 'html');
2889
-	}
2890
-
2891
-	if (!defined('_DOCTYPE_ECRIRE')) {
2892
-		/** Définit le doctype de l’espace privé */
2893
-		define('_DOCTYPE_ECRIRE', "<!DOCTYPE html>\n");
2894
-	}
2895
-	if (!defined('_DOCTYPE_AIDE')) {
2896
-		/** Définit le doctype de l’aide en ligne */
2897
-		define(
2898
-			'_DOCTYPE_AIDE',
2899
-			"<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Frameset//EN' 'http://www.w3.org/TR/1999/REC-html401-19991224/frameset.dtd'>"
2900
-		);
2901
-	}
2902
-
2903
-	if (!defined('_SPIP_SCRIPT')) {
2904
-		/** L'adresse de base du site ; on peut mettre '' si la racine est gerée par
2905
-		 * le script de l'espace public, alias index.php */
2906
-		define('_SPIP_SCRIPT', 'spip.php');
2907
-	}
2908
-	if (!defined('_SPIP_PAGE')) {
2909
-		/** Argument page, personalisable en cas de conflit avec un autre script */
2910
-		define('_SPIP_PAGE', 'page');
2911
-	}
2912
-
2913
-	// le script de l'espace prive
2914
-	// Mettre a "index.php" si DirectoryIndex ne le fait pas ou pb connexes:
2915
-	// les anciens IIS n'acceptent pas les POST sur ecrire/ (#419)
2916
-	// meme pb sur thttpd cf. https://forum.spip.net/fr_184153.html
2917
-	if (!defined('_SPIP_ECRIRE_SCRIPT')) {
2918
-		if (!empty($_SERVER['SERVER_SOFTWARE']) and preg_match(',IIS|thttpd,', $_SERVER['SERVER_SOFTWARE'])) {
2919
-			define('_SPIP_ECRIRE_SCRIPT', 'index.php');
2920
-		} else {
2921
-			define('_SPIP_ECRIRE_SCRIPT', '');
2922
-		}
2923
-	}
2924
-
2925
-
2926
-	if (!defined('_SPIP_AJAX')) {
2927
-		define('_SPIP_AJAX', ((!isset($_COOKIE['spip_accepte_ajax']))
2928
-			? 1
2929
-			: (($_COOKIE['spip_accepte_ajax'] != -1) ? 1 : 0)));
2930
-	}
2931
-
2932
-	// La requete est-elle en ajax ?
2933
-	if (!defined('_AJAX')) {
2934
-		define(
2935
-			'_AJAX',
2936
-			(isset($_SERVER['HTTP_X_REQUESTED_WITH']) # ajax jQuery
2937
-				or !empty($_REQUEST['var_ajax_redir']) # redirection 302 apres ajax jQuery
2938
-				or !empty($_REQUEST['var_ajaxcharset']) # compat ascendante pour plugins
2939
-				or !empty($_REQUEST['var_ajax']) # forms ajax & inclure ajax de spip
2940
-			)
2941
-			and empty($_REQUEST['var_noajax']) # horrible exception, car c'est pas parce que la requete est ajax jquery qu'il faut tuer tous les formulaires ajax qu'elle contient
2942
-		);
2943
-	}
2944
-
2945
-	# nombre de pixels maxi pour calcul de la vignette avec gd
2946
-	# au dela de 5500000 on considere que php n'est pas limite en memoire pour cette operation
2947
-	# les configurations limitees en memoire ont un seuil plutot vers 1MPixel
2948
-	if (!defined('_IMG_GD_MAX_PIXELS')) {
2949
-		define(
2950
-			'_IMG_GD_MAX_PIXELS',
2951
-			(isset($GLOBALS['meta']['max_taille_vignettes']) and $GLOBALS['meta']['max_taille_vignettes'])
2952
-			? $GLOBALS['meta']['max_taille_vignettes']
2953
-			: 0
2954
-		);
2955
-	}
2956
-
2957
-	// Protocoles a normaliser dans les chaines de langues
2958
-	if (!defined('_PROTOCOLES_STD')) {
2959
-		define('_PROTOCOLES_STD', 'http|https|ftp|mailto|webcal');
2960
-	}
2961
-
2962
-	init_var_mode();
2811
+    static $too_late = 0;
2812
+    if ($too_late++) {
2813
+        return;
2814
+    }
2815
+
2816
+    // taille mini des login
2817
+    if (!defined('_LOGIN_TROP_COURT')) {
2818
+        define('_LOGIN_TROP_COURT', 4);
2819
+    }
2820
+
2821
+    // la taille maxi des logos (0 : pas de limite) (pas de define par defaut, ce n'est pas utile)
2822
+    #if (!defined('_LOGO_MAX_SIZE')) define('_LOGO_MAX_SIZE', 0); # poids en ko
2823
+    #if (!defined('_LOGO_MAX_WIDTH')) define('_LOGO_MAX_WIDTH', 0); # largeur en pixels
2824
+    #if (!defined('_LOGO_MAX_HEIGHT')) define('_LOGO_MAX_HEIGHT', 0); # hauteur en pixels
2825
+
2826
+    // la taille maxi des images (0 : pas de limite) (pas de define par defaut, ce n'est pas utile)
2827
+    #if (!defined('_DOC_MAX_SIZE')) define('_DOC_MAX_SIZE', 0); # poids en ko
2828
+    #if (!defined('_IMG_MAX_SIZE')) define('_IMG_MAX_SIZE', 0); # poids en ko
2829
+    #if (!defined('_IMG_MAX_WIDTH')) define('_IMG_MAX_WIDTH', 0); # largeur en pixels
2830
+    #if (!defined('_IMG_MAX_HEIGHT')) define('_IMG_MAX_HEIGHT', 0); # hauteur en pixels
2831
+
2832
+    if (!defined('_PASS_LONGUEUR_MINI')) {
2833
+        define('_PASS_LONGUEUR_MINI', 6);
2834
+    }
2835
+
2836
+    // largeur maximale des images dans l'administration
2837
+    if (!defined('_IMG_ADMIN_MAX_WIDTH')) {
2838
+        define('_IMG_ADMIN_MAX_WIDTH', 768);
2839
+    }
2840
+
2841
+    // Qualite des images calculees automatiquement. C'est un nombre entre 0 et 100, meme pour imagick (on ramene a 0..1 par la suite)
2842
+    if (!defined('_IMG_QUALITE')) {
2843
+        define('_IMG_QUALITE', 85);
2844
+    } # valeur par defaut
2845
+    if (!defined('_IMG_GD_QUALITE')) {
2846
+        define('_IMG_GD_QUALITE', _IMG_QUALITE);
2847
+    } # surcharge pour la lib GD
2848
+    if (!defined('_IMG_CONVERT_QUALITE')) {
2849
+        define('_IMG_CONVERT_QUALITE', _IMG_QUALITE);
2850
+    } # surcharge pour imagick en ligne de commande
2851
+    // Historiquement la valeur pour imagick semble differente. Si ca n'est pas necessaire, il serait preferable de garder _IMG_QUALITE
2852
+    if (!defined('_IMG_IMAGICK_QUALITE')) {
2853
+        define('_IMG_IMAGICK_QUALITE', 75);
2854
+    } # surcharge pour imagick en PHP
2855
+
2856
+    if (!defined('_COPIE_LOCALE_MAX_SIZE')) {
2857
+        define('_COPIE_LOCALE_MAX_SIZE', 33_554_432);
2858
+    } // poids en octet
2859
+
2860
+    // qq chaines standard
2861
+    if (!defined('_ACCESS_FILE_NAME')) {
2862
+        define('_ACCESS_FILE_NAME', '.htaccess');
2863
+    }
2864
+    if (!defined('_AUTH_USER_FILE')) {
2865
+        define('_AUTH_USER_FILE', '.htpasswd');
2866
+    }
2867
+    if (!defined('_SPIP_DUMP')) {
2868
+        define('_SPIP_DUMP', 'dump@nom_site@@[email protected]');
2869
+    }
2870
+    if (!defined('_CACHE_RUBRIQUES')) {
2871
+        /** Fichier cache pour le navigateur de rubrique du bandeau */
2872
+        define('_CACHE_RUBRIQUES', _DIR_TMP . 'menu-rubriques-cache.txt');
2873
+    }
2874
+    if (!defined('_CACHE_RUBRIQUES_MAX')) {
2875
+        /** Nombre maxi de rubriques enfants affichées pour chaque rubrique du navigateur de rubrique du bandeau */
2876
+        define('_CACHE_RUBRIQUES_MAX', 500);
2877
+    }
2878
+
2879
+    if (!defined('_CACHE_CONTEXTES_AJAX_SUR_LONGUEUR')) {
2880
+        /**
2881
+         * Basculer les contextes ajax en fichier si la longueur d’url est trop grande
2882
+         * @var int Nombre de caractères */
2883
+        define('_CACHE_CONTEXTES_AJAX_SUR_LONGUEUR', 2000);
2884
+    }
2885
+
2886
+    if (!defined('_EXTENSION_SQUELETTES')) {
2887
+        define('_EXTENSION_SQUELETTES', 'html');
2888
+    }
2889
+
2890
+    if (!defined('_DOCTYPE_ECRIRE')) {
2891
+        /** Définit le doctype de l’espace privé */
2892
+        define('_DOCTYPE_ECRIRE', "<!DOCTYPE html>\n");
2893
+    }
2894
+    if (!defined('_DOCTYPE_AIDE')) {
2895
+        /** Définit le doctype de l’aide en ligne */
2896
+        define(
2897
+            '_DOCTYPE_AIDE',
2898
+            "<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Frameset//EN' 'http://www.w3.org/TR/1999/REC-html401-19991224/frameset.dtd'>"
2899
+        );
2900
+    }
2901
+
2902
+    if (!defined('_SPIP_SCRIPT')) {
2903
+        /** L'adresse de base du site ; on peut mettre '' si la racine est gerée par
2904
+         * le script de l'espace public, alias index.php */
2905
+        define('_SPIP_SCRIPT', 'spip.php');
2906
+    }
2907
+    if (!defined('_SPIP_PAGE')) {
2908
+        /** Argument page, personalisable en cas de conflit avec un autre script */
2909
+        define('_SPIP_PAGE', 'page');
2910
+    }
2911
+
2912
+    // le script de l'espace prive
2913
+    // Mettre a "index.php" si DirectoryIndex ne le fait pas ou pb connexes:
2914
+    // les anciens IIS n'acceptent pas les POST sur ecrire/ (#419)
2915
+    // meme pb sur thttpd cf. https://forum.spip.net/fr_184153.html
2916
+    if (!defined('_SPIP_ECRIRE_SCRIPT')) {
2917
+        if (!empty($_SERVER['SERVER_SOFTWARE']) and preg_match(',IIS|thttpd,', $_SERVER['SERVER_SOFTWARE'])) {
2918
+            define('_SPIP_ECRIRE_SCRIPT', 'index.php');
2919
+        } else {
2920
+            define('_SPIP_ECRIRE_SCRIPT', '');
2921
+        }
2922
+    }
2923
+
2924
+
2925
+    if (!defined('_SPIP_AJAX')) {
2926
+        define('_SPIP_AJAX', ((!isset($_COOKIE['spip_accepte_ajax']))
2927
+            ? 1
2928
+            : (($_COOKIE['spip_accepte_ajax'] != -1) ? 1 : 0)));
2929
+    }
2930
+
2931
+    // La requete est-elle en ajax ?
2932
+    if (!defined('_AJAX')) {
2933
+        define(
2934
+            '_AJAX',
2935
+            (isset($_SERVER['HTTP_X_REQUESTED_WITH']) # ajax jQuery
2936
+                or !empty($_REQUEST['var_ajax_redir']) # redirection 302 apres ajax jQuery
2937
+                or !empty($_REQUEST['var_ajaxcharset']) # compat ascendante pour plugins
2938
+                or !empty($_REQUEST['var_ajax']) # forms ajax & inclure ajax de spip
2939
+            )
2940
+            and empty($_REQUEST['var_noajax']) # horrible exception, car c'est pas parce que la requete est ajax jquery qu'il faut tuer tous les formulaires ajax qu'elle contient
2941
+        );
2942
+    }
2943
+
2944
+    # nombre de pixels maxi pour calcul de la vignette avec gd
2945
+    # au dela de 5500000 on considere que php n'est pas limite en memoire pour cette operation
2946
+    # les configurations limitees en memoire ont un seuil plutot vers 1MPixel
2947
+    if (!defined('_IMG_GD_MAX_PIXELS')) {
2948
+        define(
2949
+            '_IMG_GD_MAX_PIXELS',
2950
+            (isset($GLOBALS['meta']['max_taille_vignettes']) and $GLOBALS['meta']['max_taille_vignettes'])
2951
+            ? $GLOBALS['meta']['max_taille_vignettes']
2952
+            : 0
2953
+        );
2954
+    }
2955
+
2956
+    // Protocoles a normaliser dans les chaines de langues
2957
+    if (!defined('_PROTOCOLES_STD')) {
2958
+        define('_PROTOCOLES_STD', 'http|https|ftp|mailto|webcal');
2959
+    }
2960
+
2961
+    init_var_mode();
2963 2962
 }
2964 2963
 
2965 2964
 /**
@@ -2993,219 +2992,219 @@  discard block
 block discarded – undo
2993 2992
  * `   var_mode` (calcul ou recalcul).
2994 2993
  */
2995 2994
 function init_var_mode() {
2996
-	static $done = false;
2997
-	if (!$done) {
2998
-		if (isset($_GET['var_mode'])) {
2999
-			$var_mode = explode(',', $_GET['var_mode']);
3000
-			// tout le monde peut calcul/recalcul
3001
-			if (!defined('_VAR_MODE')) {
3002
-				if (in_array('recalcul', $var_mode)) {
3003
-					define('_VAR_MODE', 'recalcul');
3004
-				} elseif (in_array('calcul', $var_mode)) {
3005
-					define('_VAR_MODE', 'calcul');
3006
-				}
3007
-			}
3008
-			$var_mode = array_diff($var_mode, ['calcul', 'recalcul']);
3009
-			if ($var_mode) {
3010
-				include_spip('inc/autoriser');
3011
-				// autoriser preview si preview seulement, et sinon autoriser debug
3012
-				if (
3013
-					autoriser(
3014
-						($_GET['var_mode'] == 'preview')
3015
-						? 'previsualiser'
3016
-						: 'debug'
3017
-					)
3018
-				) {
3019
-					if (in_array('traduction', $var_mode)) {
3020
-						// forcer le calcul pour passer dans traduire
3021
-						if (!defined('_VAR_MODE')) {
3022
-							define('_VAR_MODE', 'calcul');
3023
-						}
3024
-						// et ne pas enregistrer de cache pour ne pas trainer les surlignages sur d'autres pages
3025
-						if (!defined('_VAR_NOCACHE')) {
3026
-							define('_VAR_NOCACHE', true);
3027
-						}
3028
-						$var_mode = array_diff($var_mode, ['traduction']);
3029
-					}
3030
-					if (in_array('preview', $var_mode)) {
3031
-						// basculer sur les criteres de preview dans les boucles
3032
-						if (!defined('_VAR_PREVIEW')) {
3033
-							define('_VAR_PREVIEW', true);
3034
-						}
3035
-						// forcer le calcul
3036
-						if (!defined('_VAR_MODE')) {
3037
-							define('_VAR_MODE', 'calcul');
3038
-						}
3039
-						// et ne pas enregistrer de cache
3040
-						if (!defined('_VAR_NOCACHE')) {
3041
-							define('_VAR_NOCACHE', true);
3042
-						}
3043
-						$var_mode = array_diff($var_mode, ['preview']);
3044
-					}
3045
-					if (in_array('inclure', $var_mode)) {
3046
-						// forcer le compilo et ignorer les caches existants
3047
-						if (!defined('_VAR_MODE')) {
3048
-							define('_VAR_MODE', 'calcul');
3049
-						}
3050
-						if (!defined('_VAR_INCLURE')) {
3051
-							define('_VAR_INCLURE', true);
3052
-						}
3053
-						// et ne pas enregistrer de cache
3054
-						if (!defined('_VAR_NOCACHE')) {
3055
-							define('_VAR_NOCACHE', true);
3056
-						}
3057
-						$var_mode = array_diff($var_mode, ['inclure']);
3058
-					}
3059
-					if (in_array('urls', $var_mode)) {
3060
-						// forcer le compilo et ignorer les caches existants
3061
-						if (!defined('_VAR_MODE')) {
3062
-							define('_VAR_MODE', 'calcul');
3063
-						}
3064
-						if (!defined('_VAR_URLS')) {
3065
-							define('_VAR_URLS', true);
3066
-						}
3067
-						$var_mode = array_diff($var_mode, ['urls']);
3068
-					}
3069
-					if (in_array('images', $var_mode)) {
3070
-						// forcer le compilo et ignorer les caches existants
3071
-						if (!defined('_VAR_MODE')) {
3072
-							define('_VAR_MODE', 'calcul');
3073
-						}
3074
-						// indiquer qu'on doit recalculer les images
3075
-						if (!defined('_VAR_IMAGES')) {
3076
-							define('_VAR_IMAGES', true);
3077
-						}
3078
-						$var_mode = array_diff($var_mode, ['images']);
3079
-					}
3080
-					if (in_array('debug', $var_mode)) {
3081
-						if (!defined('_VAR_MODE')) {
3082
-							define('_VAR_MODE', 'debug');
3083
-						}
3084
-						// et ne pas enregistrer de cache
3085
-						if (!defined('_VAR_NOCACHE')) {
3086
-							define('_VAR_NOCACHE', true);
3087
-						}
3088
-						$var_mode = array_diff($var_mode, ['debug']);
3089
-					}
3090
-					if (count($var_mode) and !defined('_VAR_MODE')) {
3091
-						define('_VAR_MODE', reset($var_mode));
3092
-					}
3093
-					if (isset($GLOBALS['visiteur_session']['nom'])) {
3094
-						spip_log($GLOBALS['visiteur_session']['nom']
3095
-							. ' ' . _VAR_MODE);
3096
-					}
3097
-				} // pas autorise ?
3098
-				else {
3099
-					// si on n'est pas connecte on se redirige, si on est pas en cli et pas deja en train de se loger
3100
-					if (
3101
-						!$GLOBALS['visiteur_session']
3102
-						and !empty($_SERVER['HTTP_HOST'])
3103
-						and !empty($_SERVER['REQUEST_METHOD'])
3104
-						and $_SERVER['REQUEST_METHOD'] === 'GET'
3105
-					) {
3106
-						$self = self('&', true);
3107
-						if (strpos($self, 'page=login') === false) {
3108
-							include_spip('inc/headers');
3109
-							$redirect = parametre_url(self('&', true), 'var_mode', $_GET['var_mode'], '&');
3110
-							redirige_par_entete(generer_url_public('login', 'url=' . rawurlencode($redirect), true));
3111
-						}
3112
-					}
3113
-					// sinon tant pis
3114
-				}
3115
-			}
3116
-		}
3117
-		if (!defined('_VAR_MODE')) {
3118
-			/**
3119
-			 * Indique le mode de calcul ou d'affichage de la page.
3120
-			 * @see init_var_mode()
3121
-			 */
3122
-			define('_VAR_MODE', false);
3123
-		}
3124
-		$done = true;
3125
-	}
2995
+    static $done = false;
2996
+    if (!$done) {
2997
+        if (isset($_GET['var_mode'])) {
2998
+            $var_mode = explode(',', $_GET['var_mode']);
2999
+            // tout le monde peut calcul/recalcul
3000
+            if (!defined('_VAR_MODE')) {
3001
+                if (in_array('recalcul', $var_mode)) {
3002
+                    define('_VAR_MODE', 'recalcul');
3003
+                } elseif (in_array('calcul', $var_mode)) {
3004
+                    define('_VAR_MODE', 'calcul');
3005
+                }
3006
+            }
3007
+            $var_mode = array_diff($var_mode, ['calcul', 'recalcul']);
3008
+            if ($var_mode) {
3009
+                include_spip('inc/autoriser');
3010
+                // autoriser preview si preview seulement, et sinon autoriser debug
3011
+                if (
3012
+                    autoriser(
3013
+                        ($_GET['var_mode'] == 'preview')
3014
+                        ? 'previsualiser'
3015
+                        : 'debug'
3016
+                    )
3017
+                ) {
3018
+                    if (in_array('traduction', $var_mode)) {
3019
+                        // forcer le calcul pour passer dans traduire
3020
+                        if (!defined('_VAR_MODE')) {
3021
+                            define('_VAR_MODE', 'calcul');
3022
+                        }
3023
+                        // et ne pas enregistrer de cache pour ne pas trainer les surlignages sur d'autres pages
3024
+                        if (!defined('_VAR_NOCACHE')) {
3025
+                            define('_VAR_NOCACHE', true);
3026
+                        }
3027
+                        $var_mode = array_diff($var_mode, ['traduction']);
3028
+                    }
3029
+                    if (in_array('preview', $var_mode)) {
3030
+                        // basculer sur les criteres de preview dans les boucles
3031
+                        if (!defined('_VAR_PREVIEW')) {
3032
+                            define('_VAR_PREVIEW', true);
3033
+                        }
3034
+                        // forcer le calcul
3035
+                        if (!defined('_VAR_MODE')) {
3036
+                            define('_VAR_MODE', 'calcul');
3037
+                        }
3038
+                        // et ne pas enregistrer de cache
3039
+                        if (!defined('_VAR_NOCACHE')) {
3040
+                            define('_VAR_NOCACHE', true);
3041
+                        }
3042
+                        $var_mode = array_diff($var_mode, ['preview']);
3043
+                    }
3044
+                    if (in_array('inclure', $var_mode)) {
3045
+                        // forcer le compilo et ignorer les caches existants
3046
+                        if (!defined('_VAR_MODE')) {
3047
+                            define('_VAR_MODE', 'calcul');
3048
+                        }
3049
+                        if (!defined('_VAR_INCLURE')) {
3050
+                            define('_VAR_INCLURE', true);
3051
+                        }
3052
+                        // et ne pas enregistrer de cache
3053
+                        if (!defined('_VAR_NOCACHE')) {
3054
+                            define('_VAR_NOCACHE', true);
3055
+                        }
3056
+                        $var_mode = array_diff($var_mode, ['inclure']);
3057
+                    }
3058
+                    if (in_array('urls', $var_mode)) {
3059
+                        // forcer le compilo et ignorer les caches existants
3060
+                        if (!defined('_VAR_MODE')) {
3061
+                            define('_VAR_MODE', 'calcul');
3062
+                        }
3063
+                        if (!defined('_VAR_URLS')) {
3064
+                            define('_VAR_URLS', true);
3065
+                        }
3066
+                        $var_mode = array_diff($var_mode, ['urls']);
3067
+                    }
3068
+                    if (in_array('images', $var_mode)) {
3069
+                        // forcer le compilo et ignorer les caches existants
3070
+                        if (!defined('_VAR_MODE')) {
3071
+                            define('_VAR_MODE', 'calcul');
3072
+                        }
3073
+                        // indiquer qu'on doit recalculer les images
3074
+                        if (!defined('_VAR_IMAGES')) {
3075
+                            define('_VAR_IMAGES', true);
3076
+                        }
3077
+                        $var_mode = array_diff($var_mode, ['images']);
3078
+                    }
3079
+                    if (in_array('debug', $var_mode)) {
3080
+                        if (!defined('_VAR_MODE')) {
3081
+                            define('_VAR_MODE', 'debug');
3082
+                        }
3083
+                        // et ne pas enregistrer de cache
3084
+                        if (!defined('_VAR_NOCACHE')) {
3085
+                            define('_VAR_NOCACHE', true);
3086
+                        }
3087
+                        $var_mode = array_diff($var_mode, ['debug']);
3088
+                    }
3089
+                    if (count($var_mode) and !defined('_VAR_MODE')) {
3090
+                        define('_VAR_MODE', reset($var_mode));
3091
+                    }
3092
+                    if (isset($GLOBALS['visiteur_session']['nom'])) {
3093
+                        spip_log($GLOBALS['visiteur_session']['nom']
3094
+                            . ' ' . _VAR_MODE);
3095
+                    }
3096
+                } // pas autorise ?
3097
+                else {
3098
+                    // si on n'est pas connecte on se redirige, si on est pas en cli et pas deja en train de se loger
3099
+                    if (
3100
+                        !$GLOBALS['visiteur_session']
3101
+                        and !empty($_SERVER['HTTP_HOST'])
3102
+                        and !empty($_SERVER['REQUEST_METHOD'])
3103
+                        and $_SERVER['REQUEST_METHOD'] === 'GET'
3104
+                    ) {
3105
+                        $self = self('&', true);
3106
+                        if (strpos($self, 'page=login') === false) {
3107
+                            include_spip('inc/headers');
3108
+                            $redirect = parametre_url(self('&', true), 'var_mode', $_GET['var_mode'], '&');
3109
+                            redirige_par_entete(generer_url_public('login', 'url=' . rawurlencode($redirect), true));
3110
+                        }
3111
+                    }
3112
+                    // sinon tant pis
3113
+                }
3114
+            }
3115
+        }
3116
+        if (!defined('_VAR_MODE')) {
3117
+            /**
3118
+             * Indique le mode de calcul ou d'affichage de la page.
3119
+             * @see init_var_mode()
3120
+             */
3121
+            define('_VAR_MODE', false);
3122
+        }
3123
+        $done = true;
3124
+    }
3126 3125
 }
3127 3126
 
3128 3127
 // Annuler les magic quotes \' sur GET POST COOKIE et GLOBALS ;
3129 3128
 // supprimer aussi les eventuels caracteres nuls %00, qui peuvent tromper
3130 3129
 // la commande is_readable('chemin/vers/fichier/interdit%00truc_normal')
3131 3130
 function spip_desinfecte(&$t, $deep = true) {
3132
-	foreach ($t as $key => $val) {
3133
-		if (is_string($t[$key])) {
3134
-			$t[$key] = str_replace(chr(0), '-', $t[$key]);
3135
-		} // traiter aussi les "texte_plus" de article_edit
3136
-		else {
3137
-			if ($deep and is_array($t[$key]) and $key !== 'GLOBALS') {
3138
-				spip_desinfecte($t[$key], $deep);
3139
-			}
3140
-		}
3141
-	}
3131
+    foreach ($t as $key => $val) {
3132
+        if (is_string($t[$key])) {
3133
+            $t[$key] = str_replace(chr(0), '-', $t[$key]);
3134
+        } // traiter aussi les "texte_plus" de article_edit
3135
+        else {
3136
+            if ($deep and is_array($t[$key]) and $key !== 'GLOBALS') {
3137
+                spip_desinfecte($t[$key], $deep);
3138
+            }
3139
+        }
3140
+    }
3142 3141
 }
3143 3142
 
3144 3143
 //  retourne le statut du visiteur s'il s'annonce
3145 3144
 
3146 3145
 function verifier_visiteur() {
3147
-	// Rq: pour que cette fonction marche depuis mes_options
3148
-	// il faut forcer l'init si ce n'est fait
3149
-	// mais on risque de perturber des plugins en initialisant trop tot
3150
-	// certaines constantes
3151
-	@spip_initialisation_core(
3152
-		(_DIR_RACINE . _NOM_PERMANENTS_INACCESSIBLES),
3153
-		(_DIR_RACINE . _NOM_PERMANENTS_ACCESSIBLES),
3154
-		(_DIR_RACINE . _NOM_TEMPORAIRES_INACCESSIBLES),
3155
-		(_DIR_RACINE . _NOM_TEMPORAIRES_ACCESSIBLES)
3156
-	);
3157
-
3158
-	// Demarrer une session NON AUTHENTIFIEE si on donne son nom
3159
-	// dans un formulaire sans login (ex: #FORMULAIRE_FORUM)
3160
-	// Attention on separe bien session_nom et nom, pour eviter
3161
-	// les melanges entre donnees SQL et variables plus aleatoires
3162
-	$variables_session = ['session_nom', 'session_email'];
3163
-	foreach ($variables_session as $var) {
3164
-		if (_request($var) !== null) {
3165
-			$init = true;
3166
-			break;
3167
-		}
3168
-	}
3169
-	if (isset($init)) {
3170
-		#@spip_initialisation_suite();
3171
-		$session = charger_fonction('session', 'inc');
3172
-		$session();
3173
-		include_spip('inc/texte');
3174
-		foreach ($variables_session as $var) {
3175
-			if (($a = _request($var)) !== null) {
3176
-				$GLOBALS['visiteur_session'][$var] = safehtml($a);
3177
-			}
3178
-		}
3179
-		if (!isset($GLOBALS['visiteur_session']['id_auteur'])) {
3180
-			$GLOBALS['visiteur_session']['id_auteur'] = 0;
3181
-		}
3182
-		$session($GLOBALS['visiteur_session']);
3183
-
3184
-		return 0;
3185
-	}
3186
-
3187
-	$h = (isset($_SERVER['PHP_AUTH_USER']) and !$GLOBALS['ignore_auth_http']);
3188
-	if ($h or isset($_COOKIE['spip_session']) or isset($_COOKIE[$GLOBALS['cookie_prefix'] . '_session'])) {
3189
-		$session = charger_fonction('session', 'inc');
3190
-		if ($session()) {
3191
-			return $GLOBALS['visiteur_session']['statut'];
3192
-		}
3193
-		if ($h and isset($_SERVER['PHP_AUTH_PW'])) {
3194
-			include_spip('inc/auth');
3195
-			$h = lire_php_auth($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
3196
-		}
3197
-		if ($h) {
3198
-			$GLOBALS['visiteur_session'] = $h;
3199
-
3200
-			return $GLOBALS['visiteur_session']['statut'];
3201
-		}
3202
-	}
3203
-
3204
-	// au moins son navigateur nous dit la langue preferee de cet inconnu
3205
-	include_spip('inc/lang');
3206
-	utiliser_langue_visiteur();
3207
-
3208
-	return false;
3146
+    // Rq: pour que cette fonction marche depuis mes_options
3147
+    // il faut forcer l'init si ce n'est fait
3148
+    // mais on risque de perturber des plugins en initialisant trop tot
3149
+    // certaines constantes
3150
+    @spip_initialisation_core(
3151
+        (_DIR_RACINE . _NOM_PERMANENTS_INACCESSIBLES),
3152
+        (_DIR_RACINE . _NOM_PERMANENTS_ACCESSIBLES),
3153
+        (_DIR_RACINE . _NOM_TEMPORAIRES_INACCESSIBLES),
3154
+        (_DIR_RACINE . _NOM_TEMPORAIRES_ACCESSIBLES)
3155
+    );
3156
+
3157
+    // Demarrer une session NON AUTHENTIFIEE si on donne son nom
3158
+    // dans un formulaire sans login (ex: #FORMULAIRE_FORUM)
3159
+    // Attention on separe bien session_nom et nom, pour eviter
3160
+    // les melanges entre donnees SQL et variables plus aleatoires
3161
+    $variables_session = ['session_nom', 'session_email'];
3162
+    foreach ($variables_session as $var) {
3163
+        if (_request($var) !== null) {
3164
+            $init = true;
3165
+            break;
3166
+        }
3167
+    }
3168
+    if (isset($init)) {
3169
+        #@spip_initialisation_suite();
3170
+        $session = charger_fonction('session', 'inc');
3171
+        $session();
3172
+        include_spip('inc/texte');
3173
+        foreach ($variables_session as $var) {
3174
+            if (($a = _request($var)) !== null) {
3175
+                $GLOBALS['visiteur_session'][$var] = safehtml($a);
3176
+            }
3177
+        }
3178
+        if (!isset($GLOBALS['visiteur_session']['id_auteur'])) {
3179
+            $GLOBALS['visiteur_session']['id_auteur'] = 0;
3180
+        }
3181
+        $session($GLOBALS['visiteur_session']);
3182
+
3183
+        return 0;
3184
+    }
3185
+
3186
+    $h = (isset($_SERVER['PHP_AUTH_USER']) and !$GLOBALS['ignore_auth_http']);
3187
+    if ($h or isset($_COOKIE['spip_session']) or isset($_COOKIE[$GLOBALS['cookie_prefix'] . '_session'])) {
3188
+        $session = charger_fonction('session', 'inc');
3189
+        if ($session()) {
3190
+            return $GLOBALS['visiteur_session']['statut'];
3191
+        }
3192
+        if ($h and isset($_SERVER['PHP_AUTH_PW'])) {
3193
+            include_spip('inc/auth');
3194
+            $h = lire_php_auth($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
3195
+        }
3196
+        if ($h) {
3197
+            $GLOBALS['visiteur_session'] = $h;
3198
+
3199
+            return $GLOBALS['visiteur_session']['statut'];
3200
+        }
3201
+    }
3202
+
3203
+    // au moins son navigateur nous dit la langue preferee de cet inconnu
3204
+    include_spip('inc/lang');
3205
+    utiliser_langue_visiteur();
3206
+
3207
+    return false;
3209 3208
 }
3210 3209
 
3211 3210
 
@@ -3228,21 +3227,21 @@  discard block
 block discarded – undo
3228 3227
  *     - string Langue utilisée.
3229 3228
  **/
3230 3229
 function lang_select($lang = null) {
3231
-	static $pile_langues = [];
3232
-	if (!function_exists('changer_langue')) {
3233
-		include_spip('inc/lang');
3234
-	}
3235
-	if ($lang === null) {
3236
-		$lang = array_pop($pile_langues);
3237
-	} else {
3238
-		array_push($pile_langues, $GLOBALS['spip_lang']);
3239
-	}
3240
-	if (isset($GLOBALS['spip_lang']) and $lang == $GLOBALS['spip_lang']) {
3241
-		return $lang;
3242
-	}
3243
-	changer_langue($lang);
3230
+    static $pile_langues = [];
3231
+    if (!function_exists('changer_langue')) {
3232
+        include_spip('inc/lang');
3233
+    }
3234
+    if ($lang === null) {
3235
+        $lang = array_pop($pile_langues);
3236
+    } else {
3237
+        array_push($pile_langues, $GLOBALS['spip_lang']);
3238
+    }
3239
+    if (isset($GLOBALS['spip_lang']) and $lang == $GLOBALS['spip_lang']) {
3240
+        return $lang;
3241
+    }
3242
+    changer_langue($lang);
3244 3243
 
3245
-	return $lang;
3244
+    return $lang;
3246 3245
 }
3247 3246
 
3248 3247
 /**
@@ -3259,20 +3258,20 @@  discard block
 block discarded – undo
3259 3258
  *     Identifiant de la session
3260 3259
  **/
3261 3260
 function spip_session($force = false) {
3262
-	static $session;
3263
-	if ($force or !isset($session)) {
3264
-		$s = pipeline(
3265
-			'definir_session',
3266
-			$GLOBALS['visiteur_session']
3267
-				? serialize($GLOBALS['visiteur_session'])
3268
-				. '_' . @$_COOKIE['spip_session']
3269
-				: ''
3270
-		);
3271
-		$session = $s ? substr(md5($s), 0, 8) : '';
3272
-	}
3261
+    static $session;
3262
+    if ($force or !isset($session)) {
3263
+        $s = pipeline(
3264
+            'definir_session',
3265
+            $GLOBALS['visiteur_session']
3266
+                ? serialize($GLOBALS['visiteur_session'])
3267
+                . '_' . @$_COOKIE['spip_session']
3268
+                : ''
3269
+        );
3270
+        $session = $s ? substr(md5($s), 0, 8) : '';
3271
+    }
3273 3272
 
3274
-	#spip_log('session: '.$session);
3275
-	return $session;
3273
+    #spip_log('session: '.$session);
3274
+    return $session;
3276 3275
 }
3277 3276
 
3278 3277
 
@@ -3291,9 +3290,9 @@  discard block
 block discarded – undo
3291 3290
  *    Lien sur une icone d'aide
3292 3291
  **/
3293 3292
 function aider($aide = '', $distante = false) {
3294
-	$aider = charger_fonction('aide', 'inc', true);
3293
+    $aider = charger_fonction('aide', 'inc', true);
3295 3294
 
3296
-	return $aider ? $aider($aide, '', [], $distante) : '';
3295
+    return $aider ? $aider($aide, '', [], $distante) : '';
3297 3296
 }
3298 3297
 
3299 3298
 /**
@@ -3303,24 +3302,24 @@  discard block
 block discarded – undo
3303 3302
  */
3304 3303
 function exec_info_dist() {
3305 3304
 
3306
-	include_spip('inc/autoriser');
3307
-	if (autoriser('phpinfos')) {
3308
-		$cookies_masques = ['spip_session', 'PHPSESSID'];
3309
-		$cookies_backup = [];
3310
-		foreach ($cookies_masques as $k) {
3311
-			if (!empty($_COOKIE[$k])) {
3312
-				$cookies_backup[$k] = $_COOKIE[$k];
3313
-				$_COOKIE[$k] = '******************************';
3314
-			}
3315
-		}
3316
-		phpinfo();
3317
-		foreach ($cookies_backup as $k => $v) {
3318
-			$_COOKIE[$k] = $v;
3319
-		}
3320
-	} else {
3321
-		include_spip('inc/filtres');
3322
-		sinon_interdire_acces();
3323
-	}
3305
+    include_spip('inc/autoriser');
3306
+    if (autoriser('phpinfos')) {
3307
+        $cookies_masques = ['spip_session', 'PHPSESSID'];
3308
+        $cookies_backup = [];
3309
+        foreach ($cookies_masques as $k) {
3310
+            if (!empty($_COOKIE[$k])) {
3311
+                $cookies_backup[$k] = $_COOKIE[$k];
3312
+                $_COOKIE[$k] = '******************************';
3313
+            }
3314
+        }
3315
+        phpinfo();
3316
+        foreach ($cookies_backup as $k => $v) {
3317
+            $_COOKIE[$k] = $v;
3318
+        }
3319
+    } else {
3320
+        include_spip('inc/filtres');
3321
+        sinon_interdire_acces();
3322
+    }
3324 3323
 }
3325 3324
 
3326 3325
 /**
@@ -3340,13 +3339,13 @@  discard block
 block discarded – undo
3340 3339
  *     - string si $message à false.
3341 3340
  **/
3342 3341
 function erreur_squelette($message = '', $lieu = '') {
3343
-	$debusquer = charger_fonction('debusquer', 'public');
3344
-	if (is_array($lieu)) {
3345
-		include_spip('public/compiler');
3346
-		$lieu = reconstruire_contexte_compil($lieu);
3347
-	}
3342
+    $debusquer = charger_fonction('debusquer', 'public');
3343
+    if (is_array($lieu)) {
3344
+        include_spip('public/compiler');
3345
+        $lieu = reconstruire_contexte_compil($lieu);
3346
+    }
3348 3347
 
3349
-	return $debusquer($message, $lieu);
3348
+    return $debusquer($message, $lieu);
3350 3349
 }
3351 3350
 
3352 3351
 /**
@@ -3383,108 +3382,108 @@  discard block
 block discarded – undo
3383 3382
  *     - ou tableau d'information sur le squelette.
3384 3383
  */
3385 3384
 function recuperer_fond($fond, $contexte = [], $options = [], string $connect = '') {
3386
-	if (!function_exists('evaluer_fond')) {
3387
-		include_spip('public/assembler');
3388
-	}
3389
-	// assurer la compat avec l'ancienne syntaxe
3390
-	// (trim etait le 3eme argument, par defaut a true)
3391
-	if (!is_array($options)) {
3392
-		$options = ['trim' => $options];
3393
-	}
3394
-	if (!isset($options['trim'])) {
3395
-		$options['trim'] = true;
3396
-	}
3397
-
3398
-	if (isset($contexte['connect'])) {
3399
-		$connect = $contexte['connect'];
3400
-		unset($contexte['connect']);
3401
-	}
3402
-
3403
-	$texte = '';
3404
-	$pages = [];
3405
-	$lang_select = '';
3406
-	if (!isset($options['etoile']) or !$options['etoile']) {
3407
-		// Si on a inclus sans fixer le critere de lang, on prend la langue courante
3408
-		if (!isset($contexte['lang'])) {
3409
-			$contexte['lang'] = $GLOBALS['spip_lang'];
3410
-		}
3411
-
3412
-		if ($contexte['lang'] != $GLOBALS['meta']['langue_site']) {
3413
-			$lang_select = lang_select($contexte['lang']);
3414
-		}
3415
-	}
3416
-
3417
-	if (!isset($GLOBALS['_INC_PUBLIC'])) {
3418
-		$GLOBALS['_INC_PUBLIC'] = 0;
3419
-	}
3420
-
3421
-	$GLOBALS['_INC_PUBLIC']++;
3422
-
3423
-	// fix #4235
3424
-	$cache_utilise_session_appelant	= ($GLOBALS['cache_utilise_session'] ?? null);
3425
-
3426
-
3427
-	foreach (is_array($fond) ? $fond : [$fond] as $f) {
3428
-		unset($GLOBALS['cache_utilise_session']);	// fix #4235
3429
-
3430
-		$page = evaluer_fond($f, $contexte, $connect);
3431
-		if ($page === '') {
3432
-			$c = $options['compil'] ?? '';
3433
-			$a = ['fichier' => $f];
3434
-			$erreur = _T('info_erreur_squelette2', $a); // squelette introuvable
3435
-			erreur_squelette($erreur, $c);
3436
-			// eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
3437
-			$page = ['texte' => '', 'erreur' => $erreur];
3438
-		}
3439
-
3440
-		$page = pipeline('recuperer_fond', [
3441
-			'args' => ['fond' => $f, 'contexte' => $contexte, 'options' => $options, 'connect' => $connect],
3442
-			'data' => $page
3443
-		]);
3444
-		if (isset($options['ajax']) and $options['ajax']) {
3445
-			if (!function_exists('encoder_contexte_ajax')) {
3446
-				include_spip('inc/filtres');
3447
-			}
3448
-			$page['texte'] = encoder_contexte_ajax(
3449
-				array_merge(
3450
-					$contexte,
3451
-					['fond' => $f],
3452
-					($connect ? ['connect' => $connect] : [])
3453
-				),
3454
-				'',
3455
-				$page['texte'],
3456
-				$options['ajax']
3457
-			);
3458
-		}
3459
-
3460
-		if (isset($options['raw']) and $options['raw']) {
3461
-			$pages[] = $page;
3462
-		} else {
3463
-			$texte .= $options['trim'] ? rtrim($page['texte'] ?? '') : $page['texte'];
3464
-		}
3465
-
3466
-		// contamination de la session appelante, pour les inclusions statiques
3467
-		if (isset($page['invalideurs']['session'])) {
3468
-			$cache_utilise_session_appelant = $page['invalideurs']['session'];
3469
-		}
3470
-	}
3471
-
3472
-	// restaurer le sessionnement du contexte appelant,
3473
-	// éventuellement contaminé si on vient de récupérer une inclusion statique sessionnée
3474
-	if (isset($cache_utilise_session_appelant)) {
3475
-		$GLOBALS['cache_utilise_session'] = $cache_utilise_session_appelant;
3476
-	}
3477
-
3478
-	$GLOBALS['_INC_PUBLIC']--;
3479
-
3480
-	if ($lang_select) {
3481
-		lang_select();
3482
-	}
3483
-	if (isset($options['raw']) and $options['raw']) {
3484
-		return is_array($fond) ? $pages : reset($pages);
3485
-	} else {
3486
-		return $options['trim'] ? ltrim($texte) : $texte;
3487
-	}
3385
+    if (!function_exists('evaluer_fond')) {
3386
+        include_spip('public/assembler');
3387
+    }
3388
+    // assurer la compat avec l'ancienne syntaxe
3389
+    // (trim etait le 3eme argument, par defaut a true)
3390
+    if (!is_array($options)) {
3391
+        $options = ['trim' => $options];
3392
+    }
3393
+    if (!isset($options['trim'])) {
3394
+        $options['trim'] = true;
3395
+    }
3396
+
3397
+    if (isset($contexte['connect'])) {
3398
+        $connect = $contexte['connect'];
3399
+        unset($contexte['connect']);
3400
+    }
3401
+
3402
+    $texte = '';
3403
+    $pages = [];
3404
+    $lang_select = '';
3405
+    if (!isset($options['etoile']) or !$options['etoile']) {
3406
+        // Si on a inclus sans fixer le critere de lang, on prend la langue courante
3407
+        if (!isset($contexte['lang'])) {
3408
+            $contexte['lang'] = $GLOBALS['spip_lang'];
3409
+        }
3410
+
3411
+        if ($contexte['lang'] != $GLOBALS['meta']['langue_site']) {
3412
+            $lang_select = lang_select($contexte['lang']);
3413
+        }
3414
+    }
3415
+
3416
+    if (!isset($GLOBALS['_INC_PUBLIC'])) {
3417
+        $GLOBALS['_INC_PUBLIC'] = 0;
3418
+    }
3419
+
3420
+    $GLOBALS['_INC_PUBLIC']++;
3421
+
3422
+    // fix #4235
3423
+    $cache_utilise_session_appelant	= ($GLOBALS['cache_utilise_session'] ?? null);
3424
+
3425
+
3426
+    foreach (is_array($fond) ? $fond : [$fond] as $f) {
3427
+        unset($GLOBALS['cache_utilise_session']);	// fix #4235
3428
+
3429
+        $page = evaluer_fond($f, $contexte, $connect);
3430
+        if ($page === '') {
3431
+            $c = $options['compil'] ?? '';
3432
+            $a = ['fichier' => $f];
3433
+            $erreur = _T('info_erreur_squelette2', $a); // squelette introuvable
3434
+            erreur_squelette($erreur, $c);
3435
+            // eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
3436
+            $page = ['texte' => '', 'erreur' => $erreur];
3437
+        }
3438
+
3439
+        $page = pipeline('recuperer_fond', [
3440
+            'args' => ['fond' => $f, 'contexte' => $contexte, 'options' => $options, 'connect' => $connect],
3441
+            'data' => $page
3442
+        ]);
3443
+        if (isset($options['ajax']) and $options['ajax']) {
3444
+            if (!function_exists('encoder_contexte_ajax')) {
3445
+                include_spip('inc/filtres');
3446
+            }
3447
+            $page['texte'] = encoder_contexte_ajax(
3448
+                array_merge(
3449
+                    $contexte,
3450
+                    ['fond' => $f],
3451
+                    ($connect ? ['connect' => $connect] : [])
3452
+                ),
3453
+                '',
3454
+                $page['texte'],
3455
+                $options['ajax']
3456
+            );
3457
+        }
3458
+
3459
+        if (isset($options['raw']) and $options['raw']) {
3460
+            $pages[] = $page;
3461
+        } else {
3462
+            $texte .= $options['trim'] ? rtrim($page['texte'] ?? '') : $page['texte'];
3463
+        }
3464
+
3465
+        // contamination de la session appelante, pour les inclusions statiques
3466
+        if (isset($page['invalideurs']['session'])) {
3467
+            $cache_utilise_session_appelant = $page['invalideurs']['session'];
3468
+        }
3469
+    }
3470
+
3471
+    // restaurer le sessionnement du contexte appelant,
3472
+    // éventuellement contaminé si on vient de récupérer une inclusion statique sessionnée
3473
+    if (isset($cache_utilise_session_appelant)) {
3474
+        $GLOBALS['cache_utilise_session'] = $cache_utilise_session_appelant;
3475
+    }
3476
+
3477
+    $GLOBALS['_INC_PUBLIC']--;
3478
+
3479
+    if ($lang_select) {
3480
+        lang_select();
3481
+    }
3482
+    if (isset($options['raw']) and $options['raw']) {
3483
+        return is_array($fond) ? $pages : reset($pages);
3484
+    } else {
3485
+        return $options['trim'] ? ltrim($texte) : $texte;
3486
+    }
3488 3487
 }
3489 3488
 
3490 3489
 /**
@@ -3494,7 +3493,7 @@  discard block
 block discarded – undo
3494 3493
  * @return string
3495 3494
  */
3496 3495
 function trouve_modele($nom) {
3497
-	return trouver_fond($nom, 'modeles/');
3496
+    return trouver_fond($nom, 'modeles/');
3498 3497
 }
3499 3498
 
3500 3499
 /**
@@ -3510,21 +3509,21 @@  discard block
 block discarded – undo
3510 3509
  * @return array|string
3511 3510
  */
3512 3511
 function trouver_fond($nom, $dir = '', $pathinfo = false) {
3513
-	$f = find_in_path($nom . '.' . _EXTENSION_SQUELETTES, $dir ? rtrim($dir, '/') . '/' : '');
3514
-	if (!$pathinfo) {
3515
-		return $f;
3516
-	}
3517
-	// renvoyer un tableau detaille si $pathinfo==true
3518
-	$p = pathinfo($f);
3519
-	if (!isset($p['extension']) or !$p['extension']) {
3520
-		$p['extension'] = _EXTENSION_SQUELETTES;
3521
-	}
3522
-	if (!isset($p['extension']) or !$p['filename']) {
3523
-		$p['filename'] = ($p['basename'] ? substr($p['basename'], 0, -strlen($p['extension']) - 1) : '');
3524
-	}
3525
-	$p['fond'] = ($f ? substr($f, 0, -strlen($p['extension']) - 1) : '');
3512
+    $f = find_in_path($nom . '.' . _EXTENSION_SQUELETTES, $dir ? rtrim($dir, '/') . '/' : '');
3513
+    if (!$pathinfo) {
3514
+        return $f;
3515
+    }
3516
+    // renvoyer un tableau detaille si $pathinfo==true
3517
+    $p = pathinfo($f);
3518
+    if (!isset($p['extension']) or !$p['extension']) {
3519
+        $p['extension'] = _EXTENSION_SQUELETTES;
3520
+    }
3521
+    if (!isset($p['extension']) or !$p['filename']) {
3522
+        $p['filename'] = ($p['basename'] ? substr($p['basename'], 0, -strlen($p['extension']) - 1) : '');
3523
+    }
3524
+    $p['fond'] = ($f ? substr($f, 0, -strlen($p['extension']) - 1) : '');
3526 3525
 
3527
-	return $p;
3526
+    return $p;
3528 3527
 }
3529 3528
 
3530 3529
 /**
@@ -3544,21 +3543,21 @@  discard block
 block discarded – undo
3544 3543
  *     Nom de l'exec, sinon chaîne vide.
3545 3544
  **/
3546 3545
 function tester_url_ecrire($nom) {
3547
-	static $exec = [];
3548
-	if (isset($exec[$nom])) {
3549
-		return $exec[$nom];
3550
-	}
3551
-	// tester si c'est une page en squelette
3552
-	if (trouver_fond($nom, 'prive/squelettes/contenu/')) {
3553
-		return $exec[$nom] = 'fond';
3554
-	} // echafaudage d'un fond !
3555
-	elseif (include_spip('public/styliser_par_z') and z_echafaudable($nom)) {
3556
-		return $exec[$nom] = 'fond';
3557
-	}
3558
-	// attention, il ne faut pas inclure l'exec ici
3559
-	// car sinon #URL_ECRIRE provoque des inclusions
3560
-	// et des define intrusifs potentiels
3561
-	return $exec[$nom] = ((find_in_path("{$nom}.php", 'exec/') or charger_fonction($nom, 'exec', true)) ? $nom : '');
3546
+    static $exec = [];
3547
+    if (isset($exec[$nom])) {
3548
+        return $exec[$nom];
3549
+    }
3550
+    // tester si c'est une page en squelette
3551
+    if (trouver_fond($nom, 'prive/squelettes/contenu/')) {
3552
+        return $exec[$nom] = 'fond';
3553
+    } // echafaudage d'un fond !
3554
+    elseif (include_spip('public/styliser_par_z') and z_echafaudable($nom)) {
3555
+        return $exec[$nom] = 'fond';
3556
+    }
3557
+    // attention, il ne faut pas inclure l'exec ici
3558
+    // car sinon #URL_ECRIRE provoque des inclusions
3559
+    // et des define intrusifs potentiels
3560
+    return $exec[$nom] = ((find_in_path("{$nom}.php", 'exec/') or charger_fonction($nom, 'exec', true)) ? $nom : '');
3562 3561
 }
3563 3562
 
3564 3563
 /**
@@ -3568,8 +3567,8 @@  discard block
 block discarded – undo
3568 3567
  *     true si la constante _VERSION_HTML n'est pas définie ou égale à html5
3569 3568
  **/
3570 3569
 function html5_permis() {
3571
-	return (!defined('_VERSION_HTML')
3572
-		or _VERSION_HTML !== 'html4');
3570
+    return (!defined('_VERSION_HTML')
3571
+        or _VERSION_HTML !== 'html4');
3573 3572
 }
3574 3573
 
3575 3574
 /**
@@ -3579,30 +3578,30 @@  discard block
 block discarded – undo
3579 3578
  * @return array
3580 3579
  */
3581 3580
 function formats_image_acceptables($gd = null, $svg_allowed = true) {
3582
-	$formats = null;
3583
-	if (!is_null($gd)) {
3584
-		$config = ($gd ? 'gd_formats' : 'formats_graphiques');
3585
-		if (isset($GLOBALS['meta'][$config])) {
3586
-			$formats = $GLOBALS['meta'][$config];
3587
-			$formats = explode(',', $formats);
3588
-			$formats = array_filter($formats);
3589
-			$formats = array_map('trim', $formats);
3590
-		}
3591
-	}
3592
-	if (is_null($formats)) {
3593
-		include_spip('inc/filtres_images_lib_mini');
3594
-		$formats = _image_extensions_acceptees_en_entree();
3595
-	}
3596
-
3597
-	if ($svg_allowed) {
3598
-		if (!in_array('svg', $formats)) {
3599
-			$formats[] = 'svg';
3600
-		}
3601
-	}
3602
-	else {
3603
-		$formats = array_diff($formats, ['svg']);
3604
-	}
3605
-	return $formats;
3581
+    $formats = null;
3582
+    if (!is_null($gd)) {
3583
+        $config = ($gd ? 'gd_formats' : 'formats_graphiques');
3584
+        if (isset($GLOBALS['meta'][$config])) {
3585
+            $formats = $GLOBALS['meta'][$config];
3586
+            $formats = explode(',', $formats);
3587
+            $formats = array_filter($formats);
3588
+            $formats = array_map('trim', $formats);
3589
+        }
3590
+    }
3591
+    if (is_null($formats)) {
3592
+        include_spip('inc/filtres_images_lib_mini');
3593
+        $formats = _image_extensions_acceptees_en_entree();
3594
+    }
3595
+
3596
+    if ($svg_allowed) {
3597
+        if (!in_array('svg', $formats)) {
3598
+            $formats[] = 'svg';
3599
+        }
3600
+    }
3601
+    else {
3602
+        $formats = array_diff($formats, ['svg']);
3603
+    }
3604
+    return $formats;
3606 3605
 }
3607 3606
 
3608 3607
 /**
@@ -3611,20 +3610,20 @@  discard block
 block discarded – undo
3611 3610
  * @return array|bool
3612 3611
  */
3613 3612
 function spip_getimagesize($fichier) {
3614
-	if (!$imagesize = @getimagesize($fichier)) {
3615
-		include_spip('inc/svg');
3616
-		if ($attrs = svg_lire_attributs($fichier)) {
3617
-			[$width, $height, $viewbox] = svg_getimagesize_from_attr($attrs);
3618
-			$imagesize = [
3619
-				$width,
3620
-				$height,
3621
-				IMAGETYPE_SVG,
3622
-				"width=\"{$width}\" height=\"{$height}\"",
3623
-				'mime' => 'image/svg+xml'
3624
-			];
3625
-		}
3626
-	}
3627
-	return $imagesize;
3613
+    if (!$imagesize = @getimagesize($fichier)) {
3614
+        include_spip('inc/svg');
3615
+        if ($attrs = svg_lire_attributs($fichier)) {
3616
+            [$width, $height, $viewbox] = svg_getimagesize_from_attr($attrs);
3617
+            $imagesize = [
3618
+                $width,
3619
+                $height,
3620
+                IMAGETYPE_SVG,
3621
+                "width=\"{$width}\" height=\"{$height}\"",
3622
+                'mime' => 'image/svg+xml'
3623
+            ];
3624
+        }
3625
+    }
3626
+    return $imagesize;
3628 3627
 }
3629 3628
 
3630 3629
 /**
@@ -3638,19 +3637,19 @@  discard block
 block discarded – undo
3638 3637
  * @param string $statut
3639 3638
  */
3640 3639
 function avertir_auteurs($nom, $message, $statut = '') {
3641
-	$alertes = $GLOBALS['meta']['message_alertes_auteurs'];
3642
-	if (
3643
-		!$alertes
3644
-		or !is_array($alertes = unserialize($alertes))
3645
-	) {
3646
-		$alertes = [];
3647
-	}
3640
+    $alertes = $GLOBALS['meta']['message_alertes_auteurs'];
3641
+    if (
3642
+        !$alertes
3643
+        or !is_array($alertes = unserialize($alertes))
3644
+    ) {
3645
+        $alertes = [];
3646
+    }
3648 3647
 
3649
-	if (!isset($alertes[$statut])) {
3650
-		$alertes[$statut] = [];
3651
-	}
3652
-	$alertes[$statut][$nom] = $message;
3653
-	ecrire_meta('message_alertes_auteurs', serialize($alertes));
3648
+    if (!isset($alertes[$statut])) {
3649
+        $alertes[$statut] = [];
3650
+    }
3651
+    $alertes[$statut][$nom] = $message;
3652
+    ecrire_meta('message_alertes_auteurs', serialize($alertes));
3654 3653
 }
3655 3654
 
3656 3655
 /**
@@ -3664,10 +3663,10 @@  discard block
 block discarded – undo
3664 3663
  * @return string|string[]
3665 3664
  */
3666 3665
 function spip_sanitize_classname($classes) {
3667
-	if (is_array($classes)) {
3668
-		return array_map('spip_sanitize_classname', $classes);
3669
-	}
3670
-	return preg_replace('/[^ 0-9a-z_\-+@]/i', '', $classes);
3666
+    if (is_array($classes)) {
3667
+        return array_map('spip_sanitize_classname', $classes);
3668
+    }
3669
+    return preg_replace('/[^ 0-9a-z_\-+@]/i', '', $classes);
3671 3670
 }
3672 3671
 
3673 3672
 
@@ -3692,32 +3691,32 @@  discard block
 block discarded – undo
3692 3691
  *    Avec operateur : bool.
3693 3692
  **/
3694 3693
 function spip_version_compare($v1, $v2, $op = null) {
3695
-	$v1 = strtolower(preg_replace(',([0-9])[\s.-]?(dev|alpha|a|beta|b|rc|pl|p),i', '\\1.\\2', $v1));
3696
-	$v2 = strtolower(preg_replace(',([0-9])[\s.-]?(dev|alpha|a|beta|b|rc|pl|p),i', '\\1.\\2', $v2));
3697
-	$v1 = str_replace('rc', 'RC', $v1); // certaines versions de PHP ne comprennent RC qu'en majuscule
3698
-	$v2 = str_replace('rc', 'RC', $v2); // certaines versions de PHP ne comprennent RC qu'en majuscule
3699
-
3700
-	$v1 = explode('.', $v1);
3701
-	$v2 = explode('.', $v2);
3702
-	// $v1 est toujours une version, donc sans etoile
3703
-	while (count($v1) < count($v2)) {
3704
-		$v1[] = '0';
3705
-	}
3706
-
3707
-	// $v2 peut etre une borne, donc accepte l'etoile
3708
-	$etoile = false;
3709
-	foreach ($v1 as $k => $v) {
3710
-		if (!isset($v2[$k])) {
3711
-			$v2[] = ($etoile and (is_numeric($v) or $v == 'pl' or $v == 'p')) ? $v : '0';
3712
-		} else {
3713
-			if ($v2[$k] == '*') {
3714
-				$etoile = true;
3715
-				$v2[$k] = $v;
3716
-			}
3717
-		}
3718
-	}
3719
-	$v1 = implode('.', $v1);
3720
-	$v2 = implode('.', $v2);
3721
-
3722
-	return $op ? version_compare($v1, $v2, $op) : version_compare($v1, $v2);
3694
+    $v1 = strtolower(preg_replace(',([0-9])[\s.-]?(dev|alpha|a|beta|b|rc|pl|p),i', '\\1.\\2', $v1));
3695
+    $v2 = strtolower(preg_replace(',([0-9])[\s.-]?(dev|alpha|a|beta|b|rc|pl|p),i', '\\1.\\2', $v2));
3696
+    $v1 = str_replace('rc', 'RC', $v1); // certaines versions de PHP ne comprennent RC qu'en majuscule
3697
+    $v2 = str_replace('rc', 'RC', $v2); // certaines versions de PHP ne comprennent RC qu'en majuscule
3698
+
3699
+    $v1 = explode('.', $v1);
3700
+    $v2 = explode('.', $v2);
3701
+    // $v1 est toujours une version, donc sans etoile
3702
+    while (count($v1) < count($v2)) {
3703
+        $v1[] = '0';
3704
+    }
3705
+
3706
+    // $v2 peut etre une borne, donc accepte l'etoile
3707
+    $etoile = false;
3708
+    foreach ($v1 as $k => $v) {
3709
+        if (!isset($v2[$k])) {
3710
+            $v2[] = ($etoile and (is_numeric($v) or $v == 'pl' or $v == 'p')) ? $v : '0';
3711
+        } else {
3712
+            if ($v2[$k] == '*') {
3713
+                $etoile = true;
3714
+                $v2[$k] = $v;
3715
+            }
3716
+        }
3717
+    }
3718
+    $v1 = implode('.', $v1);
3719
+    $v2 = implode('.', $v2);
3720
+
3721
+    return $op ? version_compare($v1, $v2, $op) : version_compare($v1, $v2);
3723 3722
 }
Please login to merge, or discard this patch.
ecrire/inc/filtres.php 1 patch
Indentation   +2467 added lines, -2467 removed lines patch added patch discarded remove patch
@@ -16,7 +16,7 @@  discard block
 block discarded – undo
16 16
  * @package SPIP\Core\Filtres
17 17
  **/
18 18
 if (!defined('_ECRIRE_INC_VERSION')) {
19
-	return;
19
+    return;
20 20
 }
21 21
 
22 22
 include_spip('inc/charsets');
@@ -42,8 +42,8 @@  discard block
 block discarded – undo
42 42
  * @return string Fonction PHP correspondante du filtre
43 43
  */
44 44
 function charger_filtre($fonc, $default = 'filtre_identite_dist') {
45
-	include_fichiers_fonctions(); // inclure les fichiers fonctions
46
-	return chercher_filtre($fonc, $default);
45
+    include_fichiers_fonctions(); // inclure les fichiers fonctions
46
+    return chercher_filtre($fonc, $default);
47 47
 }
48 48
 
49 49
 /**
@@ -53,7 +53,7 @@  discard block
 block discarded – undo
53 53
  * @return string Texte
54 54
  **/
55 55
 function filtre_identite_dist($texte) {
56
- return $texte;
56
+    return $texte;
57 57
 }
58 58
 
59 59
 /**
@@ -77,33 +77,33 @@  discard block
 block discarded – undo
77 77
  *     Fonction PHP correspondante du filtre demandé
78 78
  */
79 79
 function chercher_filtre($fonc, $default = null) {
80
-	if (!$fonc) {
81
-		return $default;
82
-	}
83
-	// Cas des types mime, sans confondre avec les appels de fonction de classe
84
-	// Foo::Bar
85
-	// qui peuvent etre avec un namespace : space\Foo::Bar
86
-	if (preg_match(',^[\w]+/,', $fonc)) {
87
-		$nom = preg_replace(',\W,', '_', $fonc);
88
-		$f = chercher_filtre($nom);
89
-		// cas du sous-type MIME sans filtre associe, passer au type:
90
-		// si filtre_text_plain pas defini, passe a filtre_text
91
-		if (!$f and $nom !== $fonc) {
92
-			$f = chercher_filtre(preg_replace(',\W.*$,', '', $fonc));
93
-		}
94
-
95
-		return $f;
96
-	}
97
-
98
-	include_fichiers_fonctions();
99
-	foreach (['filtre_' . $fonc, 'filtre_' . $fonc . '_dist', $fonc] as $f) {
100
-		trouver_filtre_matrice($f); // charge des fichiers spécifiques éventuels
101
-		if (is_callable($f)) {
102
-			return $f;
103
-		}
104
-	}
105
-
106
-	return $default;
80
+    if (!$fonc) {
81
+        return $default;
82
+    }
83
+    // Cas des types mime, sans confondre avec les appels de fonction de classe
84
+    // Foo::Bar
85
+    // qui peuvent etre avec un namespace : space\Foo::Bar
86
+    if (preg_match(',^[\w]+/,', $fonc)) {
87
+        $nom = preg_replace(',\W,', '_', $fonc);
88
+        $f = chercher_filtre($nom);
89
+        // cas du sous-type MIME sans filtre associe, passer au type:
90
+        // si filtre_text_plain pas defini, passe a filtre_text
91
+        if (!$f and $nom !== $fonc) {
92
+            $f = chercher_filtre(preg_replace(',\W.*$,', '', $fonc));
93
+        }
94
+
95
+        return $f;
96
+    }
97
+
98
+    include_fichiers_fonctions();
99
+    foreach (['filtre_' . $fonc, 'filtre_' . $fonc . '_dist', $fonc] as $f) {
100
+        trouver_filtre_matrice($f); // charge des fichiers spécifiques éventuels
101
+        if (is_callable($f)) {
102
+            return $f;
103
+        }
104
+    }
105
+
106
+    return $default;
107 107
 }
108 108
 
109 109
 /**
@@ -147,8 +147,8 @@  discard block
 block discarded – undo
147 147
  *     Chaîne vide sinon.
148 148
  **/
149 149
 function appliquer_filtre($arg, $filtre) {
150
-	$args = func_get_args();
151
-	return appliquer_filtre_sinon($arg, $filtre, $args, '');
150
+    $args = func_get_args();
151
+    return appliquer_filtre_sinon($arg, $filtre, $args, '');
152 152
 }
153 153
 
154 154
 /**
@@ -173,8 +173,8 @@  discard block
 block discarded – undo
173 173
  *     Texte d'origine sinon
174 174
  **/
175 175
 function appliquer_si_filtre($arg, $filtre) {
176
-	$args = func_get_args();
177
-	return appliquer_filtre_sinon($arg, $filtre, $args, $arg);
176
+    $args = func_get_args();
177
+    return appliquer_filtre_sinon($arg, $filtre, $args, $arg);
178 178
 }
179 179
 
180 180
 /**
@@ -190,12 +190,12 @@  discard block
 block discarded – undo
190 190
  *     Version de SPIP
191 191
  **/
192 192
 function spip_version() {
193
-	$version = $GLOBALS['spip_version_affichee'];
194
-	if ($vcs_version = version_vcs_courante(_DIR_RACINE)) {
195
-		$version .= " $vcs_version";
196
-	}
193
+    $version = $GLOBALS['spip_version_affichee'];
194
+    if ($vcs_version = version_vcs_courante(_DIR_RACINE)) {
195
+        $version .= " $vcs_version";
196
+    }
197 197
 
198
-	return $version;
198
+    return $version;
199 199
 }
200 200
 
201 201
 /**
@@ -207,11 +207,11 @@  discard block
 block discarded – undo
207 207
  * @return string
208 208
  */
209 209
 function header_silencieux($version): string {
210
-	if (isset($GLOBALS['spip_header_silencieux']) && (bool) $GLOBALS['spip_header_silencieux']) {
211
-		$version = '';
212
-	}
210
+    if (isset($GLOBALS['spip_header_silencieux']) && (bool) $GLOBALS['spip_header_silencieux']) {
211
+        $version = '';
212
+    }
213 213
 
214
-	return (string) $version;
214
+    return (string) $version;
215 215
 }
216 216
 
217 217
 /**
@@ -224,19 +224,19 @@  discard block
 block discarded – undo
224 224
  *    - string|null si $raw = false
225 225
  */
226 226
 function version_vcs_courante($dir, $raw = false) {
227
-	$desc = decrire_version_git($dir);
228
-	if ($desc === null) {
229
-		$desc = decrire_version_svn($dir);
230
-	}
231
-	if ($desc === null or $raw) {
232
-		return $desc;
233
-	}
234
-	// affichage "GIT [master: abcdef]"
235
-	$commit = $desc['commit_short'] ?? $desc['commit'];
236
-	if ($desc['branch']) {
237
-		$commit = $desc['branch'] . ': ' . $commit;
238
-	}
239
-	return "{$desc['vcs']} [$commit]";
227
+    $desc = decrire_version_git($dir);
228
+    if ($desc === null) {
229
+        $desc = decrire_version_svn($dir);
230
+    }
231
+    if ($desc === null or $raw) {
232
+        return $desc;
233
+    }
234
+    // affichage "GIT [master: abcdef]"
235
+    $commit = $desc['commit_short'] ?? $desc['commit'];
236
+    if ($desc['branch']) {
237
+        $commit = $desc['branch'] . ': ' . $commit;
238
+    }
239
+    return "{$desc['vcs']} [$commit]";
240 240
 }
241 241
 
242 242
 /**
@@ -248,24 +248,24 @@  discard block
 block discarded – undo
248 248
  *      array ['branch' => xx, 'commit' => yy] sinon.
249 249
  **/
250 250
 function decrire_version_git($dir) {
251
-	if (!$dir) {
252
-		$dir = '.';
253
-	}
251
+    if (!$dir) {
252
+        $dir = '.';
253
+    }
254 254
 
255
-	// version installee par GIT
256
-	if (lire_fichier($dir . '/.git/HEAD', $c)) {
257
-		$currentHead = trim(substr($c, 4));
258
-		if (lire_fichier($dir . '/.git/' . $currentHead, $hash)) {
259
-			return [
260
-				'vcs' => 'GIT',
261
-				'branch' => basename($currentHead),
262
-				'commit' => trim($hash),
263
-				'commit_short' => substr(trim($hash), 0, 8),
264
-			];
265
-		}
266
-	}
255
+    // version installee par GIT
256
+    if (lire_fichier($dir . '/.git/HEAD', $c)) {
257
+        $currentHead = trim(substr($c, 4));
258
+        if (lire_fichier($dir . '/.git/' . $currentHead, $hash)) {
259
+            return [
260
+                'vcs' => 'GIT',
261
+                'branch' => basename($currentHead),
262
+                'commit' => trim($hash),
263
+                'commit_short' => substr(trim($hash), 0, 8),
264
+            ];
265
+        }
266
+    }
267 267
 
268
-	return null;
268
+    return null;
269 269
 }
270 270
 
271 271
 
@@ -278,25 +278,25 @@  discard block
 block discarded – undo
278 278
  *      array ['commit' => yy, 'date' => xx, 'author' => xx] sinon.
279 279
  **/
280 280
 function decrire_version_svn($dir) {
281
-	if (!$dir) {
282
-		$dir = '.';
283
-	}
284
-	// version installee par SVN
285
-	if (file_exists($dir . '/.svn/wc.db') && class_exists(\SQLite3::class)) {
286
-		$db = new SQLite3($dir . '/.svn/wc.db');
287
-		$result = $db->query('SELECT changed_revision FROM nodes WHERE local_relpath = "" LIMIT 1');
288
-		if ($result) {
289
-			$row = $result->fetchArray();
290
-			if ($row['changed_revision'] != '') {
291
-				return [
292
-					'vcs' => 'SVN',
293
-					'branch' => '',
294
-					'commit' => $row['changed_revision'],
295
-				];
296
-			}
297
-		}
298
-	}
299
-	return null;
281
+    if (!$dir) {
282
+        $dir = '.';
283
+    }
284
+    // version installee par SVN
285
+    if (file_exists($dir . '/.svn/wc.db') && class_exists(\SQLite3::class)) {
286
+        $db = new SQLite3($dir . '/.svn/wc.db');
287
+        $result = $db->query('SELECT changed_revision FROM nodes WHERE local_relpath = "" LIMIT 1');
288
+        if ($result) {
289
+            $row = $result->fetchArray();
290
+            if ($row['changed_revision'] != '') {
291
+                return [
292
+                    'vcs' => 'SVN',
293
+                    'branch' => '',
294
+                    'commit' => $row['changed_revision'],
295
+                ];
296
+            }
297
+        }
298
+    }
299
+    return null;
300 300
 }
301 301
 
302 302
 // La matrice est necessaire pour ne filtrer _que_ des fonctions definies dans filtres_images
@@ -343,18 +343,18 @@  discard block
 block discarded – undo
343 343
  *     Code HTML retourné par le filtre
344 344
  **/
345 345
 function filtrer($filtre) {
346
-	$tous = func_get_args();
347
-	if (trouver_filtre_matrice($filtre) and substr($filtre, 0, 6) == 'image_') {
348
-		return image_filtrer($tous);
349
-	} elseif ($f = chercher_filtre($filtre)) {
350
-		array_shift($tous);
351
-		return $f(...$tous);
352
-	} else {
353
-		// le filtre n'existe pas, on provoque une erreur
354
-		$msg = ['zbug_erreur_filtre', ['filtre' => texte_script($filtre)]];
355
-		erreur_squelette($msg);
356
-		return '';
357
-	}
346
+    $tous = func_get_args();
347
+    if (trouver_filtre_matrice($filtre) and substr($filtre, 0, 6) == 'image_') {
348
+        return image_filtrer($tous);
349
+    } elseif ($f = chercher_filtre($filtre)) {
350
+        array_shift($tous);
351
+        return $f(...$tous);
352
+    } else {
353
+        // le filtre n'existe pas, on provoque une erreur
354
+        $msg = ['zbug_erreur_filtre', ['filtre' => texte_script($filtre)]];
355
+        erreur_squelette($msg);
356
+        return '';
357
+    }
358 358
 }
359 359
 
360 360
 /**
@@ -371,11 +371,11 @@  discard block
 block discarded – undo
371 371
  * @return bool true si on trouve le filtre dans la matrice, false sinon.
372 372
  */
373 373
 function trouver_filtre_matrice($filtre) {
374
-	if (isset($GLOBALS['spip_matrice'][$filtre]) and is_string($f = $GLOBALS['spip_matrice'][$filtre])) {
375
-		find_in_path($f, '', true);
376
-		$GLOBALS['spip_matrice'][$filtre] = true;
377
-	}
378
-	return !empty($GLOBALS['spip_matrice'][$filtre]);
374
+    if (isset($GLOBALS['spip_matrice'][$filtre]) and is_string($f = $GLOBALS['spip_matrice'][$filtre])) {
375
+        find_in_path($f, '', true);
376
+        $GLOBALS['spip_matrice'][$filtre] = true;
377
+    }
378
+    return !empty($GLOBALS['spip_matrice'][$filtre]);
379 379
 }
380 380
 
381 381
 
@@ -403,8 +403,8 @@  discard block
 block discarded – undo
403 403
  * @return mixed
404 404
  */
405 405
 function filtre_set(&$Pile, $val, $key, $continue = null) {
406
-	$Pile['vars'][$key] = $val;
407
-	return $continue ? $val : '';
406
+    $Pile['vars'][$key] = $val;
407
+    return $continue ? $val : '';
408 408
 }
409 409
 
410 410
 /**
@@ -430,8 +430,8 @@  discard block
 block discarded – undo
430 430
  * @return string|mixed Retourne `$val` si `$continue` présent, sinon ''.
431 431
  */
432 432
 function filtre_setenv(&$Pile, $val, $key, $continue = null) {
433
-	$Pile[0][$key] = $val;
434
-	return $continue ? $val : '';
433
+    $Pile[0][$key] = $val;
434
+    return $continue ? $val : '';
435 435
 }
436 436
 
437 437
 /**
@@ -440,8 +440,8 @@  discard block
 block discarded – undo
440 440
  * @return string
441 441
  */
442 442
 function filtre_sanitize_env(&$Pile, $keys) {
443
-	$Pile[0] = spip_sanitize_from_request($Pile[0], $keys);
444
-	return '';
443
+    $Pile[0] = spip_sanitize_from_request($Pile[0], $keys);
444
+    return '';
445 445
 }
446 446
 
447 447
 
@@ -464,18 +464,18 @@  discard block
 block discarded – undo
464 464
  * @return mixed Retourne la valeur (sans la modifier).
465 465
  */
466 466
 function filtre_debug($val, $key = null) {
467
-	$debug = (
468
-		is_null($key) ? '' : (var_export($key, true) . ' = ')
469
-		) . var_export($val, true);
467
+    $debug = (
468
+        is_null($key) ? '' : (var_export($key, true) . ' = ')
469
+        ) . var_export($val, true);
470 470
 
471
-	include_spip('inc/autoriser');
472
-	if (autoriser('webmestre')) {
473
-		echo "<div class='spip_debug'>\n", $debug, "</div>\n";
474
-	}
471
+    include_spip('inc/autoriser');
472
+    if (autoriser('webmestre')) {
473
+        echo "<div class='spip_debug'>\n", $debug, "</div>\n";
474
+    }
475 475
 
476
-	spip_log($debug, 'debug');
476
+    spip_log($debug, 'debug');
477 477
 
478
-	return $val;
478
+    return $val;
479 479
 }
480 480
 
481 481
 
@@ -505,84 +505,84 @@  discard block
 block discarded – undo
505 505
  *     Texte qui a reçu les filtres
506 506
  **/
507 507
 function image_filtrer($args) {
508
-	$filtre = array_shift($args); # enlever $filtre
509
-	$texte = array_shift($args);
510
-	if ($texte === null || !strlen($texte)) {
511
-		return '';
512
-	}
513
-	find_in_path('filtres_images_mini.php', 'inc/', true);
514
-	statut_effacer_images_temporaires(true); // activer la suppression des images temporaires car le compilo finit la chaine par un image_graver
515
-	// Cas du nom de fichier local
516
-	$is_file = trim($texte);
517
-	if (
518
-		strpos(substr($is_file, strlen(_DIR_RACINE)), '..') !== false
519
-		  or strpbrk($is_file, "<>\n\r\t") !== false
520
-		  or strpos($is_file, '/') === 0
521
-	) {
522
-		$is_file = false;
523
-	}
524
-	if ($is_file) {
525
-		$is_local_file = function ($path) {
526
-			if (strpos($path, '?') !== false) {
527
-				$path = supprimer_timestamp($path);
528
-				// remove ?24px added by find_in_theme on .svg files
529
-				$path = preg_replace(',\?[[:digit:]]+(px)$,', '', $path);
530
-			}
531
-			return file_exists($path);
532
-		};
533
-		if ($is_local_file($is_file) or tester_url_absolue($is_file)) {
534
-			$res = $filtre("<img src='$is_file' />", ...$args);
535
-			statut_effacer_images_temporaires(false); // desactiver pour les appels hors compilo
536
-			return $res;
537
-		}
538
-	}
539
-
540
-	// Cas general : trier toutes les images, avec eventuellement leur <span>
541
-	if (
542
-		preg_match_all(
543
-			',(<([a-z]+) [^<>]*spip_documents[^<>]*>)?\s*(<img\s.*>),UimsS',
544
-			$texte,
545
-			$tags,
546
-			PREG_SET_ORDER
547
-		)
548
-	) {
549
-		foreach ($tags as $tag) {
550
-			$class = extraire_attribut($tag[3], 'class');
551
-			if (
552
-				!$class or
553
-				(strpos($class, 'filtre_inactif') === false
554
-					// compat historique a virer en 3.2
555
-					and strpos($class, 'no_image_filtrer') === false)
556
-			) {
557
-				if ($reduit = $filtre($tag[3], ...$args)) {
558
-					// En cas de span spip_documents, modifier le style=...width:
559
-					if ($tag[1]) {
560
-						$w = extraire_attribut($reduit, 'width');
561
-						if (!$w and preg_match(',width:\s*(\d+)px,S', extraire_attribut($reduit, 'style'), $regs)) {
562
-							$w = $regs[1];
563
-						}
564
-						if ($w and ($style = extraire_attribut($tag[1], 'style'))) {
565
-							$style = preg_replace(',width:\s*\d+px,S', "width:${w}px", $style);
566
-							$replace = inserer_attribut($tag[1], 'style', $style);
567
-							$texte = str_replace($tag[1], $replace, $texte);
568
-						}
569
-					}
570
-					// traiter aussi un eventuel mouseover
571
-					if ($mouseover = extraire_attribut($reduit, 'onmouseover')) {
572
-						if (preg_match(",this[.]src=['\"]([^'\"]+)['\"],ims", $mouseover, $match)) {
573
-							$srcover = $match[1];
574
-							$srcover_filter = $filtre("<img src='" . $match[1] . "' />", ...$args);
575
-							$srcover_filter = extraire_attribut($srcover_filter, 'src');
576
-							$reduit = str_replace($srcover, $srcover_filter, $reduit);
577
-						}
578
-					}
579
-					$texte = str_replace($tag[3], $reduit, $texte);
580
-				}
581
-			}
582
-		}
583
-	}
584
-	statut_effacer_images_temporaires(false); // desactiver pour les appels hors compilo
585
-	return $texte;
508
+    $filtre = array_shift($args); # enlever $filtre
509
+    $texte = array_shift($args);
510
+    if ($texte === null || !strlen($texte)) {
511
+        return '';
512
+    }
513
+    find_in_path('filtres_images_mini.php', 'inc/', true);
514
+    statut_effacer_images_temporaires(true); // activer la suppression des images temporaires car le compilo finit la chaine par un image_graver
515
+    // Cas du nom de fichier local
516
+    $is_file = trim($texte);
517
+    if (
518
+        strpos(substr($is_file, strlen(_DIR_RACINE)), '..') !== false
519
+          or strpbrk($is_file, "<>\n\r\t") !== false
520
+          or strpos($is_file, '/') === 0
521
+    ) {
522
+        $is_file = false;
523
+    }
524
+    if ($is_file) {
525
+        $is_local_file = function ($path) {
526
+            if (strpos($path, '?') !== false) {
527
+                $path = supprimer_timestamp($path);
528
+                // remove ?24px added by find_in_theme on .svg files
529
+                $path = preg_replace(',\?[[:digit:]]+(px)$,', '', $path);
530
+            }
531
+            return file_exists($path);
532
+        };
533
+        if ($is_local_file($is_file) or tester_url_absolue($is_file)) {
534
+            $res = $filtre("<img src='$is_file' />", ...$args);
535
+            statut_effacer_images_temporaires(false); // desactiver pour les appels hors compilo
536
+            return $res;
537
+        }
538
+    }
539
+
540
+    // Cas general : trier toutes les images, avec eventuellement leur <span>
541
+    if (
542
+        preg_match_all(
543
+            ',(<([a-z]+) [^<>]*spip_documents[^<>]*>)?\s*(<img\s.*>),UimsS',
544
+            $texte,
545
+            $tags,
546
+            PREG_SET_ORDER
547
+        )
548
+    ) {
549
+        foreach ($tags as $tag) {
550
+            $class = extraire_attribut($tag[3], 'class');
551
+            if (
552
+                !$class or
553
+                (strpos($class, 'filtre_inactif') === false
554
+                    // compat historique a virer en 3.2
555
+                    and strpos($class, 'no_image_filtrer') === false)
556
+            ) {
557
+                if ($reduit = $filtre($tag[3], ...$args)) {
558
+                    // En cas de span spip_documents, modifier le style=...width:
559
+                    if ($tag[1]) {
560
+                        $w = extraire_attribut($reduit, 'width');
561
+                        if (!$w and preg_match(',width:\s*(\d+)px,S', extraire_attribut($reduit, 'style'), $regs)) {
562
+                            $w = $regs[1];
563
+                        }
564
+                        if ($w and ($style = extraire_attribut($tag[1], 'style'))) {
565
+                            $style = preg_replace(',width:\s*\d+px,S', "width:${w}px", $style);
566
+                            $replace = inserer_attribut($tag[1], 'style', $style);
567
+                            $texte = str_replace($tag[1], $replace, $texte);
568
+                        }
569
+                    }
570
+                    // traiter aussi un eventuel mouseover
571
+                    if ($mouseover = extraire_attribut($reduit, 'onmouseover')) {
572
+                        if (preg_match(",this[.]src=['\"]([^'\"]+)['\"],ims", $mouseover, $match)) {
573
+                            $srcover = $match[1];
574
+                            $srcover_filter = $filtre("<img src='" . $match[1] . "' />", ...$args);
575
+                            $srcover_filter = extraire_attribut($srcover_filter, 'src');
576
+                            $reduit = str_replace($srcover, $srcover_filter, $reduit);
577
+                        }
578
+                    }
579
+                    $texte = str_replace($tag[3], $reduit, $texte);
580
+                }
581
+            }
582
+        }
583
+    }
584
+    statut_effacer_images_temporaires(false); // desactiver pour les appels hors compilo
585
+    return $texte;
586 586
 }
587 587
 
588 588
 /**
@@ -599,91 +599,91 @@  discard block
 block discarded – undo
599 599
  **/
600 600
 function infos_image($img, $force_refresh = false) {
601 601
 
602
-	static $largeur_img = [], $hauteur_img = [], $poids_img = [];
603
-	$srcWidth = 0;
604
-	$srcHeight = 0;
605
-	$srcSize = null;
606
-
607
-	$src = extraire_attribut($img, 'src');
608
-
609
-	if (!$src) {
610
-		$src = $img;
611
-	} else {
612
-		$srcWidth = extraire_attribut($img, 'width');
613
-		$srcHeight = extraire_attribut($img, 'height');
614
-	}
615
-
616
-	// ne jamais operer directement sur une image distante pour des raisons de perfo
617
-	// la copie locale a toutes les chances d'etre la ou de resservir
618
-	if (tester_url_absolue($src)) {
619
-		include_spip('inc/distant');
620
-		$fichier = copie_locale($src);
621
-		$src = $fichier ? _DIR_RACINE . $fichier : $src;
622
-	}
623
-	if (($p = strpos($src, '?')) !== false) {
624
-		$src = substr($src, 0, $p);
625
-	}
626
-
627
-	$imagesize = false;
628
-	if (isset($largeur_img[$src]) and !$force_refresh) {
629
-		$srcWidth = $largeur_img[$src];
630
-	}
631
-	if (isset($hauteur_img[$src]) and !$force_refresh) {
632
-		$srcHeight = $hauteur_img[$src];
633
-	}
634
-	if (isset($poids_img[$src]) and !$force_refresh) {
635
-		$srcSize = $poids_img[$src];
636
-	}
637
-	if (!$srcWidth or !$srcHeight or is_null($srcSize)) {
638
-		if (
639
-			file_exists($src)
640
-			and $imagesize = spip_getimagesize($src)
641
-		) {
642
-			if (!$srcWidth) {
643
-				$largeur_img[$src] = $srcWidth = $imagesize[0];
644
-			}
645
-			if (!$srcHeight) {
646
-				$hauteur_img[$src] = $srcHeight = $imagesize[1];
647
-			}
648
-			if (!$srcSize) {
649
-				$poids_img[$src] = filesize($src);
650
-			}
651
-		}
652
-		elseif (strpos($src, '<svg') !== false) {
653
-			include_spip('inc/svg');
654
-			if ($attrs = svg_lire_attributs($src)) {
655
-				[$width, $height, $viewbox] = svg_getimagesize_from_attr($attrs);
656
-				if (!$srcWidth) {
657
-					$largeur_img[$src] = $srcWidth = $width;
658
-				}
659
-				if (!$srcHeight) {
660
-					$hauteur_img[$src] = $srcHeight = $height;
661
-				}
662
-				if (!$srcSize) {
663
-					$poids_img[$src] = $srcSize = strlen($src);
664
-				}
665
-			}
666
-		}
667
-		// $src peut etre une reference a une image temporaire dont a n'a que le log .src
668
-		// on s'y refere, l'image sera reconstruite en temps utile si necessaire
669
-		elseif (
670
-			@file_exists($f = "$src.src")
671
-			and lire_fichier($f, $valeurs)
672
-			and $valeurs = unserialize($valeurs)
673
-		) {
674
-			if (!$srcWidth) {
675
-				$largeur_img[$src] = $srcWidth = $valeurs['largeur_dest'];
676
-			}
677
-			if (!$srcHeight) {
678
-				$hauteur_img[$src] = $srcHeight = $valeurs['hauteur_dest'];
679
-			}
680
-			if (!$srcSize) {
681
-				$poids_img[$src] = $srcSize = 0;
682
-			}
683
-		}
684
-	}
685
-
686
-	return ['hauteur' => $srcHeight, 'largeur' => $srcWidth, 'poids' => $srcSize];
602
+    static $largeur_img = [], $hauteur_img = [], $poids_img = [];
603
+    $srcWidth = 0;
604
+    $srcHeight = 0;
605
+    $srcSize = null;
606
+
607
+    $src = extraire_attribut($img, 'src');
608
+
609
+    if (!$src) {
610
+        $src = $img;
611
+    } else {
612
+        $srcWidth = extraire_attribut($img, 'width');
613
+        $srcHeight = extraire_attribut($img, 'height');
614
+    }
615
+
616
+    // ne jamais operer directement sur une image distante pour des raisons de perfo
617
+    // la copie locale a toutes les chances d'etre la ou de resservir
618
+    if (tester_url_absolue($src)) {
619
+        include_spip('inc/distant');
620
+        $fichier = copie_locale($src);
621
+        $src = $fichier ? _DIR_RACINE . $fichier : $src;
622
+    }
623
+    if (($p = strpos($src, '?')) !== false) {
624
+        $src = substr($src, 0, $p);
625
+    }
626
+
627
+    $imagesize = false;
628
+    if (isset($largeur_img[$src]) and !$force_refresh) {
629
+        $srcWidth = $largeur_img[$src];
630
+    }
631
+    if (isset($hauteur_img[$src]) and !$force_refresh) {
632
+        $srcHeight = $hauteur_img[$src];
633
+    }
634
+    if (isset($poids_img[$src]) and !$force_refresh) {
635
+        $srcSize = $poids_img[$src];
636
+    }
637
+    if (!$srcWidth or !$srcHeight or is_null($srcSize)) {
638
+        if (
639
+            file_exists($src)
640
+            and $imagesize = spip_getimagesize($src)
641
+        ) {
642
+            if (!$srcWidth) {
643
+                $largeur_img[$src] = $srcWidth = $imagesize[0];
644
+            }
645
+            if (!$srcHeight) {
646
+                $hauteur_img[$src] = $srcHeight = $imagesize[1];
647
+            }
648
+            if (!$srcSize) {
649
+                $poids_img[$src] = filesize($src);
650
+            }
651
+        }
652
+        elseif (strpos($src, '<svg') !== false) {
653
+            include_spip('inc/svg');
654
+            if ($attrs = svg_lire_attributs($src)) {
655
+                [$width, $height, $viewbox] = svg_getimagesize_from_attr($attrs);
656
+                if (!$srcWidth) {
657
+                    $largeur_img[$src] = $srcWidth = $width;
658
+                }
659
+                if (!$srcHeight) {
660
+                    $hauteur_img[$src] = $srcHeight = $height;
661
+                }
662
+                if (!$srcSize) {
663
+                    $poids_img[$src] = $srcSize = strlen($src);
664
+                }
665
+            }
666
+        }
667
+        // $src peut etre une reference a une image temporaire dont a n'a que le log .src
668
+        // on s'y refere, l'image sera reconstruite en temps utile si necessaire
669
+        elseif (
670
+            @file_exists($f = "$src.src")
671
+            and lire_fichier($f, $valeurs)
672
+            and $valeurs = unserialize($valeurs)
673
+        ) {
674
+            if (!$srcWidth) {
675
+                $largeur_img[$src] = $srcWidth = $valeurs['largeur_dest'];
676
+            }
677
+            if (!$srcHeight) {
678
+                $hauteur_img[$src] = $srcHeight = $valeurs['hauteur_dest'];
679
+            }
680
+            if (!$srcSize) {
681
+                $poids_img[$src] = $srcSize = 0;
682
+            }
683
+        }
684
+    }
685
+
686
+    return ['hauteur' => $srcHeight, 'largeur' => $srcWidth, 'poids' => $srcSize];
687 687
 }
688 688
 
689 689
 /**
@@ -699,13 +699,13 @@  discard block
 block discarded – undo
699 699
  *     poids
700 700
  **/
701 701
 function poids_image($img, $force_refresh = false) {
702
-	$infos = infos_image($img, $force_refresh);
703
-	return $infos['poids'];
702
+    $infos = infos_image($img, $force_refresh);
703
+    return $infos['poids'];
704 704
 }
705 705
 
706 706
 function taille_image($img, $force_refresh = false) {
707
-	$infos = infos_image($img, $force_refresh);
708
-	return [$infos['hauteur'], $infos['largeur']];
707
+    $infos = infos_image($img, $force_refresh);
708
+    return [$infos['hauteur'], $infos['largeur']];
709 709
 }
710 710
 
711 711
 /**
@@ -722,12 +722,12 @@  discard block
 block discarded – undo
722 722
  *     Largeur en pixels, NULL ou 0 si aucune image.
723 723
  **/
724 724
 function largeur($img) {
725
-	if (!$img) {
726
-		return;
727
-	}
728
-	[$h, $l] = taille_image($img);
725
+    if (!$img) {
726
+        return;
727
+    }
728
+    [$h, $l] = taille_image($img);
729 729
 
730
-	return $l;
730
+    return $l;
731 731
 }
732 732
 
733 733
 /**
@@ -744,12 +744,12 @@  discard block
 block discarded – undo
744 744
  *     Hauteur en pixels, NULL ou 0 si aucune image.
745 745
  **/
746 746
 function hauteur($img) {
747
-	if (!$img) {
748
-		return;
749
-	}
750
-	[$h, $l] = taille_image($img);
747
+    if (!$img) {
748
+        return;
749
+    }
750
+    [$h, $l] = taille_image($img);
751 751
 
752
-	return $h;
752
+    return $h;
753 753
 }
754 754
 
755 755
 
@@ -769,11 +769,11 @@  discard block
 block discarded – undo
769 769
  * @return string
770 770
  **/
771 771
 function corriger_entites_html($texte) {
772
-	if (strpos($texte, '&amp;') === false) {
773
-		return $texte;
774
-	}
772
+    if (strpos($texte, '&amp;') === false) {
773
+        return $texte;
774
+    }
775 775
 
776
-	return preg_replace(',&amp;(#[0-9][0-9][0-9]+;|amp;),iS', '&\1', $texte);
776
+    return preg_replace(',&amp;(#[0-9][0-9][0-9]+;|amp;),iS', '&\1', $texte);
777 777
 }
778 778
 
779 779
 /**
@@ -788,11 +788,11 @@  discard block
 block discarded – undo
788 788
  * @return string
789 789
  **/
790 790
 function corriger_toutes_entites_html($texte) {
791
-	if (strpos($texte, '&amp;') === false) {
792
-		return $texte;
793
-	}
791
+    if (strpos($texte, '&amp;') === false) {
792
+        return $texte;
793
+    }
794 794
 
795
-	return preg_replace(',&amp;(#?[a-z0-9]+;),iS', '&\1', $texte);
795
+    return preg_replace(',&amp;(#?[a-z0-9]+;),iS', '&\1', $texte);
796 796
 }
797 797
 
798 798
 /**
@@ -802,7 +802,7 @@  discard block
 block discarded – undo
802 802
  * @return string
803 803
  **/
804 804
 function proteger_amp($texte) {
805
-	return str_replace('&', '&amp;', $texte);
805
+    return str_replace('&', '&amp;', $texte);
806 806
 }
807 807
 
808 808
 
@@ -833,21 +833,21 @@  discard block
 block discarded – undo
833 833
  * @return mixed|string
834 834
  */
835 835
 function entites_html($texte, $tout = false, $quote = true) {
836
-	if (
837
-		!is_string($texte) or !$texte
838
-		or strpbrk($texte, "&\"'<>") == false
839
-	) {
840
-		return $texte;
841
-	}
842
-	include_spip('inc/texte');
843
-	$flags = ($quote ? ENT_QUOTES : ENT_NOQUOTES);
844
-	$flags |= ENT_HTML401;
845
-	$texte = spip_htmlspecialchars(echappe_retour(echappe_html($texte, '', true), '', 'proteger_amp'), $flags);
846
-	if ($tout) {
847
-		return corriger_toutes_entites_html($texte);
848
-	} else {
849
-		return corriger_entites_html($texte);
850
-	}
836
+    if (
837
+        !is_string($texte) or !$texte
838
+        or strpbrk($texte, "&\"'<>") == false
839
+    ) {
840
+        return $texte;
841
+    }
842
+    include_spip('inc/texte');
843
+    $flags = ($quote ? ENT_QUOTES : ENT_NOQUOTES);
844
+    $flags |= ENT_HTML401;
845
+    $texte = spip_htmlspecialchars(echappe_retour(echappe_html($texte, '', true), '', 'proteger_amp'), $flags);
846
+    if ($tout) {
847
+        return corriger_toutes_entites_html($texte);
848
+    } else {
849
+        return corriger_entites_html($texte);
850
+    }
851 851
 }
852 852
 
853 853
 /**
@@ -866,37 +866,37 @@  discard block
 block discarded – undo
866 866
  *     Texte converti
867 867
  **/
868 868
 function filtrer_entites($texte) {
869
-	if (strpos($texte, '&') === false) {
870
-		return $texte;
871
-	}
872
-	// filtrer
873
-	$texte = html2unicode($texte);
874
-	// remettre le tout dans le charset cible
875
-	$texte = unicode2charset($texte);
876
-	// cas particulier des " et ' qu'il faut filtrer aussi
877
-	// (on le faisait deja avec un &quot;)
878
-	if (strpos($texte, '&#') !== false) {
879
-		$texte = str_replace(['&#039;', '&#39;', '&#034;', '&#34;'], ["'", "'", '"', '"'], $texte);
880
-	}
869
+    if (strpos($texte, '&') === false) {
870
+        return $texte;
871
+    }
872
+    // filtrer
873
+    $texte = html2unicode($texte);
874
+    // remettre le tout dans le charset cible
875
+    $texte = unicode2charset($texte);
876
+    // cas particulier des " et ' qu'il faut filtrer aussi
877
+    // (on le faisait deja avec un &quot;)
878
+    if (strpos($texte, '&#') !== false) {
879
+        $texte = str_replace(['&#039;', '&#39;', '&#034;', '&#34;'], ["'", "'", '"', '"'], $texte);
880
+    }
881 881
 
882
-	return $texte;
882
+    return $texte;
883 883
 }
884 884
 
885 885
 
886 886
 if (!function_exists('filtre_filtrer_entites_dist')) {
887
-	/**
888
-	 * Version sécurisée de filtrer_entites
889
-	 *
890
-	 * @uses interdire_scripts()
891
-	 * @uses filtrer_entites()
892
-	 *
893
-	 * @param string $t
894
-	 * @return string
895
-	 */
896
-	function filtre_filtrer_entites_dist($t) {
897
-		include_spip('inc/texte');
898
-		return interdire_scripts(filtrer_entites($t));
899
-	}
887
+    /**
888
+     * Version sécurisée de filtrer_entites
889
+     *
890
+     * @uses interdire_scripts()
891
+     * @uses filtrer_entites()
892
+     *
893
+     * @param string $t
894
+     * @return string
895
+     */
896
+    function filtre_filtrer_entites_dist($t) {
897
+        include_spip('inc/texte');
898
+        return interdire_scripts(filtrer_entites($t));
899
+    }
900 900
 }
901 901
 
902 902
 
@@ -911,18 +911,18 @@  discard block
 block discarded – undo
911 911
  * @return string|array
912 912
  **/
913 913
 function supprimer_caracteres_illegaux($texte) {
914
-	static $from = "\x0\x1\x2\x3\x4\x5\x6\x7\x8\xB\xC\xE\xF\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
915
-	static $to = null;
914
+    static $from = "\x0\x1\x2\x3\x4\x5\x6\x7\x8\xB\xC\xE\xF\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
915
+    static $to = null;
916 916
 
917
-	if (is_array($texte)) {
918
-		return array_map('supprimer_caracteres_illegaux', $texte);
919
-	}
917
+    if (is_array($texte)) {
918
+        return array_map('supprimer_caracteres_illegaux', $texte);
919
+    }
920 920
 
921
-	if (!$to) {
922
-		$to = str_repeat('-', strlen($from));
923
-	}
921
+    if (!$to) {
922
+        $to = str_repeat('-', strlen($from));
923
+    }
924 924
 
925
-	return strtr($texte, $from, $to);
925
+    return strtr($texte, $from, $to);
926 926
 }
927 927
 
928 928
 /**
@@ -934,10 +934,10 @@  discard block
 block discarded – undo
934 934
  * @return string|array
935 935
  **/
936 936
 function corriger_caracteres($texte) {
937
-	$texte = corriger_caracteres_windows($texte);
938
-	$texte = supprimer_caracteres_illegaux($texte);
937
+    $texte = corriger_caracteres_windows($texte);
938
+    $texte = supprimer_caracteres_illegaux($texte);
939 939
 
940
-	return $texte;
940
+    return $texte;
941 941
 }
942 942
 
943 943
 /**
@@ -954,44 +954,44 @@  discard block
 block discarded – undo
954 954
  *     Texte encodé pour XML
955 955
  */
956 956
 function texte_backend(string $texte): string {
957
-	if ($texte === '') {
958
-		return '';
959
-	}
957
+    if ($texte === '') {
958
+        return '';
959
+    }
960 960
 
961
-	static $apostrophe = ['&#8217;', "'"]; # n'allouer qu'une fois
961
+    static $apostrophe = ['&#8217;', "'"]; # n'allouer qu'une fois
962 962
 
963
-	// si on a des liens ou des images, les passer en absolu
964
-	$texte = liens_absolus($texte);
963
+    // si on a des liens ou des images, les passer en absolu
964
+    $texte = liens_absolus($texte);
965 965
 
966
-	// echapper les tags &gt; &lt;
967
-	$texte = preg_replace(',&(gt|lt);,S', '&amp;\1;', $texte);
966
+    // echapper les tags &gt; &lt;
967
+    $texte = preg_replace(',&(gt|lt);,S', '&amp;\1;', $texte);
968 968
 
969
-	// importer les &eacute;
970
-	$texte = filtrer_entites($texte);
969
+    // importer les &eacute;
970
+    $texte = filtrer_entites($texte);
971 971
 
972
-	// " -> &quot; et tout ce genre de choses
973
-	$u = $GLOBALS['meta']['pcre_u'];
974
-	$texte = str_replace('&nbsp;', ' ', $texte);
975
-	$texte = preg_replace('/\s{2,}/S' . $u, ' ', $texte);
976
-	// ne pas echapper les sinqle quotes car certains outils de syndication gerent mal
977
-	$texte = entites_html($texte, false, false);
978
-	// mais bien echapper les double quotes !
979
-	$texte = str_replace('"', '&#034;', $texte);
972
+    // " -> &quot; et tout ce genre de choses
973
+    $u = $GLOBALS['meta']['pcre_u'];
974
+    $texte = str_replace('&nbsp;', ' ', $texte);
975
+    $texte = preg_replace('/\s{2,}/S' . $u, ' ', $texte);
976
+    // ne pas echapper les sinqle quotes car certains outils de syndication gerent mal
977
+    $texte = entites_html($texte, false, false);
978
+    // mais bien echapper les double quotes !
979
+    $texte = str_replace('"', '&#034;', $texte);
980 980
 
981
-	// verifier le charset
982
-	$texte = charset2unicode($texte);
981
+    // verifier le charset
982
+    $texte = charset2unicode($texte);
983 983
 
984
-	// Caracteres problematiques en iso-latin 1
985
-	if (isset($GLOBALS['meta']['charset']) and $GLOBALS['meta']['charset'] == 'iso-8859-1') {
986
-		$texte = str_replace(chr(156), '&#156;', $texte);
987
-		$texte = str_replace(chr(140), '&#140;', $texte);
988
-		$texte = str_replace(chr(159), '&#159;', $texte);
989
-	}
984
+    // Caracteres problematiques en iso-latin 1
985
+    if (isset($GLOBALS['meta']['charset']) and $GLOBALS['meta']['charset'] == 'iso-8859-1') {
986
+        $texte = str_replace(chr(156), '&#156;', $texte);
987
+        $texte = str_replace(chr(140), '&#140;', $texte);
988
+        $texte = str_replace(chr(159), '&#159;', $texte);
989
+    }
990 990
 
991
-	// l'apostrophe curly pose probleme a certains lecteure de RSS
992
-	// et le caractere apostrophe alourdit les squelettes avec PHP
993
-	// ==> on les remplace par l'entite HTML
994
-	return str_replace($apostrophe, "'", $texte);
991
+    // l'apostrophe curly pose probleme a certains lecteure de RSS
992
+    // et le caractere apostrophe alourdit les squelettes avec PHP
993
+    // ==> on les remplace par l'entite HTML
994
+    return str_replace($apostrophe, "'", $texte);
995 995
 }
996 996
 
997 997
 /**
@@ -1008,7 +1008,7 @@  discard block
 block discarded – undo
1008 1008
  *     Texte encodé et quote pour XML
1009 1009
  */
1010 1010
 function texte_backendq(string $texte): string {
1011
-	return addslashes(texte_backend($texte));
1011
+    return addslashes(texte_backend($texte));
1012 1012
 }
1013 1013
 
1014 1014
 
@@ -1031,11 +1031,11 @@  discard block
 block discarded – undo
1031 1031
  *     Numéro de titre, sinon chaîne vide
1032 1032
  **/
1033 1033
 function supprimer_numero($texte) {
1034
-	return preg_replace(
1035
-		',^[[:space:]]*([0-9]+)([.)]|' . chr(194) . '?' . chr(176) . ')[[:space:]]+,S',
1036
-		'',
1037
-		$texte
1038
-	);
1034
+    return preg_replace(
1035
+        ',^[[:space:]]*([0-9]+)([.)]|' . chr(194) . '?' . chr(176) . ')[[:space:]]+,S',
1036
+        '',
1037
+        $texte
1038
+    );
1039 1039
 }
1040 1040
 
1041 1041
 /**
@@ -1058,17 +1058,17 @@  discard block
 block discarded – undo
1058 1058
  *     Numéro de titre, sinon chaîne vide
1059 1059
  **/
1060 1060
 function recuperer_numero($texte) {
1061
-	if (
1062
-		preg_match(
1063
-			',^[[:space:]]*([0-9]+)([.)]|' . chr(194) . '?' . chr(176) . ')[[:space:]]+,S',
1064
-			$texte,
1065
-			$regs
1066
-		)
1067
-	) {
1068
-		return strval($regs[1]);
1069
-	} else {
1070
-		return '';
1071
-	}
1061
+    if (
1062
+        preg_match(
1063
+            ',^[[:space:]]*([0-9]+)([.)]|' . chr(194) . '?' . chr(176) . ')[[:space:]]+,S',
1064
+            $texte,
1065
+            $regs
1066
+        )
1067
+    ) {
1068
+        return strval($regs[1]);
1069
+    } else {
1070
+        return '';
1071
+    }
1072 1072
 }
1073 1073
 
1074 1074
 /**
@@ -1095,16 +1095,16 @@  discard block
 block discarded – undo
1095 1095
  *     Texte ou tableau de textes converti
1096 1096
  **/
1097 1097
 function supprimer_tags($texte, $rempl = '') {
1098
-	if ($texte === null) {
1099
-		return '';
1100
-	}
1101
-	$texte = preg_replace(',<(!--|\w|/|!\[endif|!\[if)[^>]*>,US', $rempl, $texte);
1102
-	// ne pas oublier un < final non ferme car coupe
1103
-	$texte = preg_replace(',<(!--|\w|/).*$,US', $rempl, $texte);
1104
-	// mais qui peut aussi etre un simple signe plus petit que
1105
-	$texte = str_replace('<', '&lt;', $texte);
1098
+    if ($texte === null) {
1099
+        return '';
1100
+    }
1101
+    $texte = preg_replace(',<(!--|\w|/|!\[endif|!\[if)[^>]*>,US', $rempl, $texte);
1102
+    // ne pas oublier un < final non ferme car coupe
1103
+    $texte = preg_replace(',<(!--|\w|/).*$,US', $rempl, $texte);
1104
+    // mais qui peut aussi etre un simple signe plus petit que
1105
+    $texte = str_replace('<', '&lt;', $texte);
1106 1106
 
1107
-	return $texte;
1107
+    return $texte;
1108 1108
 }
1109 1109
 
1110 1110
 /**
@@ -1127,9 +1127,9 @@  discard block
 block discarded – undo
1127 1127
  *     Texte converti
1128 1128
  **/
1129 1129
 function echapper_tags($texte, $rempl = '') {
1130
-	$texte = preg_replace('/<([^>]*)>/', "&lt;\\1&gt;", $texte);
1130
+    $texte = preg_replace('/<([^>]*)>/', "&lt;\\1&gt;", $texte);
1131 1131
 
1132
-	return $texte;
1132
+    return $texte;
1133 1133
 }
1134 1134
 
1135 1135
 /**
@@ -1150,18 +1150,18 @@  discard block
 block discarded – undo
1150 1150
  *     Texte converti
1151 1151
  **/
1152 1152
 function textebrut($texte) {
1153
-	$u = $GLOBALS['meta']['pcre_u'];
1154
-	$texte = preg_replace('/\s+/S' . $u, ' ', $texte);
1155
-	$texte = preg_replace('/<(p|br)( [^>]*)?' . '>/iS', "\n\n", $texte);
1156
-	$texte = preg_replace("/^\n+/", '', $texte);
1157
-	$texte = preg_replace("/\n+$/", '', $texte);
1158
-	$texte = preg_replace("/\n +/", "\n", $texte);
1159
-	$texte = supprimer_tags($texte);
1160
-	$texte = preg_replace('/(&nbsp;| )+/S', ' ', $texte);
1161
-	// nettoyer l'apostrophe curly qui pose probleme a certains rss-readers, lecteurs de mail...
1162
-	$texte = str_replace('&#8217;', "'", $texte);
1153
+    $u = $GLOBALS['meta']['pcre_u'];
1154
+    $texte = preg_replace('/\s+/S' . $u, ' ', $texte);
1155
+    $texte = preg_replace('/<(p|br)( [^>]*)?' . '>/iS', "\n\n", $texte);
1156
+    $texte = preg_replace("/^\n+/", '', $texte);
1157
+    $texte = preg_replace("/\n+$/", '', $texte);
1158
+    $texte = preg_replace("/\n +/", "\n", $texte);
1159
+    $texte = supprimer_tags($texte);
1160
+    $texte = preg_replace('/(&nbsp;| )+/S', ' ', $texte);
1161
+    // nettoyer l'apostrophe curly qui pose probleme a certains rss-readers, lecteurs de mail...
1162
+    $texte = str_replace('&#8217;', "'", $texte);
1163 1163
 
1164
-	return $texte;
1164
+    return $texte;
1165 1165
 }
1166 1166
 
1167 1167
 
@@ -1177,23 +1177,23 @@  discard block
 block discarded – undo
1177 1177
  *     Texte avec liens ouvrants
1178 1178
  **/
1179 1179
 function liens_ouvrants($texte) {
1180
-	if (
1181
-		preg_match_all(
1182
-			",(<a\s+[^>]*https?://[^>]*class=[\"']spip_(out|url)\b[^>]+>),imsS",
1183
-			$texte,
1184
-			$liens,
1185
-			PREG_PATTERN_ORDER
1186
-		)
1187
-	) {
1188
-		foreach ($liens[0] as $a) {
1189
-			$rel = 'noopener noreferrer ' . extraire_attribut($a, 'rel');
1190
-			$ablank = inserer_attribut($a, 'rel', $rel);
1191
-			$ablank = inserer_attribut($ablank, 'target', '_blank');
1192
-			$texte = str_replace($a, $ablank, $texte);
1193
-		}
1194
-	}
1195
-
1196
-	return $texte;
1180
+    if (
1181
+        preg_match_all(
1182
+            ",(<a\s+[^>]*https?://[^>]*class=[\"']spip_(out|url)\b[^>]+>),imsS",
1183
+            $texte,
1184
+            $liens,
1185
+            PREG_PATTERN_ORDER
1186
+        )
1187
+    ) {
1188
+        foreach ($liens[0] as $a) {
1189
+            $rel = 'noopener noreferrer ' . extraire_attribut($a, 'rel');
1190
+            $ablank = inserer_attribut($a, 'rel', $rel);
1191
+            $ablank = inserer_attribut($ablank, 'target', '_blank');
1192
+            $texte = str_replace($a, $ablank, $texte);
1193
+        }
1194
+    }
1195
+
1196
+    return $texte;
1197 1197
 }
1198 1198
 
1199 1199
 /**
@@ -1203,22 +1203,22 @@  discard block
 block discarded – undo
1203 1203
  * @return string
1204 1204
  */
1205 1205
 function liens_nofollow($texte) {
1206
-	if (stripos($texte, '<a') === false) {
1207
-		return $texte;
1208
-	}
1206
+    if (stripos($texte, '<a') === false) {
1207
+        return $texte;
1208
+    }
1209 1209
 
1210
-	if (preg_match_all(",<a\b[^>]*>,UimsS", $texte, $regs, PREG_PATTERN_ORDER)) {
1211
-		foreach ($regs[0] as $a) {
1212
-			$rel = extraire_attribut($a, 'rel') ?? '';
1213
-			if (strpos($rel, 'nofollow') === false) {
1214
-				$rel = 'nofollow' . ($rel ? " $rel" : '');
1215
-				$anofollow = inserer_attribut($a, 'rel', $rel);
1216
-				$texte = str_replace($a, $anofollow, $texte);
1217
-			}
1218
-		}
1219
-	}
1210
+    if (preg_match_all(",<a\b[^>]*>,UimsS", $texte, $regs, PREG_PATTERN_ORDER)) {
1211
+        foreach ($regs[0] as $a) {
1212
+            $rel = extraire_attribut($a, 'rel') ?? '';
1213
+            if (strpos($rel, 'nofollow') === false) {
1214
+                $rel = 'nofollow' . ($rel ? " $rel" : '');
1215
+                $anofollow = inserer_attribut($a, 'rel', $rel);
1216
+                $texte = str_replace($a, $anofollow, $texte);
1217
+            }
1218
+        }
1219
+    }
1220 1220
 
1221
-	return $texte;
1221
+    return $texte;
1222 1222
 }
1223 1223
 
1224 1224
 /**
@@ -1237,12 +1237,12 @@  discard block
 block discarded – undo
1237 1237
  *     Texte sans paraghaphes
1238 1238
  **/
1239 1239
 function PtoBR($texte) {
1240
-	$u = $GLOBALS['meta']['pcre_u'];
1241
-	$texte = preg_replace('@</p>@iS', "\n", $texte);
1242
-	$texte = preg_replace("@<p\b.*>@UiS", '<br />', $texte);
1243
-	$texte = preg_replace('@^\s*<br />@S' . $u, '', $texte);
1240
+    $u = $GLOBALS['meta']['pcre_u'];
1241
+    $texte = preg_replace('@</p>@iS', "\n", $texte);
1242
+    $texte = preg_replace("@<p\b.*>@UiS", '<br />', $texte);
1243
+    $texte = preg_replace('@^\s*<br />@S' . $u, '', $texte);
1244 1244
 
1245
-	return $texte;
1245
+    return $texte;
1246 1246
 }
1247 1247
 
1248 1248
 
@@ -1267,14 +1267,14 @@  discard block
 block discarded – undo
1267 1267
  * @return string Texte encadré du style CSS
1268 1268
  */
1269 1269
 function lignes_longues($texte) {
1270
-	if (!strlen(trim($texte))) {
1271
-		return $texte;
1272
-	}
1273
-	include_spip('inc/texte');
1274
-	$tag = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $texte) ?
1275
-		'div' : 'span';
1270
+    if (!strlen(trim($texte))) {
1271
+        return $texte;
1272
+    }
1273
+    include_spip('inc/texte');
1274
+    $tag = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $texte) ?
1275
+        'div' : 'span';
1276 1276
 
1277
-	return "<$tag style='word-wrap:break-word;'>$texte</$tag>";
1277
+    return "<$tag style='word-wrap:break-word;'>$texte</$tag>";
1278 1278
 }
1279 1279
 
1280 1280
 /**
@@ -1293,30 +1293,30 @@  discard block
 block discarded – undo
1293 1293
  * @return string Texte en majuscule
1294 1294
  */
1295 1295
 function majuscules($texte) {
1296
-	if (!strlen($texte)) {
1297
-		return '';
1298
-	}
1296
+    if (!strlen($texte)) {
1297
+        return '';
1298
+    }
1299 1299
 
1300
-	// Cas du turc
1301
-	if ($GLOBALS['spip_lang'] == 'tr') {
1302
-		# remplacer hors des tags et des entites
1303
-		if (preg_match_all(',<[^<>]+>|&[^;]+;,S', $texte, $regs, PREG_SET_ORDER)) {
1304
-			foreach ($regs as $n => $match) {
1305
-				$texte = str_replace($match[0], "@@SPIP_TURC$n@@", $texte);
1306
-			}
1307
-		}
1300
+    // Cas du turc
1301
+    if ($GLOBALS['spip_lang'] == 'tr') {
1302
+        # remplacer hors des tags et des entites
1303
+        if (preg_match_all(',<[^<>]+>|&[^;]+;,S', $texte, $regs, PREG_SET_ORDER)) {
1304
+            foreach ($regs as $n => $match) {
1305
+                $texte = str_replace($match[0], "@@SPIP_TURC$n@@", $texte);
1306
+            }
1307
+        }
1308 1308
 
1309
-		$texte = str_replace('i', '&#304;', $texte);
1309
+        $texte = str_replace('i', '&#304;', $texte);
1310 1310
 
1311
-		if ($regs) {
1312
-			foreach ($regs as $n => $match) {
1313
-				$texte = str_replace("@@SPIP_TURC$n@@", $match[0], $texte);
1314
-			}
1315
-		}
1316
-	}
1311
+        if ($regs) {
1312
+            foreach ($regs as $n => $match) {
1313
+                $texte = str_replace("@@SPIP_TURC$n@@", $match[0], $texte);
1314
+            }
1315
+        }
1316
+    }
1317 1317
 
1318
-	// Cas general
1319
-	return "<span style='text-transform: uppercase;'>$texte</span>";
1318
+    // Cas general
1319
+    return "<span style='text-transform: uppercase;'>$texte</span>";
1320 1320
 }
1321 1321
 
1322 1322
 /**
@@ -1334,29 +1334,29 @@  discard block
 block discarded – undo
1334 1334
  * @return string
1335 1335
  **/
1336 1336
 function taille_en_octets($taille) {
1337
-	if (!defined('_KILOBYTE')) {
1338
-		/**
1339
-		 * Définit le nombre d'octets dans un Kilobyte
1340
-		 *
1341
-		 * @var int
1342
-		 **/
1343
-		define('_KILOBYTE', 1024);
1344
-	}
1337
+    if (!defined('_KILOBYTE')) {
1338
+        /**
1339
+         * Définit le nombre d'octets dans un Kilobyte
1340
+         *
1341
+         * @var int
1342
+         **/
1343
+        define('_KILOBYTE', 1024);
1344
+    }
1345 1345
 
1346
-	if ($taille < 1) {
1347
-		return '';
1348
-	}
1349
-	if ($taille < _KILOBYTE) {
1350
-		$taille = _T('taille_octets', ['taille' => $taille]);
1351
-	} elseif ($taille < _KILOBYTE * _KILOBYTE) {
1352
-		$taille = _T('taille_ko', ['taille' => round($taille / _KILOBYTE, 1)]);
1353
-	} elseif ($taille < _KILOBYTE * _KILOBYTE * _KILOBYTE) {
1354
-		$taille = _T('taille_mo', ['taille' => round($taille / _KILOBYTE / _KILOBYTE, 1)]);
1355
-	} else {
1356
-		$taille = _T('taille_go', ['taille' => round($taille / _KILOBYTE / _KILOBYTE / _KILOBYTE, 2)]);
1357
-	}
1346
+    if ($taille < 1) {
1347
+        return '';
1348
+    }
1349
+    if ($taille < _KILOBYTE) {
1350
+        $taille = _T('taille_octets', ['taille' => $taille]);
1351
+    } elseif ($taille < _KILOBYTE * _KILOBYTE) {
1352
+        $taille = _T('taille_ko', ['taille' => round($taille / _KILOBYTE, 1)]);
1353
+    } elseif ($taille < _KILOBYTE * _KILOBYTE * _KILOBYTE) {
1354
+        $taille = _T('taille_mo', ['taille' => round($taille / _KILOBYTE / _KILOBYTE, 1)]);
1355
+    } else {
1356
+        $taille = _T('taille_go', ['taille' => round($taille / _KILOBYTE / _KILOBYTE / _KILOBYTE, 2)]);
1357
+    }
1358 1358
 
1359
-	return $taille;
1359
+    return $taille;
1360 1360
 }
1361 1361
 
1362 1362
 
@@ -1378,21 +1378,21 @@  discard block
 block discarded – undo
1378 1378
  *     Texte prêt pour être utilisé en attribut HTML
1379 1379
  **/
1380 1380
 function attribut_html(?string $texte, $textebrut = true): string {
1381
-	if ($texte === null) {
1382
-		return '';
1383
-	}
1384
-	$u = $GLOBALS['meta']['pcre_u'];
1385
-	if ($textebrut) {
1386
-		$texte = preg_replace([",\n,", ',\s(?=\s),msS' . $u], [' ', ''], textebrut($texte));
1387
-	}
1388
-	$texte = texte_backend($texte);
1389
-	$texte = str_replace(["'", '"'], ['&#039;', '&#034;'], $texte);
1381
+    if ($texte === null) {
1382
+        return '';
1383
+    }
1384
+    $u = $GLOBALS['meta']['pcre_u'];
1385
+    if ($textebrut) {
1386
+        $texte = preg_replace([",\n,", ',\s(?=\s),msS' . $u], [' ', ''], textebrut($texte));
1387
+    }
1388
+    $texte = texte_backend($texte);
1389
+    $texte = str_replace(["'", '"'], ['&#039;', '&#034;'], $texte);
1390 1390
 
1391
-	return preg_replace(
1392
-		['/&(amp;|#38;)/', '/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/'],
1393
-		['&', '&#38;'],
1394
-		$texte
1395
-	);
1391
+    return preg_replace(
1392
+        ['/&(amp;|#38;)/', '/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/'],
1393
+        ['&', '&#38;'],
1394
+        $texte
1395
+    );
1396 1396
 }
1397 1397
 
1398 1398
 
@@ -1412,15 +1412,15 @@  discard block
 block discarded – undo
1412 1412
  *     URL ou chaîne vide
1413 1413
  **/
1414 1414
 function vider_url(?string $url, $entites = true): string {
1415
-	if ($url === null) {
1416
-		return '';
1417
-	}
1418
-	# un message pour abs_url
1419
-	$GLOBALS['mode_abs_url'] = 'url';
1420
-	$url = trim($url);
1421
-	$r = ',^(?:' . _PROTOCOLES_STD . '):?/?/?$,iS';
1415
+    if ($url === null) {
1416
+        return '';
1417
+    }
1418
+    # un message pour abs_url
1419
+    $GLOBALS['mode_abs_url'] = 'url';
1420
+    $url = trim($url);
1421
+    $r = ',^(?:' . _PROTOCOLES_STD . '):?/?/?$,iS';
1422 1422
 
1423
-	return preg_match($r, $url) ? '' : ($entites ? entites_html($url) : $url);
1423
+    return preg_match($r, $url) ? '' : ($entites ? entites_html($url) : $url);
1424 1424
 }
1425 1425
 
1426 1426
 
@@ -1435,10 +1435,10 @@  discard block
 block discarded – undo
1435 1435
  * @return string Adresse email maquillée
1436 1436
  **/
1437 1437
 function antispam($texte) {
1438
-	include_spip('inc/acces');
1439
-	$masque = creer_pass_aleatoire(3);
1438
+    include_spip('inc/acces');
1439
+    $masque = creer_pass_aleatoire(3);
1440 1440
 
1441
-	return preg_replace('/@/', " $masque ", $texte);
1441
+    return preg_replace('/@/', " $masque ", $texte);
1442 1442
 }
1443 1443
 
1444 1444
 /**
@@ -1470,8 +1470,8 @@  discard block
 block discarded – undo
1470 1470
  *     True si on a le droit d'accès, false sinon.
1471 1471
  **/
1472 1472
 function filtre_securiser_acces_dist($id_auteur, $cle, $dir, $op = '', $args = '') {
1473
-	include_spip('inc/acces');
1474
-	return securiser_acces_low_sec($id_auteur, $cle, $op ? "$dir $op $args" : $dir);
1473
+    include_spip('inc/acces');
1474
+    return securiser_acces_low_sec($id_auteur, $cle, $op ? "$dir $op $args" : $dir);
1475 1475
 }
1476 1476
 
1477 1477
 /**
@@ -1496,13 +1496,13 @@  discard block
 block discarded – undo
1496 1496
  *     Retourne $texte, sinon $sinon.
1497 1497
  **/
1498 1498
 function sinon($texte, $sinon = '') {
1499
-	if ($texte) {
1500
-		return $texte;
1501
-	} elseif (is_scalar($texte) and strlen($texte)) {
1502
-		return $texte;
1503
-	} else {
1504
-		return $sinon;
1505
-	}
1499
+    if ($texte) {
1500
+        return $texte;
1501
+    } elseif (is_scalar($texte) and strlen($texte)) {
1502
+        return $texte;
1503
+    } else {
1504
+        return $sinon;
1505
+    }
1506 1506
 }
1507 1507
 
1508 1508
 /**
@@ -1526,7 +1526,7 @@  discard block
 block discarded – undo
1526 1526
  * @return mixed
1527 1527
  **/
1528 1528
 function choixsivide($a, $vide, $pasvide) {
1529
-	return $a ? $pasvide : $vide;
1529
+    return $a ? $pasvide : $vide;
1530 1530
 }
1531 1531
 
1532 1532
 /**
@@ -1550,7 +1550,7 @@  discard block
 block discarded – undo
1550 1550
  * @return mixed
1551 1551
  **/
1552 1552
 function choixsiegal($a1, $a2, $v, $f) {
1553
-	return ($a1 == $a2) ? $v : $f;
1553
+    return ($a1 == $a2) ? $v : $f;
1554 1554
 }
1555 1555
 
1556 1556
 //
@@ -1569,13 +1569,13 @@  discard block
 block discarded – undo
1569 1569
  * @return string
1570 1570
  **/
1571 1571
 function filtrer_ical($texte) {
1572
-	#include_spip('inc/charsets');
1573
-	$texte = html2unicode($texte);
1574
-	$texte = unicode2charset(charset2unicode($texte, $GLOBALS['meta']['charset']), 'utf-8');
1575
-	$texte = preg_replace("/\n/", ' ', $texte);
1576
-	$texte = preg_replace('/,/', '\,', $texte);
1572
+    #include_spip('inc/charsets');
1573
+    $texte = html2unicode($texte);
1574
+    $texte = unicode2charset(charset2unicode($texte, $GLOBALS['meta']['charset']), 'utf-8');
1575
+    $texte = preg_replace("/\n/", ' ', $texte);
1576
+    $texte = preg_replace('/,/', '\,', $texte);
1577 1577
 
1578
-	return $texte;
1578
+    return $texte;
1579 1579
 }
1580 1580
 
1581 1581
 
@@ -1600,54 +1600,54 @@  discard block
 block discarded – undo
1600 1600
  * @return string
1601 1601
  **/
1602 1602
 function post_autobr($texte, $delim = "\n_ ") {
1603
-	if (!function_exists('echappe_html')) {
1604
-		include_spip('inc/texte_mini');
1605
-	}
1606
-	$texte = str_replace("\r\n", "\r", $texte);
1607
-	$texte = str_replace("\r", "\n", $texte);
1608
-
1609
-	if (preg_match(",\n+$,", $texte, $fin)) {
1610
-		$texte = substr($texte, 0, -strlen($fin = $fin[0]));
1611
-	} else {
1612
-		$fin = '';
1613
-	}
1614
-
1615
-	$texte = echappe_html($texte, '', true);
1616
-
1617
-	// echapper les modeles
1618
-	if (strpos($texte, '<') !== false) {
1619
-		include_spip('inc/lien');
1620
-		if (defined('_PREG_MODELE')) {
1621
-			$preg_modeles = '@' . _PREG_MODELE . '@imsS';
1622
-			$texte = echappe_html($texte, '', true, $preg_modeles);
1623
-		}
1624
-	}
1625
-
1626
-	$debut = '';
1627
-	$suite = $texte;
1628
-	while ($t = strpos('-' . $suite, "\n", 1)) {
1629
-		$debut .= substr($suite, 0, $t - 1);
1630
-		$suite = substr($suite, $t);
1631
-		$car = substr($suite, 0, 1);
1632
-		if (
1633
-			($car <> '-') and ($car <> '_') and ($car <> "\n") and ($car <> '|') and ($car <> '}')
1634
-			and !preg_match(',^\s*(\n|</?(quote|div|dl|dt|dd)|$),S', ($suite))
1635
-			and !preg_match(',</?(quote|div|dl|dt|dd)> *$,iS', $debut)
1636
-		) {
1637
-			$debut .= $delim;
1638
-		} else {
1639
-			$debut .= "\n";
1640
-		}
1641
-		if (preg_match(",^\n+,", $suite, $regs)) {
1642
-			$debut .= $regs[0];
1643
-			$suite = substr($suite, strlen($regs[0]));
1644
-		}
1645
-	}
1646
-	$texte = $debut . $suite;
1647
-
1648
-	$texte = echappe_retour($texte);
1649
-
1650
-	return $texte . $fin;
1603
+    if (!function_exists('echappe_html')) {
1604
+        include_spip('inc/texte_mini');
1605
+    }
1606
+    $texte = str_replace("\r\n", "\r", $texte);
1607
+    $texte = str_replace("\r", "\n", $texte);
1608
+
1609
+    if (preg_match(",\n+$,", $texte, $fin)) {
1610
+        $texte = substr($texte, 0, -strlen($fin = $fin[0]));
1611
+    } else {
1612
+        $fin = '';
1613
+    }
1614
+
1615
+    $texte = echappe_html($texte, '', true);
1616
+
1617
+    // echapper les modeles
1618
+    if (strpos($texte, '<') !== false) {
1619
+        include_spip('inc/lien');
1620
+        if (defined('_PREG_MODELE')) {
1621
+            $preg_modeles = '@' . _PREG_MODELE . '@imsS';
1622
+            $texte = echappe_html($texte, '', true, $preg_modeles);
1623
+        }
1624
+    }
1625
+
1626
+    $debut = '';
1627
+    $suite = $texte;
1628
+    while ($t = strpos('-' . $suite, "\n", 1)) {
1629
+        $debut .= substr($suite, 0, $t - 1);
1630
+        $suite = substr($suite, $t);
1631
+        $car = substr($suite, 0, 1);
1632
+        if (
1633
+            ($car <> '-') and ($car <> '_') and ($car <> "\n") and ($car <> '|') and ($car <> '}')
1634
+            and !preg_match(',^\s*(\n|</?(quote|div|dl|dt|dd)|$),S', ($suite))
1635
+            and !preg_match(',</?(quote|div|dl|dt|dd)> *$,iS', $debut)
1636
+        ) {
1637
+            $debut .= $delim;
1638
+        } else {
1639
+            $debut .= "\n";
1640
+        }
1641
+        if (preg_match(",^\n+,", $suite, $regs)) {
1642
+            $debut .= $regs[0];
1643
+            $suite = substr($suite, strlen($regs[0]));
1644
+        }
1645
+    }
1646
+    $texte = $debut . $suite;
1647
+
1648
+    $texte = echappe_retour($texte);
1649
+
1650
+    return $texte . $fin;
1651 1651
 }
1652 1652
 
1653 1653
 
@@ -1688,47 +1688,47 @@  discard block
 block discarded – undo
1688 1688
  * @return string
1689 1689
  **/
1690 1690
 function extraire_idiome($letexte, $lang = null, $options = []) {
1691
-	static $traduire = false;
1692
-	if (
1693
-		$letexte
1694
-		and preg_match_all(_EXTRAIRE_IDIOME, $letexte, $regs, PREG_SET_ORDER)
1695
-	) {
1696
-		if (!$traduire) {
1697
-			$traduire = charger_fonction('traduire', 'inc');
1698
-			include_spip('inc/lang');
1699
-		}
1700
-		if (!$lang) {
1701
-			$lang = $GLOBALS['spip_lang'];
1702
-		}
1703
-		// Compatibilité avec le prototype de fonction précédente qui utilisait un boolean
1704
-		if (is_bool($options)) {
1705
-			$options = ['echappe_span' => $options];
1706
-		}
1707
-		if (!isset($options['echappe_span'])) {
1708
-			$options = array_merge($options, ['echappe_span' => false]);
1709
-		}
1710
-
1711
-		foreach ($regs as $reg) {
1712
-			$cle = ($reg[1] ? $reg[1] . ':' : '') . $reg[2];
1713
-			$desc = $traduire($cle, $lang, true);
1714
-			$l = $desc->langue;
1715
-			// si pas de traduction, on laissera l'écriture de l'idiome entier dans le texte.
1716
-			if (strlen($desc->texte ?? '')) {
1717
-				$trad = code_echappement($desc->texte, 'idiome', false);
1718
-				if ($l !== $lang) {
1719
-					$trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
1720
-				}
1721
-				if (lang_dir($l) !== lang_dir($lang)) {
1722
-					$trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
1723
-				}
1724
-				if (!$options['echappe_span']) {
1725
-					$trad = echappe_retour($trad, 'idiome');
1726
-				}
1727
-				$letexte = str_replace($reg[0], $trad, $letexte);
1728
-			}
1729
-		}
1730
-	}
1731
-	return $letexte;
1691
+    static $traduire = false;
1692
+    if (
1693
+        $letexte
1694
+        and preg_match_all(_EXTRAIRE_IDIOME, $letexte, $regs, PREG_SET_ORDER)
1695
+    ) {
1696
+        if (!$traduire) {
1697
+            $traduire = charger_fonction('traduire', 'inc');
1698
+            include_spip('inc/lang');
1699
+        }
1700
+        if (!$lang) {
1701
+            $lang = $GLOBALS['spip_lang'];
1702
+        }
1703
+        // Compatibilité avec le prototype de fonction précédente qui utilisait un boolean
1704
+        if (is_bool($options)) {
1705
+            $options = ['echappe_span' => $options];
1706
+        }
1707
+        if (!isset($options['echappe_span'])) {
1708
+            $options = array_merge($options, ['echappe_span' => false]);
1709
+        }
1710
+
1711
+        foreach ($regs as $reg) {
1712
+            $cle = ($reg[1] ? $reg[1] . ':' : '') . $reg[2];
1713
+            $desc = $traduire($cle, $lang, true);
1714
+            $l = $desc->langue;
1715
+            // si pas de traduction, on laissera l'écriture de l'idiome entier dans le texte.
1716
+            if (strlen($desc->texte ?? '')) {
1717
+                $trad = code_echappement($desc->texte, 'idiome', false);
1718
+                if ($l !== $lang) {
1719
+                    $trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
1720
+                }
1721
+                if (lang_dir($l) !== lang_dir($lang)) {
1722
+                    $trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
1723
+                }
1724
+                if (!$options['echappe_span']) {
1725
+                    $trad = echappe_retour($trad, 'idiome');
1726
+                }
1727
+                $letexte = str_replace($reg[0], $trad, $letexte);
1728
+            }
1729
+        }
1730
+    }
1731
+    return $letexte;
1732 1732
 }
1733 1733
 
1734 1734
 /**
@@ -1780,68 +1780,68 @@  discard block
 block discarded – undo
1780 1780
  **/
1781 1781
 function extraire_multi($letexte, $lang = null, $options = []) {
1782 1782
 
1783
-	if (
1784
-		$letexte
1785
-		and preg_match_all(_EXTRAIRE_MULTI, $letexte, $regs, PREG_SET_ORDER)
1786
-	) {
1787
-		if (!$lang) {
1788
-			$lang = $GLOBALS['spip_lang'];
1789
-		}
1790
-
1791
-		// Compatibilité avec le prototype de fonction précédente qui utilisait un boolean
1792
-		if (is_bool($options)) {
1793
-			$options = ['echappe_span' => $options, 'lang_defaut' => _LANGUE_PAR_DEFAUT];
1794
-		}
1795
-		if (!isset($options['echappe_span'])) {
1796
-			$options = array_merge($options, ['echappe_span' => false]);
1797
-		}
1798
-		if (!isset($options['lang_defaut'])) {
1799
-			$options = array_merge($options, ['lang_defaut' => _LANGUE_PAR_DEFAUT]);
1800
-		}
1801
-
1802
-		include_spip('inc/lang');
1803
-		foreach ($regs as $reg) {
1804
-			// chercher la version de la langue courante
1805
-			$trads = extraire_trads($reg[1]);
1806
-			if ($l = approcher_langue($trads, $lang)) {
1807
-				$trad = $trads[$l];
1808
-			} else {
1809
-				if ($options['lang_defaut'] == 'aucune') {
1810
-					$trad = '';
1811
-				} else {
1812
-					// langue absente, prendre le fr ou une langue précisée (meme comportement que inc/traduire.php)
1813
-					// ou la premiere dispo
1814
-					// mais typographier le texte selon les regles de celle-ci
1815
-					// Attention aux blocs multi sur plusieurs lignes
1816
-					if (!$l = approcher_langue($trads, $options['lang_defaut'])) {
1817
-						$l = key($trads);
1818
-					}
1819
-					$trad = $trads[$l];
1820
-					$typographie = charger_fonction(lang_typo($l), 'typographie');
1821
-					$trad = $typographie($trad);
1822
-					// Tester si on echappe en span ou en div
1823
-					// il ne faut pas echapper en div si propre produit un seul paragraphe
1824
-					include_spip('inc/texte');
1825
-					$trad_propre = preg_replace(',(^<p[^>]*>|</p>$),Uims', '', propre($trad));
1826
-					$mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
1827
-					if ($mode === 'div') {
1828
-						$trad = rtrim($trad) . "\n\n";
1829
-					}
1830
-					$trad = code_echappement($trad, 'multi', false, $mode);
1831
-					$trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
1832
-					if (lang_dir($l) !== lang_dir($lang)) {
1833
-						$trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
1834
-					}
1835
-					if (!$options['echappe_span']) {
1836
-						$trad = echappe_retour($trad, 'multi');
1837
-					}
1838
-				}
1839
-			}
1840
-			$letexte = str_replace($reg[0], $trad, $letexte);
1841
-		}
1842
-	}
1843
-
1844
-	return $letexte;
1783
+    if (
1784
+        $letexte
1785
+        and preg_match_all(_EXTRAIRE_MULTI, $letexte, $regs, PREG_SET_ORDER)
1786
+    ) {
1787
+        if (!$lang) {
1788
+            $lang = $GLOBALS['spip_lang'];
1789
+        }
1790
+
1791
+        // Compatibilité avec le prototype de fonction précédente qui utilisait un boolean
1792
+        if (is_bool($options)) {
1793
+            $options = ['echappe_span' => $options, 'lang_defaut' => _LANGUE_PAR_DEFAUT];
1794
+        }
1795
+        if (!isset($options['echappe_span'])) {
1796
+            $options = array_merge($options, ['echappe_span' => false]);
1797
+        }
1798
+        if (!isset($options['lang_defaut'])) {
1799
+            $options = array_merge($options, ['lang_defaut' => _LANGUE_PAR_DEFAUT]);
1800
+        }
1801
+
1802
+        include_spip('inc/lang');
1803
+        foreach ($regs as $reg) {
1804
+            // chercher la version de la langue courante
1805
+            $trads = extraire_trads($reg[1]);
1806
+            if ($l = approcher_langue($trads, $lang)) {
1807
+                $trad = $trads[$l];
1808
+            } else {
1809
+                if ($options['lang_defaut'] == 'aucune') {
1810
+                    $trad = '';
1811
+                } else {
1812
+                    // langue absente, prendre le fr ou une langue précisée (meme comportement que inc/traduire.php)
1813
+                    // ou la premiere dispo
1814
+                    // mais typographier le texte selon les regles de celle-ci
1815
+                    // Attention aux blocs multi sur plusieurs lignes
1816
+                    if (!$l = approcher_langue($trads, $options['lang_defaut'])) {
1817
+                        $l = key($trads);
1818
+                    }
1819
+                    $trad = $trads[$l];
1820
+                    $typographie = charger_fonction(lang_typo($l), 'typographie');
1821
+                    $trad = $typographie($trad);
1822
+                    // Tester si on echappe en span ou en div
1823
+                    // il ne faut pas echapper en div si propre produit un seul paragraphe
1824
+                    include_spip('inc/texte');
1825
+                    $trad_propre = preg_replace(',(^<p[^>]*>|</p>$),Uims', '', propre($trad));
1826
+                    $mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
1827
+                    if ($mode === 'div') {
1828
+                        $trad = rtrim($trad) . "\n\n";
1829
+                    }
1830
+                    $trad = code_echappement($trad, 'multi', false, $mode);
1831
+                    $trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
1832
+                    if (lang_dir($l) !== lang_dir($lang)) {
1833
+                        $trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
1834
+                    }
1835
+                    if (!$options['echappe_span']) {
1836
+                        $trad = echappe_retour($trad, 'multi');
1837
+                    }
1838
+                }
1839
+            }
1840
+            $letexte = str_replace($reg[0], $trad, $letexte);
1841
+        }
1842
+    }
1843
+
1844
+    return $letexte;
1845 1845
 }
1846 1846
 
1847 1847
 /**
@@ -1857,21 +1857,21 @@  discard block
 block discarded – undo
1857 1857
  *     Peut retourner un code de langue vide, lorsqu'un texte par défaut est indiqué.
1858 1858
  **/
1859 1859
 function extraire_trads($bloc) {
1860
-	$trads = [];
1861
-	$lang = '';
1860
+    $trads = [];
1861
+    $lang = '';
1862 1862
 // ce reg fait planter l'analyse multi s'il y a de l'{italique} dans le champ
1863 1863
 //	while (preg_match("/^(.*?)[{\[]([a-z_]+)[}\]]/siS", $bloc, $regs)) {
1864
-	while (preg_match('/^(.*?)[\[]([a-z_]+)[\]]/siS', $bloc, $regs)) {
1865
-		$texte = trim($regs[1]);
1866
-		if ($texte or $lang) {
1867
-			$trads[$lang] = $texte;
1868
-		}
1869
-		$bloc = substr($bloc, strlen($regs[0]));
1870
-		$lang = $regs[2];
1871
-	}
1872
-	$trads[$lang] = $bloc;
1864
+    while (preg_match('/^(.*?)[\[]([a-z_]+)[\]]/siS', $bloc, $regs)) {
1865
+        $texte = trim($regs[1]);
1866
+        if ($texte or $lang) {
1867
+            $trads[$lang] = $texte;
1868
+        }
1869
+        $bloc = substr($bloc, strlen($regs[0]));
1870
+        $lang = $regs[2];
1871
+    }
1872
+    $trads[$lang] = $bloc;
1873 1873
 
1874
-	return $trads;
1874
+    return $trads;
1875 1875
 }
1876 1876
 
1877 1877
 
@@ -1882,7 +1882,7 @@  discard block
 block discarded – undo
1882 1882
  * @return string L'initiale en majuscule
1883 1883
  */
1884 1884
 function filtre_initiale($nom) {
1885
-	return spip_substr(trim(strtoupper(extraire_multi($nom))), 0, 1);
1885
+    return spip_substr(trim(strtoupper(extraire_multi($nom))), 0, 1);
1886 1886
 }
1887 1887
 
1888 1888
 
@@ -1927,33 +1927,33 @@  discard block
 block discarded – undo
1927 1927
  *      - null (interne) : si on empile
1928 1928
  **/
1929 1929
 function unique($donnee, $famille = '', $cpt = false) {
1930
-	static $mem = [];
1931
-	// permettre de vider la pile et de la restaurer
1932
-	// pour le calcul de introduction...
1933
-	if ($famille == '_spip_raz_') {
1934
-		$tmp = $mem;
1935
-		$mem = [];
1936
-
1937
-		return $tmp;
1938
-	} elseif ($famille == '_spip_set_') {
1939
-		$mem = $donnee;
1940
-
1941
-		return;
1942
-	}
1943
-	// eviter une notice
1944
-	if (!isset($mem[$famille])) {
1945
-		$mem[$famille] = [];
1946
-	}
1947
-	if ($cpt) {
1948
-		return is_countable($mem[$famille]) ? count($mem[$famille]) : 0;
1949
-	}
1950
-	// eviter une notice
1951
-	if (!isset($mem[$famille][$donnee])) {
1952
-		$mem[$famille][$donnee] = 0;
1953
-	}
1954
-	if (!($mem[$famille][$donnee]++)) {
1955
-		return $donnee;
1956
-	}
1930
+    static $mem = [];
1931
+    // permettre de vider la pile et de la restaurer
1932
+    // pour le calcul de introduction...
1933
+    if ($famille == '_spip_raz_') {
1934
+        $tmp = $mem;
1935
+        $mem = [];
1936
+
1937
+        return $tmp;
1938
+    } elseif ($famille == '_spip_set_') {
1939
+        $mem = $donnee;
1940
+
1941
+        return;
1942
+    }
1943
+    // eviter une notice
1944
+    if (!isset($mem[$famille])) {
1945
+        $mem[$famille] = [];
1946
+    }
1947
+    if ($cpt) {
1948
+        return is_countable($mem[$famille]) ? count($mem[$famille]) : 0;
1949
+    }
1950
+    // eviter une notice
1951
+    if (!isset($mem[$famille][$donnee])) {
1952
+        $mem[$famille][$donnee] = 0;
1953
+    }
1954
+    if (!($mem[$famille][$donnee]++)) {
1955
+        return $donnee;
1956
+    }
1957 1957
 }
1958 1958
 
1959 1959
 
@@ -1983,20 +1983,20 @@  discard block
 block discarded – undo
1983 1983
  *     Une des valeurs en fonction du compteur.
1984 1984
  **/
1985 1985
 function alterner($i, ...$args) {
1986
-	// recuperer les arguments (attention fonctions un peu space)
1987
-	$num = count($args);
1986
+    // recuperer les arguments (attention fonctions un peu space)
1987
+    $num = count($args);
1988 1988
 
1989
-	if ($num === 1 && is_array($args[0])) {
1990
-		// un tableau de valeur dont les cles sont numerotees de 0 a num
1991
-		$args = array_values($args[0]);
1992
-		$num = count($args);
1993
-	}
1989
+    if ($num === 1 && is_array($args[0])) {
1990
+        // un tableau de valeur dont les cles sont numerotees de 0 a num
1991
+        $args = array_values($args[0]);
1992
+        $num = count($args);
1993
+    }
1994 1994
 
1995
-	// un index compris entre 0 et num exclus
1996
-	$i = ((intval($i) - 1) % $num); // dans ]-$num;$num[
1997
-	$i = ($i + $num) % $num; // dans [0;$num[
1998
-	// renvoyer le i-ieme argument, modulo le nombre d'arguments
1999
-	return $args[$i];
1995
+    // un index compris entre 0 et num exclus
1996
+    $i = ((intval($i) - 1) % $num); // dans ]-$num;$num[
1997
+    $i = ($i + $num) % $num; // dans [0;$num[
1998
+    // renvoyer le i-ieme argument, modulo le nombre d'arguments
1999
+    return $args[$i];
2000 2000
 }
2001 2001
 
2002 2002
 
@@ -2022,51 +2022,51 @@  discard block
 block discarded – undo
2022 2022
  *     - null lorsque l’attribut n’existe pas.
2023 2023
  **/
2024 2024
 function extraire_attribut($balise, $attribut, $complet = false) {
2025
-	if (is_array($balise)) {
2026
-		array_walk(
2027
-			$balise,
2028
-			function (&$a, $key, $t) {
2029
-				$a = extraire_attribut($a, $t);
2030
-			},
2031
-			$attribut
2032
-		);
2033
-
2034
-		return $balise;
2035
-	}
2036
-	if (
2037
-		$balise
2038
-		&& preg_match(
2039
-			',(^.*?<(?:(?>\s*)(?>[\w:.-]+)(?>(?:=(?:"[^"]*"|\'[^\']*\'|[^\'"]\S*))?))*?)(\s+'
2040
-			. $attribut
2041
-			. '(?:=\s*("[^"]*"|\'[^\']*\'|[^\'"]\S*))?)()((?:[\s/][^>]*)?>.*),isS',
2042
-			$balise,
2043
-			$r
2044
-		)
2045
-	) {
2046
-		if (isset($r[3][0]) and ($r[3][0] == '"' || $r[3][0] == "'")) {
2047
-			$r[4] = substr($r[3], 1, -1);
2048
-			$r[3] = $r[3][0];
2049
-		} elseif ($r[3] !== '') {
2050
-			$r[4] = $r[3];
2051
-			$r[3] = '';
2052
-		} else {
2053
-			$r[4] = trim($r[2]);
2054
-		}
2055
-		$att = $r[4];
2056
-		if (strpos($att, '&#') !== false) {
2057
-			$att = str_replace(['&#039;', '&#39;', '&#034;', '&#34;'], ["'", "'", '"', '"'], $att);
2058
-		}
2059
-		$att = filtrer_entites($att);
2060
-	} else {
2061
-		$att = null;
2062
-		$r = [];
2063
-	}
2064
-
2065
-	if ($complet) {
2066
-		return [$att, $r];
2067
-	} else {
2068
-		return $att;
2069
-	}
2025
+    if (is_array($balise)) {
2026
+        array_walk(
2027
+            $balise,
2028
+            function (&$a, $key, $t) {
2029
+                $a = extraire_attribut($a, $t);
2030
+            },
2031
+            $attribut
2032
+        );
2033
+
2034
+        return $balise;
2035
+    }
2036
+    if (
2037
+        $balise
2038
+        && preg_match(
2039
+            ',(^.*?<(?:(?>\s*)(?>[\w:.-]+)(?>(?:=(?:"[^"]*"|\'[^\']*\'|[^\'"]\S*))?))*?)(\s+'
2040
+            . $attribut
2041
+            . '(?:=\s*("[^"]*"|\'[^\']*\'|[^\'"]\S*))?)()((?:[\s/][^>]*)?>.*),isS',
2042
+            $balise,
2043
+            $r
2044
+        )
2045
+    ) {
2046
+        if (isset($r[3][0]) and ($r[3][0] == '"' || $r[3][0] == "'")) {
2047
+            $r[4] = substr($r[3], 1, -1);
2048
+            $r[3] = $r[3][0];
2049
+        } elseif ($r[3] !== '') {
2050
+            $r[4] = $r[3];
2051
+            $r[3] = '';
2052
+        } else {
2053
+            $r[4] = trim($r[2]);
2054
+        }
2055
+        $att = $r[4];
2056
+        if (strpos($att, '&#') !== false) {
2057
+            $att = str_replace(['&#039;', '&#39;', '&#034;', '&#34;'], ["'", "'", '"', '"'], $att);
2058
+        }
2059
+        $att = filtrer_entites($att);
2060
+    } else {
2061
+        $att = null;
2062
+        $r = [];
2063
+    }
2064
+
2065
+    if ($complet) {
2066
+        return [$att, $r];
2067
+    } else {
2068
+        return $att;
2069
+    }
2070 2070
 }
2071 2071
 
2072 2072
 /**
@@ -2099,41 +2099,41 @@  discard block
 block discarded – undo
2099 2099
  **/
2100 2100
 function inserer_attribut(?string $balise, string $attribut, string $val, bool $proteger = true, bool $vider = false): string {
2101 2101
 
2102
-	if ($balise === null or $balise === '') {
2103
-		return '';
2104
-	}
2102
+    if ($balise === null or $balise === '') {
2103
+        return '';
2104
+    }
2105 2105
 
2106
-	// preparer l'attribut
2107
-	// supprimer les &nbsp; etc mais pas les balises html
2108
-	// qui ont un sens dans un attribut value d'un input
2109
-	if ($proteger) {
2110
-		$val = attribut_html($val, false);
2111
-	}
2106
+    // preparer l'attribut
2107
+    // supprimer les &nbsp; etc mais pas les balises html
2108
+    // qui ont un sens dans un attribut value d'un input
2109
+    if ($proteger) {
2110
+        $val = attribut_html($val, false);
2111
+    }
2112 2112
 
2113
-	// echapper les ' pour eviter tout bug
2114
-	$val = str_replace("'", '&#039;', $val);
2115
-	if ($vider and strlen($val) === 0) {
2116
-		$insert = '';
2117
-	} else {
2118
-		$insert = " $attribut='$val'";
2119
-	}
2113
+    // echapper les ' pour eviter tout bug
2114
+    $val = str_replace("'", '&#039;', $val);
2115
+    if ($vider and strlen($val) === 0) {
2116
+        $insert = '';
2117
+    } else {
2118
+        $insert = " $attribut='$val'";
2119
+    }
2120 2120
 
2121
-	[$old, $r] = extraire_attribut($balise, $attribut, true);
2121
+    [$old, $r] = extraire_attribut($balise, $attribut, true);
2122 2122
 
2123
-	if ($old !== null) {
2124
-		// Remplacer l'ancien attribut du meme nom
2125
-		$balise = $r[1] . $insert . $r[5];
2126
-	} else {
2127
-		// preferer une balise " />" (comme <img />)
2128
-		if (preg_match(',/>,', $balise)) {
2129
-			$balise = preg_replace(',\s?/>,S', $insert . ' />', $balise, 1);
2130
-		} // sinon une balise <a ...> ... </a>
2131
-		else {
2132
-			$balise = preg_replace(',\s?>,S', $insert . '>', $balise, 1);
2133
-		}
2134
-	}
2123
+    if ($old !== null) {
2124
+        // Remplacer l'ancien attribut du meme nom
2125
+        $balise = $r[1] . $insert . $r[5];
2126
+    } else {
2127
+        // preferer une balise " />" (comme <img />)
2128
+        if (preg_match(',/>,', $balise)) {
2129
+            $balise = preg_replace(',\s?/>,S', $insert . ' />', $balise, 1);
2130
+        } // sinon une balise <a ...> ... </a>
2131
+        else {
2132
+            $balise = preg_replace(',\s?>,S', $insert . '>', $balise, 1);
2133
+        }
2134
+    }
2135 2135
 
2136
-	return $balise;
2136
+    return $balise;
2137 2137
 }
2138 2138
 
2139 2139
 /**
@@ -2151,7 +2151,7 @@  discard block
 block discarded – undo
2151 2151
  * @return string Code HTML sans l'attribut
2152 2152
  **/
2153 2153
 function vider_attribut(?string $balise, string $attribut): string {
2154
-	return inserer_attribut($balise, $attribut, '', false, true);
2154
+    return inserer_attribut($balise, $attribut, '', false, true);
2155 2155
 }
2156 2156
 
2157 2157
 /**
@@ -2163,53 +2163,53 @@  discard block
 block discarded – undo
2163 2163
  * @return string
2164 2164
  */
2165 2165
 function modifier_class($balise, $class, $operation = 'ajouter') {
2166
-	if (is_string($class)) {
2167
-		$class = explode(' ', trim($class));
2168
-	}
2169
-	$class = array_filter($class);
2170
-	$class = array_unique($class);
2171
-	if (!$class) {
2172
-		return $balise;
2173
-	}
2174
-
2175
-	// si la ou les classes ont des caracteres invalides on ne fait rien
2176
-	if (preg_match(',[^\w-],', implode('', $class))) {
2177
-		return $balise;
2178
-	}
2179
-
2180
-	$class_courante = extraire_attribut($balise, 'class');
2181
-	$class_new = $class_courante;
2182
-	foreach ($class as $c) {
2183
-		$is_class_presente = false;
2184
-		if (
2185
-			$class_courante
2186
-			and strpos($class_courante, (string) $c) !== false
2187
-			and preg_match('/(^|\s)' . preg_quote($c) . '($|\s)/', $class_courante)
2188
-		) {
2189
-			$is_class_presente = true;
2190
-		}
2191
-		if (
2192
-			in_array($operation, ['ajouter', 'commuter'])
2193
-			and !$is_class_presente
2194
-		) {
2195
-			$class_new = ltrim(rtrim($class_new ?? '') . ' ' . $c);
2196
-		} elseif (
2197
-			in_array($operation, ['supprimer', 'commuter'])
2198
-			and $is_class_presente
2199
-		) {
2200
-			$class_new = trim(preg_replace('/(^|\s)' . preg_quote($c) . '($|\s)/', "\\1", $class_new));
2201
-		}
2202
-	}
2203
-
2204
-	if ($class_new !== $class_courante) {
2205
-		if (strlen($class_new)) {
2206
-			$balise = inserer_attribut($balise, 'class', $class_new);
2207
-		} elseif ($class_courante) {
2208
-			$balise = vider_attribut($balise, 'class');
2209
-		}
2210
-	}
2211
-
2212
-	return $balise;
2166
+    if (is_string($class)) {
2167
+        $class = explode(' ', trim($class));
2168
+    }
2169
+    $class = array_filter($class);
2170
+    $class = array_unique($class);
2171
+    if (!$class) {
2172
+        return $balise;
2173
+    }
2174
+
2175
+    // si la ou les classes ont des caracteres invalides on ne fait rien
2176
+    if (preg_match(',[^\w-],', implode('', $class))) {
2177
+        return $balise;
2178
+    }
2179
+
2180
+    $class_courante = extraire_attribut($balise, 'class');
2181
+    $class_new = $class_courante;
2182
+    foreach ($class as $c) {
2183
+        $is_class_presente = false;
2184
+        if (
2185
+            $class_courante
2186
+            and strpos($class_courante, (string) $c) !== false
2187
+            and preg_match('/(^|\s)' . preg_quote($c) . '($|\s)/', $class_courante)
2188
+        ) {
2189
+            $is_class_presente = true;
2190
+        }
2191
+        if (
2192
+            in_array($operation, ['ajouter', 'commuter'])
2193
+            and !$is_class_presente
2194
+        ) {
2195
+            $class_new = ltrim(rtrim($class_new ?? '') . ' ' . $c);
2196
+        } elseif (
2197
+            in_array($operation, ['supprimer', 'commuter'])
2198
+            and $is_class_presente
2199
+        ) {
2200
+            $class_new = trim(preg_replace('/(^|\s)' . preg_quote($c) . '($|\s)/', "\\1", $class_new));
2201
+        }
2202
+    }
2203
+
2204
+    if ($class_new !== $class_courante) {
2205
+        if (strlen($class_new)) {
2206
+            $balise = inserer_attribut($balise, 'class', $class_new);
2207
+        } elseif ($class_courante) {
2208
+            $balise = vider_attribut($balise, 'class');
2209
+        }
2210
+    }
2211
+
2212
+    return $balise;
2213 2213
 }
2214 2214
 
2215 2215
 /**
@@ -2219,7 +2219,7 @@  discard block
 block discarded – undo
2219 2219
  * @return string
2220 2220
  */
2221 2221
 function ajouter_class($balise, $class) {
2222
-	return modifier_class($balise, $class, 'ajouter');
2222
+    return modifier_class($balise, $class, 'ajouter');
2223 2223
 }
2224 2224
 
2225 2225
 /**
@@ -2229,7 +2229,7 @@  discard block
 block discarded – undo
2229 2229
  * @return string
2230 2230
  */
2231 2231
 function supprimer_class($balise, $class) {
2232
-	return modifier_class($balise, $class, 'supprimer');
2232
+    return modifier_class($balise, $class, 'supprimer');
2233 2233
 }
2234 2234
 
2235 2235
 /**
@@ -2240,7 +2240,7 @@  discard block
 block discarded – undo
2240 2240
  * @return string
2241 2241
  */
2242 2242
 function commuter_class($balise, $class) {
2243
-	return modifier_class($balise, $class, 'commuter');
2243
+    return modifier_class($balise, $class, 'commuter');
2244 2244
 }
2245 2245
 
2246 2246
 /**
@@ -2251,19 +2251,19 @@  discard block
 block discarded – undo
2251 2251
  * @return string
2252 2252
  */
2253 2253
 function tester_config($id, $mode = '') {
2254
-	include_spip('action/inscrire_auteur');
2254
+    include_spip('action/inscrire_auteur');
2255 2255
 
2256
-	return tester_statut_inscription($mode, $id);
2256
+    return tester_statut_inscription($mode, $id);
2257 2257
 }
2258 2258
 
2259 2259
 //
2260 2260
 // Quelques fonctions de calcul arithmetique
2261 2261
 //
2262 2262
 function floatstr($a) {
2263
- return str_replace(',', '.', (string)floatval($a));
2263
+    return str_replace(',', '.', (string)floatval($a));
2264 2264
 }
2265 2265
 function strize($f, $a, $b) {
2266
- return floatstr($f(floatstr($a), floatstr($b)));
2266
+    return floatstr($f(floatstr($a), floatstr($b)));
2267 2267
 }
2268 2268
 
2269 2269
 /**
@@ -2282,7 +2282,7 @@  discard block
 block discarded – undo
2282 2282
  * @return int $a+$b
2283 2283
  **/
2284 2284
 function plus($a, $b) {
2285
-	return $a + $b;
2285
+    return $a + $b;
2286 2286
 }
2287 2287
 function strplus($a, $b) {
2288 2288
 return strize('plus', $a, $b);
@@ -2303,7 +2303,7 @@  discard block
 block discarded – undo
2303 2303
  * @return int $a-$b
2304 2304
  **/
2305 2305
 function moins($a, $b) {
2306
-	return $a - $b;
2306
+    return $a - $b;
2307 2307
 }
2308 2308
 function strmoins($a, $b) {
2309 2309
 return strize('moins', $a, $b);
@@ -2326,7 +2326,7 @@  discard block
 block discarded – undo
2326 2326
  * @return int $a*$b
2327 2327
  **/
2328 2328
 function mult($a, $b) {
2329
-	return $a * $b;
2329
+    return $a * $b;
2330 2330
 }
2331 2331
 function strmult($a, $b) {
2332 2332
 return strize('mult', $a, $b);
@@ -2349,7 +2349,7 @@  discard block
 block discarded – undo
2349 2349
  * @return int $a/$b (ou 0 si $b est nul)
2350 2350
  **/
2351 2351
 function div($a, $b) {
2352
-	return $b ? $a / $b : 0;
2352
+    return $b ? $a / $b : 0;
2353 2353
 }
2354 2354
 function strdiv($a, $b) {
2355 2355
 return strize('div', $a, $b);
@@ -2373,7 +2373,7 @@  discard block
 block discarded – undo
2373 2373
  * @return int ($nb % $mod) + $add
2374 2374
  **/
2375 2375
 function modulo($nb, $mod, $add = 0) {
2376
-	return ($mod ? $nb % $mod : 0) + $add;
2376
+    return ($mod ? $nb % $mod : 0) + $add;
2377 2377
 }
2378 2378
 
2379 2379
 
@@ -2388,26 +2388,26 @@  discard block
 block discarded – undo
2388 2388
  *      - true sinon
2389 2389
  **/
2390 2390
 function nom_acceptable($nom) {
2391
-	$remp2 = [];
2392
-	$remp1 = [];
2393
-	if (!is_string($nom)) {
2394
-		return false;
2395
-	}
2396
-	if (!defined('_TAGS_NOM_AUTEUR')) {
2397
-		define('_TAGS_NOM_AUTEUR', '');
2398
-	}
2399
-	$tags_acceptes = array_unique(explode(',', 'multi,' . _TAGS_NOM_AUTEUR));
2400
-	foreach ($tags_acceptes as $tag) {
2401
-		if (strlen($tag)) {
2402
-			$remp1[] = '<' . trim($tag) . '>';
2403
-			$remp1[] = '</' . trim($tag) . '>';
2404
-			$remp2[] = '\x60' . trim($tag) . '\x61';
2405
-			$remp2[] = '\x60/' . trim($tag) . '\x61';
2406
-		}
2407
-	}
2408
-	$v_nom = str_replace($remp2, $remp1, supprimer_tags(str_replace($remp1, $remp2, $nom)));
2409
-
2410
-	return str_replace('&lt;', '<', $v_nom) == $nom;
2391
+    $remp2 = [];
2392
+    $remp1 = [];
2393
+    if (!is_string($nom)) {
2394
+        return false;
2395
+    }
2396
+    if (!defined('_TAGS_NOM_AUTEUR')) {
2397
+        define('_TAGS_NOM_AUTEUR', '');
2398
+    }
2399
+    $tags_acceptes = array_unique(explode(',', 'multi,' . _TAGS_NOM_AUTEUR));
2400
+    foreach ($tags_acceptes as $tag) {
2401
+        if (strlen($tag)) {
2402
+            $remp1[] = '<' . trim($tag) . '>';
2403
+            $remp1[] = '</' . trim($tag) . '>';
2404
+            $remp2[] = '\x60' . trim($tag) . '\x61';
2405
+            $remp2[] = '\x60/' . trim($tag) . '\x61';
2406
+        }
2407
+    }
2408
+    $v_nom = str_replace($remp2, $remp1, supprimer_tags(str_replace($remp1, $remp2, $nom)));
2409
+
2410
+    return str_replace('&lt;', '<', $v_nom) == $nom;
2411 2411
 }
2412 2412
 
2413 2413
 
@@ -2423,14 +2423,14 @@  discard block
 block discarded – undo
2423 2423
  *      - renvoie un tableau si l'entree est un tableau
2424 2424
  **/
2425 2425
 function email_valide($adresses) {
2426
-	if (is_array($adresses)) {
2427
-		$adresses = array_map('email_valide', $adresses);
2428
-		$adresses = array_filter($adresses);
2429
-		return $adresses;
2430
-	}
2426
+    if (is_array($adresses)) {
2427
+        $adresses = array_map('email_valide', $adresses);
2428
+        $adresses = array_filter($adresses);
2429
+        return $adresses;
2430
+    }
2431 2431
 
2432
-	$email_valide = charger_fonction('email_valide', 'inc');
2433
-	return $email_valide($adresses);
2432
+    $email_valide = charger_fonction('email_valide', 'inc');
2433
+    return $email_valide($adresses);
2434 2434
 }
2435 2435
 
2436 2436
 /**
@@ -2444,27 +2444,27 @@  discard block
 block discarded – undo
2444 2444
  * @return string Texte
2445 2445
  **/
2446 2446
 function afficher_enclosures($tags) {
2447
-	$s = [];
2448
-	foreach (extraire_balises($tags, 'a') as $tag) {
2449
-		if (
2450
-			extraire_attribut($tag, 'rel') == 'enclosure'
2451
-			and $t = extraire_attribut($tag, 'href')
2452
-		) {
2453
-			$s[] = preg_replace(
2454
-				',>[^<]+</a>,S',
2455
-				'>'
2456
-				. http_img_pack(
2457
-					'attachment-16.png',
2458
-					$t,
2459
-					'title="' . attribut_html($t) . '"'
2460
-				)
2461
-				. '</a>',
2462
-				$tag
2463
-			);
2464
-		}
2465
-	}
2466
-
2467
-	return join('&nbsp;', $s);
2447
+    $s = [];
2448
+    foreach (extraire_balises($tags, 'a') as $tag) {
2449
+        if (
2450
+            extraire_attribut($tag, 'rel') == 'enclosure'
2451
+            and $t = extraire_attribut($tag, 'href')
2452
+        ) {
2453
+            $s[] = preg_replace(
2454
+                ',>[^<]+</a>,S',
2455
+                '>'
2456
+                . http_img_pack(
2457
+                    'attachment-16.png',
2458
+                    $t,
2459
+                    'title="' . attribut_html($t) . '"'
2460
+                )
2461
+                . '</a>',
2462
+                $tag
2463
+            );
2464
+        }
2465
+    }
2466
+
2467
+    return join('&nbsp;', $s);
2468 2468
 }
2469 2469
 
2470 2470
 /**
@@ -2479,15 +2479,15 @@  discard block
 block discarded – undo
2479 2479
  * @return string Liens trouvés
2480 2480
  **/
2481 2481
 function afficher_tags($tags, $rels = 'tag,directory') {
2482
-	$s = [];
2483
-	foreach (extraire_balises($tags, 'a') as $tag) {
2484
-		$rel = extraire_attribut($tag, 'rel');
2485
-		if (strstr(",$rels,", (string) ",$rel,")) {
2486
-			$s[] = $tag;
2487
-		}
2488
-	}
2482
+    $s = [];
2483
+    foreach (extraire_balises($tags, 'a') as $tag) {
2484
+        $rel = extraire_attribut($tag, 'rel');
2485
+        if (strstr(",$rels,", (string) ",$rel,")) {
2486
+            $s[] = $tag;
2487
+        }
2488
+    }
2489 2489
 
2490
-	return join(', ', $s);
2490
+    return join(', ', $s);
2491 2491
 }
2492 2492
 
2493 2493
 
@@ -2509,21 +2509,21 @@  discard block
 block discarded – undo
2509 2509
  * @return string Tag HTML `<a>` avec microformat.
2510 2510
  **/
2511 2511
 function enclosure2microformat($e) {
2512
-	if (!$url = filtrer_entites(extraire_attribut($e, 'url'))) {
2513
-		$url = filtrer_entites(extraire_attribut($e, 'href'));
2514
-	}
2515
-	$type = extraire_attribut($e, 'type');
2516
-	if (!$length = extraire_attribut($e, 'length')) {
2517
-		# <media:content : longeur dans fileSize. On tente.
2518
-		$length = extraire_attribut($e, 'fileSize');
2519
-	}
2520
-	$fichier = basename($url);
2512
+    if (!$url = filtrer_entites(extraire_attribut($e, 'url'))) {
2513
+        $url = filtrer_entites(extraire_attribut($e, 'href'));
2514
+    }
2515
+    $type = extraire_attribut($e, 'type');
2516
+    if (!$length = extraire_attribut($e, 'length')) {
2517
+        # <media:content : longeur dans fileSize. On tente.
2518
+        $length = extraire_attribut($e, 'fileSize');
2519
+    }
2520
+    $fichier = basename($url);
2521 2521
 
2522
-	return '<a rel="enclosure"'
2523
-	. ($url ? ' href="' . spip_htmlspecialchars($url) . '"' : '')
2524
-	. ($type ? ' type="' . spip_htmlspecialchars($type) . '"' : '')
2525
-	. ($length ? ' title="' . spip_htmlspecialchars($length) . '"' : '')
2526
-	. '>' . $fichier . '</a>';
2522
+    return '<a rel="enclosure"'
2523
+    . ($url ? ' href="' . spip_htmlspecialchars($url) . '"' : '')
2524
+    . ($type ? ' type="' . spip_htmlspecialchars($type) . '"' : '')
2525
+    . ($length ? ' title="' . spip_htmlspecialchars($length) . '"' : '')
2526
+    . '>' . $fichier . '</a>';
2527 2527
 }
2528 2528
 
2529 2529
 /**
@@ -2541,24 +2541,24 @@  discard block
 block discarded – undo
2541 2541
  * @return string Tags RSS `<enclosure>`.
2542 2542
  **/
2543 2543
 function microformat2enclosure($tags) {
2544
-	$enclosures = [];
2545
-	foreach (extraire_balises($tags, 'a') as $e) {
2546
-		if (extraire_attribut($e, 'rel') == 'enclosure') {
2547
-			$url = filtrer_entites(extraire_attribut($e, 'href'));
2548
-			$type = extraire_attribut($e, 'type');
2549
-			if (!$length = intval(extraire_attribut($e, 'title'))) {
2550
-				$length = intval(extraire_attribut($e, 'length'));
2551
-			} # vieux data
2552
-			$fichier = basename($url);
2553
-			$enclosures[] = '<enclosure'
2554
-				. ($url ? ' url="' . spip_htmlspecialchars($url) . '"' : '')
2555
-				. ($type ? ' type="' . spip_htmlspecialchars($type) . '"' : '')
2556
-				. ($length ? ' length="' . $length . '"' : '')
2557
-				. ' />';
2558
-		}
2559
-	}
2544
+    $enclosures = [];
2545
+    foreach (extraire_balises($tags, 'a') as $e) {
2546
+        if (extraire_attribut($e, 'rel') == 'enclosure') {
2547
+            $url = filtrer_entites(extraire_attribut($e, 'href'));
2548
+            $type = extraire_attribut($e, 'type');
2549
+            if (!$length = intval(extraire_attribut($e, 'title'))) {
2550
+                $length = intval(extraire_attribut($e, 'length'));
2551
+            } # vieux data
2552
+            $fichier = basename($url);
2553
+            $enclosures[] = '<enclosure'
2554
+                . ($url ? ' url="' . spip_htmlspecialchars($url) . '"' : '')
2555
+                . ($type ? ' type="' . spip_htmlspecialchars($type) . '"' : '')
2556
+                . ($length ? ' length="' . $length . '"' : '')
2557
+                . ' />';
2558
+        }
2559
+    }
2560 2560
 
2561
-	return join("\n", $enclosures);
2561
+    return join("\n", $enclosures);
2562 2562
 }
2563 2563
 
2564 2564
 
@@ -2574,16 +2574,16 @@  discard block
 block discarded – undo
2574 2574
  * @return string Tags RSS Atom `<dc:subject>`.
2575 2575
  **/
2576 2576
 function tags2dcsubject($tags) {
2577
-	$subjects = '';
2578
-	foreach (extraire_balises($tags, 'a') as $e) {
2579
-		if (extraire_attribut($e, 'rel') == 'tag') {
2580
-			$subjects .= '<dc:subject>'
2581
-				. texte_backend(textebrut($e))
2582
-				. '</dc:subject>' . "\n";
2583
-		}
2584
-	}
2577
+    $subjects = '';
2578
+    foreach (extraire_balises($tags, 'a') as $e) {
2579
+        if (extraire_attribut($e, 'rel') == 'tag') {
2580
+            $subjects .= '<dc:subject>'
2581
+                . texte_backend(textebrut($e))
2582
+                . '</dc:subject>' . "\n";
2583
+        }
2584
+    }
2585 2585
 
2586
-	return $subjects;
2586
+    return $subjects;
2587 2587
 }
2588 2588
 
2589 2589
 /**
@@ -2612,27 +2612,27 @@  discard block
 block discarded – undo
2612 2612
  *     - Tableau de résultats, si tableau en entrée.
2613 2613
  **/
2614 2614
 function extraire_balise($texte, $tag = 'a') {
2615
-	if (is_array($texte)) {
2616
-		array_walk(
2617
-			$texte,
2618
-			function (&$a, $key, $t) {
2619
-				$a = extraire_balise($a, $t);
2620
-			},
2621
-			$tag
2622
-		);
2623
-
2624
-		return $texte;
2625
-	}
2626
-
2627
-	if (
2628
-		preg_match(
2629
-			",<$tag\b[^>]*(/>|>.*</$tag\b[^>]*>|>),UimsS",
2630
-			$texte,
2631
-			$regs
2632
-		)
2633
-	) {
2634
-		return $regs[0];
2635
-	}
2615
+    if (is_array($texte)) {
2616
+        array_walk(
2617
+            $texte,
2618
+            function (&$a, $key, $t) {
2619
+                $a = extraire_balise($a, $t);
2620
+            },
2621
+            $tag
2622
+        );
2623
+
2624
+        return $texte;
2625
+    }
2626
+
2627
+    if (
2628
+        preg_match(
2629
+            ",<$tag\b[^>]*(/>|>.*</$tag\b[^>]*>|>),UimsS",
2630
+            $texte,
2631
+            $regs
2632
+        )
2633
+    ) {
2634
+        return $regs[0];
2635
+    }
2636 2636
 }
2637 2637
 
2638 2638
 /**
@@ -2660,30 +2660,30 @@  discard block
 block discarded – undo
2660 2660
  *     - Tableau de résultats, si tableau en entrée.
2661 2661
  **/
2662 2662
 function extraire_balises($texte, $tag = 'a') {
2663
-	if (is_array($texte)) {
2664
-		array_walk(
2665
-			$texte,
2666
-			function (&$a, $key, $t) {
2667
-				$a = extraire_balises($a, $t);
2668
-			},
2669
-			$tag
2670
-		);
2671
-
2672
-		return $texte;
2673
-	}
2674
-
2675
-	if (
2676
-		preg_match_all(
2677
-			",<${tag}\b[^>]*(/>|>.*</${tag}\b[^>]*>|>),UimsS",
2678
-			$texte,
2679
-			$regs,
2680
-			PREG_PATTERN_ORDER
2681
-		)
2682
-	) {
2683
-		return $regs[0];
2684
-	} else {
2685
-		return [];
2686
-	}
2663
+    if (is_array($texte)) {
2664
+        array_walk(
2665
+            $texte,
2666
+            function (&$a, $key, $t) {
2667
+                $a = extraire_balises($a, $t);
2668
+            },
2669
+            $tag
2670
+        );
2671
+
2672
+        return $texte;
2673
+    }
2674
+
2675
+    if (
2676
+        preg_match_all(
2677
+            ",<${tag}\b[^>]*(/>|>.*</${tag}\b[^>]*>|>),UimsS",
2678
+            $texte,
2679
+            $regs,
2680
+            PREG_PATTERN_ORDER
2681
+        )
2682
+    ) {
2683
+        return $regs[0];
2684
+    } else {
2685
+        return [];
2686
+    }
2687 2687
 }
2688 2688
 
2689 2689
 /**
@@ -2712,11 +2712,11 @@  discard block
 block discarded – undo
2712 2712
  *     - `$def` si on n'a pas transmis de tableau
2713 2713
  **/
2714 2714
 function in_any($val, $vals, $def = '') {
2715
-	if (!is_array($vals) and $vals and $v = unserialize($vals)) {
2716
-		$vals = $v;
2717
-	}
2715
+    if (!is_array($vals) and $vals and $v = unserialize($vals)) {
2716
+        $vals = $v;
2717
+    }
2718 2718
 
2719
-	return (!is_array($vals) ? $def : (in_array($val, $vals) ? ' ' : ''));
2719
+    return (!is_array($vals) ? $def : (in_array($val, $vals) ? ' ' : ''));
2720 2720
 }
2721 2721
 
2722 2722
 
@@ -2737,12 +2737,12 @@  discard block
 block discarded – undo
2737 2737
  *     Résultat du calcul
2738 2738
  **/
2739 2739
 function valeur_numerique($expr) {
2740
-	$a = 0;
2741
-	if (preg_match(',^[0-9]+(\s*[+*-]\s*[0-9]+)*$,S', trim($expr))) {
2742
-		eval("\$a = $expr;");
2743
-	}
2740
+    $a = 0;
2741
+    if (preg_match(',^[0-9]+(\s*[+*-]\s*[0-9]+)*$,S', trim($expr))) {
2742
+        eval("\$a = $expr;");
2743
+    }
2744 2744
 
2745
-	return intval($a);
2745
+    return intval($a);
2746 2746
 }
2747 2747
 
2748 2748
 /**
@@ -2761,7 +2761,7 @@  discard block
 block discarded – undo
2761 2761
  *      Retourne `$a*$b/$c`
2762 2762
  **/
2763 2763
 function regledetrois($a, $b, $c) {
2764
-	return round($a * $b / $c);
2764
+    return round($a * $b / $c);
2765 2765
 }
2766 2766
 
2767 2767
 
@@ -2784,79 +2784,79 @@  discard block
 block discarded – undo
2784 2784
  * @return string Suite de champs input hidden
2785 2785
  **/
2786 2786
 function form_hidden(?string $action = ''): string {
2787
-	$action ??= '';
2788
-
2789
-	$contexte = [];
2790
-	include_spip('inc/urls');
2791
-	if (
2792
-		$p = urls_decoder_url($action, '')
2793
-		and reset($p)
2794
-	) {
2795
-		$fond = array_shift($p);
2796
-		if ($fond != '404') {
2797
-			$contexte = array_shift($p);
2798
-			$contexte['page'] = $fond;
2799
-			$action = preg_replace('/([?]' . preg_quote($fond) . '[^&=]*[0-9]+)(&|$)/', '?&', $action);
2800
-		}
2801
-	}
2802
-	// defaire ce qu'a injecte urls_decoder_url : a revoir en modifiant la signature de urls_decoder_url
2803
-	if (defined('_DEFINIR_CONTEXTE_TYPE') and _DEFINIR_CONTEXTE_TYPE) {
2804
-		unset($contexte['type']);
2805
-	}
2806
-	if (!defined('_DEFINIR_CONTEXTE_TYPE_PAGE') or _DEFINIR_CONTEXTE_TYPE_PAGE) {
2807
-		unset($contexte['type-page']);
2808
-	}
2809
-
2810
-	// on va remplir un tableau de valeurs en prenant bien soin de ne pas
2811
-	// ecraser les elements de la forme mots[]=1&mots[]=2
2812
-	$values = [];
2813
-
2814
-	// d'abord avec celles de l'url
2815
-	if (false !== ($p = strpos($action, '?'))) {
2816
-		foreach (preg_split('/&(amp;)?/S', substr($action, $p + 1)) as $c) {
2817
-			$c = explode('=', $c, 2);
2818
-			$var = array_shift($c);
2819
-			$val = array_shift($c) ?? '';
2820
-			if ($var) {
2821
-				$val = rawurldecode($val);
2822
-				$var = rawurldecode($var); // decoder les [] eventuels
2823
-				if (preg_match(',\[\]$,S', $var)) {
2824
-					$values[] = [$var, $val];
2825
-				} else {
2826
-					if (!isset($values[$var])) {
2827
-						$values[$var] = [$var, $val];
2828
-					}
2829
-				}
2830
-			}
2831
-		}
2832
-	}
2833
-
2834
-	// ensuite avec celles du contexte, sans doublonner !
2835
-	foreach ($contexte as $var => $val) {
2836
-		if (preg_match(',\[\]$,S', $var)) {
2837
-			$values[] = [$var, $val];
2838
-		} else {
2839
-			if (!isset($values[$var])) {
2840
-				$values[$var] = [$var, $val];
2841
-			}
2842
-		}
2843
-	}
2844
-
2845
-	// puis on rassemble le tout
2846
-	$hidden = [];
2847
-	foreach ($values as $value) {
2848
-		[$var, $val] = $value;
2849
-		$hidden[] = '<input name="'
2850
-			. entites_html($var)
2851
-			. '"'
2852
-			. (is_null($val)
2853
-				? ''
2854
-				: ' value="' . entites_html($val) . '"'
2855
-			)
2856
-			. ' type="hidden"' . "\n/>";
2857
-	}
2858
-
2859
-	return join('', $hidden);
2787
+    $action ??= '';
2788
+
2789
+    $contexte = [];
2790
+    include_spip('inc/urls');
2791
+    if (
2792
+        $p = urls_decoder_url($action, '')
2793
+        and reset($p)
2794
+    ) {
2795
+        $fond = array_shift($p);
2796
+        if ($fond != '404') {
2797
+            $contexte = array_shift($p);
2798
+            $contexte['page'] = $fond;
2799
+            $action = preg_replace('/([?]' . preg_quote($fond) . '[^&=]*[0-9]+)(&|$)/', '?&', $action);
2800
+        }
2801
+    }
2802
+    // defaire ce qu'a injecte urls_decoder_url : a revoir en modifiant la signature de urls_decoder_url
2803
+    if (defined('_DEFINIR_CONTEXTE_TYPE') and _DEFINIR_CONTEXTE_TYPE) {
2804
+        unset($contexte['type']);
2805
+    }
2806
+    if (!defined('_DEFINIR_CONTEXTE_TYPE_PAGE') or _DEFINIR_CONTEXTE_TYPE_PAGE) {
2807
+        unset($contexte['type-page']);
2808
+    }
2809
+
2810
+    // on va remplir un tableau de valeurs en prenant bien soin de ne pas
2811
+    // ecraser les elements de la forme mots[]=1&mots[]=2
2812
+    $values = [];
2813
+
2814
+    // d'abord avec celles de l'url
2815
+    if (false !== ($p = strpos($action, '?'))) {
2816
+        foreach (preg_split('/&(amp;)?/S', substr($action, $p + 1)) as $c) {
2817
+            $c = explode('=', $c, 2);
2818
+            $var = array_shift($c);
2819
+            $val = array_shift($c) ?? '';
2820
+            if ($var) {
2821
+                $val = rawurldecode($val);
2822
+                $var = rawurldecode($var); // decoder les [] eventuels
2823
+                if (preg_match(',\[\]$,S', $var)) {
2824
+                    $values[] = [$var, $val];
2825
+                } else {
2826
+                    if (!isset($values[$var])) {
2827
+                        $values[$var] = [$var, $val];
2828
+                    }
2829
+                }
2830
+            }
2831
+        }
2832
+    }
2833
+
2834
+    // ensuite avec celles du contexte, sans doublonner !
2835
+    foreach ($contexte as $var => $val) {
2836
+        if (preg_match(',\[\]$,S', $var)) {
2837
+            $values[] = [$var, $val];
2838
+        } else {
2839
+            if (!isset($values[$var])) {
2840
+                $values[$var] = [$var, $val];
2841
+            }
2842
+        }
2843
+    }
2844
+
2845
+    // puis on rassemble le tout
2846
+    $hidden = [];
2847
+    foreach ($values as $value) {
2848
+        [$var, $val] = $value;
2849
+        $hidden[] = '<input name="'
2850
+            . entites_html($var)
2851
+            . '"'
2852
+            . (is_null($val)
2853
+                ? ''
2854
+                : ' value="' . entites_html($val) . '"'
2855
+            )
2856
+            . ' type="hidden"' . "\n/>";
2857
+    }
2858
+
2859
+    return join('', $hidden);
2860 2860
 }
2861 2861
 
2862 2862
 
@@ -2878,7 +2878,7 @@  discard block
 block discarded – undo
2878 2878
  *    - la première valeur du tableau sinon.
2879 2879
  **/
2880 2880
 function filtre_reset($array) {
2881
-	return !is_array($array) ? null : reset($array);
2881
+    return !is_array($array) ? null : reset($array);
2882 2882
 }
2883 2883
 
2884 2884
 /**
@@ -2899,7 +2899,7 @@  discard block
 block discarded – undo
2899 2899
  *    - la dernière valeur du tableau sinon.
2900 2900
  **/
2901 2901
 function filtre_end($array) {
2902
-	return !is_array($array) ? null : end($array);
2902
+    return !is_array($array) ? null : end($array);
2903 2903
 }
2904 2904
 
2905 2905
 /**
@@ -2919,11 +2919,11 @@  discard block
 block discarded – undo
2919 2919
  *
2920 2920
  **/
2921 2921
 function filtre_push($array, $val) {
2922
-	if (!is_array($array) or !array_push($array, $val)) {
2923
-		return '';
2924
-	}
2922
+    if (!is_array($array) or !array_push($array, $val)) {
2923
+        return '';
2924
+    }
2925 2925
 
2926
-	return $array;
2926
+    return $array;
2927 2927
 }
2928 2928
 
2929 2929
 /**
@@ -2942,7 +2942,7 @@  discard block
 block discarded – undo
2942 2942
  *     - `true` si la valeur existe dans le tableau, `false` sinon.
2943 2943
  **/
2944 2944
 function filtre_find($array, $val) {
2945
-	return (is_array($array) and in_array($val, $array));
2945
+    return (is_array($array) and in_array($val, $array));
2946 2946
 }
2947 2947
 
2948 2948
 
@@ -2959,13 +2959,13 @@  discard block
 block discarded – undo
2959 2959
  *     Contenu avec urls en absolus
2960 2960
  **/
2961 2961
 function urls_absolues_css($contenu, $source) {
2962
-	$path = suivre_lien(url_absolue($source), './');
2962
+    $path = suivre_lien(url_absolue($source), './');
2963 2963
 
2964
-	return preg_replace_callback(
2965
-		",url\s*\(\s*['\"]?([^'\"/#\s][^:]*)['\"]?\s*\),Uims",
2966
-		fn($x) => "url('" . suivre_lien($path, $x[1]) . "')",
2967
-		$contenu
2968
-	);
2964
+    return preg_replace_callback(
2965
+        ",url\s*\(\s*['\"]?([^'\"/#\s][^:]*)['\"]?\s*\),Uims",
2966
+        fn($x) => "url('" . suivre_lien($path, $x[1]) . "')",
2967
+        $contenu
2968
+    );
2969 2969
 }
2970 2970
 
2971 2971
 
@@ -2994,119 +2994,119 @@  discard block
 block discarded – undo
2994 2994
  *     Chemin du fichier CSS inversé
2995 2995
  **/
2996 2996
 function direction_css($css, $voulue = '') {
2997
-	if (!preg_match(',(_rtl)?\.css$,i', $css, $r)) {
2998
-		return $css;
2999
-	}
3000
-	include_spip('inc/lang');
3001
-	// si on a precise le sens voulu en argument, le prendre en compte
3002
-	if ($voulue = strtolower($voulue)) {
3003
-		if ($voulue != 'rtl' and $voulue != 'ltr') {
3004
-			$voulue = lang_dir($voulue);
3005
-		}
3006
-	} else {
3007
-		$voulue = lang_dir();
3008
-	}
3009
-
3010
-	$r = count($r) > 1;
3011
-	$right = $r ? 'left' : 'right'; // 'right' de la css lue en entree
3012
-	$dir = $r ? 'rtl' : 'ltr';
3013
-	$ndir = $r ? 'ltr' : 'rtl';
3014
-
3015
-	if ($voulue == $dir) {
3016
-		return $css;
3017
-	}
3018
-
3019
-	if (
3020
-		// url absolue
3021
-		preg_match(',^https?:,i', $css)
3022
-		// ou qui contient un ?
3023
-		or (($p = strpos($css, '?')) !== false)
3024
-	) {
3025
-		$distant = true;
3026
-		$cssf = parse_url($css);
3027
-		$cssf = $cssf['path'] . ($cssf['query'] ? '?' . $cssf['query'] : '');
3028
-		$cssf = preg_replace(',[?:&=],', '_', $cssf);
3029
-	} else {
3030
-		$distant = false;
3031
-		$cssf = $css;
3032
-		// 1. regarder d'abord si un fichier avec la bonne direction n'est pas aussi
3033
-		//propose (rien a faire dans ce cas)
3034
-		$f = preg_replace(',(_rtl)?\.css$,i', '_' . $ndir . '.css', $css);
3035
-		if (@file_exists($f)) {
3036
-			return $f;
3037
-		}
3038
-	}
3039
-
3040
-	// 2.
3041
-	$dir_var = sous_repertoire(_DIR_VAR, 'cache-css');
3042
-	$f = $dir_var
3043
-		. preg_replace(',.*/(.*?)(_rtl)?\.css,', '\1', $cssf)
3044
-		. '.' . substr(md5($cssf), 0, 4) . '_' . $ndir . '.css';
3045
-
3046
-	// la css peut etre distante (url absolue !)
3047
-	if ($distant) {
3048
-		include_spip('inc/distant');
3049
-		$res = recuperer_url($css);
3050
-		if (!$res or !$contenu = $res['page']) {
3051
-			return $css;
3052
-		}
3053
-	} else {
3054
-		if (
3055
-			(@filemtime($f) > @filemtime($css))
3056
-			and (_VAR_MODE != 'recalcul')
3057
-		) {
3058
-			return $f;
3059
-		}
3060
-		if (!lire_fichier($css, $contenu)) {
3061
-			return $css;
3062
-		}
3063
-	}
3064
-
3065
-
3066
-	// Inverser la direction gauche-droite en utilisant CSSTidy qui gere aussi les shorthands
3067
-	include_spip('lib/csstidy/class.csstidy');
3068
-	$parser = new csstidy();
3069
-	$parser->set_cfg('optimise_shorthands', 0);
3070
-	$parser->set_cfg('reverse_left_and_right', true);
3071
-	$parser->parse($contenu);
3072
-
3073
-	$contenu = $parser->print->plain();
3074
-
3075
-
3076
-	// reperer les @import auxquels il faut propager le direction_css
3077
-	preg_match_all(",\@import\s*url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),Uims", $contenu, $regs);
3078
-	$src = [];
3079
-	$src_direction_css = [];
3080
-	$src_faux_abs = [];
3081
-	$d = dirname($css);
3082
-	foreach ($regs[1] as $k => $import_css) {
3083
-		$css_direction = direction_css("$d/$import_css", $voulue);
3084
-		// si la css_direction est dans le meme path que la css d'origine, on tronque le path, elle sera passee en absolue
3085
-		if (substr($css_direction, 0, strlen($d) + 1) == "$d/") {
3086
-			$css_direction = substr($css_direction, strlen($d) + 1);
3087
-		} // si la css_direction commence par $dir_var on la fait passer pour une absolue
3088
-		elseif (substr($css_direction, 0, strlen($dir_var)) == $dir_var) {
3089
-			$css_direction = substr($css_direction, strlen($dir_var));
3090
-			$src_faux_abs['/@@@@@@/' . $css_direction] = $css_direction;
3091
-			$css_direction = '/@@@@@@/' . $css_direction;
3092
-		}
3093
-		$src[] = $regs[0][$k];
3094
-		$src_direction_css[] = str_replace($import_css, $css_direction, $regs[0][$k]);
3095
-	}
3096
-	$contenu = str_replace($src, $src_direction_css, $contenu);
3097
-
3098
-	$contenu = urls_absolues_css($contenu, $css);
3099
-
3100
-	// virer les fausses url absolues que l'on a mis dans les import
3101
-	if (count($src_faux_abs)) {
3102
-		$contenu = str_replace(array_keys($src_faux_abs), $src_faux_abs, $contenu);
3103
-	}
3104
-
3105
-	if (!ecrire_fichier($f, $contenu)) {
3106
-		return $css;
3107
-	}
3108
-
3109
-	return $f;
2997
+    if (!preg_match(',(_rtl)?\.css$,i', $css, $r)) {
2998
+        return $css;
2999
+    }
3000
+    include_spip('inc/lang');
3001
+    // si on a precise le sens voulu en argument, le prendre en compte
3002
+    if ($voulue = strtolower($voulue)) {
3003
+        if ($voulue != 'rtl' and $voulue != 'ltr') {
3004
+            $voulue = lang_dir($voulue);
3005
+        }
3006
+    } else {
3007
+        $voulue = lang_dir();
3008
+    }
3009
+
3010
+    $r = count($r) > 1;
3011
+    $right = $r ? 'left' : 'right'; // 'right' de la css lue en entree
3012
+    $dir = $r ? 'rtl' : 'ltr';
3013
+    $ndir = $r ? 'ltr' : 'rtl';
3014
+
3015
+    if ($voulue == $dir) {
3016
+        return $css;
3017
+    }
3018
+
3019
+    if (
3020
+        // url absolue
3021
+        preg_match(',^https?:,i', $css)
3022
+        // ou qui contient un ?
3023
+        or (($p = strpos($css, '?')) !== false)
3024
+    ) {
3025
+        $distant = true;
3026
+        $cssf = parse_url($css);
3027
+        $cssf = $cssf['path'] . ($cssf['query'] ? '?' . $cssf['query'] : '');
3028
+        $cssf = preg_replace(',[?:&=],', '_', $cssf);
3029
+    } else {
3030
+        $distant = false;
3031
+        $cssf = $css;
3032
+        // 1. regarder d'abord si un fichier avec la bonne direction n'est pas aussi
3033
+        //propose (rien a faire dans ce cas)
3034
+        $f = preg_replace(',(_rtl)?\.css$,i', '_' . $ndir . '.css', $css);
3035
+        if (@file_exists($f)) {
3036
+            return $f;
3037
+        }
3038
+    }
3039
+
3040
+    // 2.
3041
+    $dir_var = sous_repertoire(_DIR_VAR, 'cache-css');
3042
+    $f = $dir_var
3043
+        . preg_replace(',.*/(.*?)(_rtl)?\.css,', '\1', $cssf)
3044
+        . '.' . substr(md5($cssf), 0, 4) . '_' . $ndir . '.css';
3045
+
3046
+    // la css peut etre distante (url absolue !)
3047
+    if ($distant) {
3048
+        include_spip('inc/distant');
3049
+        $res = recuperer_url($css);
3050
+        if (!$res or !$contenu = $res['page']) {
3051
+            return $css;
3052
+        }
3053
+    } else {
3054
+        if (
3055
+            (@filemtime($f) > @filemtime($css))
3056
+            and (_VAR_MODE != 'recalcul')
3057
+        ) {
3058
+            return $f;
3059
+        }
3060
+        if (!lire_fichier($css, $contenu)) {
3061
+            return $css;
3062
+        }
3063
+    }
3064
+
3065
+
3066
+    // Inverser la direction gauche-droite en utilisant CSSTidy qui gere aussi les shorthands
3067
+    include_spip('lib/csstidy/class.csstidy');
3068
+    $parser = new csstidy();
3069
+    $parser->set_cfg('optimise_shorthands', 0);
3070
+    $parser->set_cfg('reverse_left_and_right', true);
3071
+    $parser->parse($contenu);
3072
+
3073
+    $contenu = $parser->print->plain();
3074
+
3075
+
3076
+    // reperer les @import auxquels il faut propager le direction_css
3077
+    preg_match_all(",\@import\s*url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),Uims", $contenu, $regs);
3078
+    $src = [];
3079
+    $src_direction_css = [];
3080
+    $src_faux_abs = [];
3081
+    $d = dirname($css);
3082
+    foreach ($regs[1] as $k => $import_css) {
3083
+        $css_direction = direction_css("$d/$import_css", $voulue);
3084
+        // si la css_direction est dans le meme path que la css d'origine, on tronque le path, elle sera passee en absolue
3085
+        if (substr($css_direction, 0, strlen($d) + 1) == "$d/") {
3086
+            $css_direction = substr($css_direction, strlen($d) + 1);
3087
+        } // si la css_direction commence par $dir_var on la fait passer pour une absolue
3088
+        elseif (substr($css_direction, 0, strlen($dir_var)) == $dir_var) {
3089
+            $css_direction = substr($css_direction, strlen($dir_var));
3090
+            $src_faux_abs['/@@@@@@/' . $css_direction] = $css_direction;
3091
+            $css_direction = '/@@@@@@/' . $css_direction;
3092
+        }
3093
+        $src[] = $regs[0][$k];
3094
+        $src_direction_css[] = str_replace($import_css, $css_direction, $regs[0][$k]);
3095
+    }
3096
+    $contenu = str_replace($src, $src_direction_css, $contenu);
3097
+
3098
+    $contenu = urls_absolues_css($contenu, $css);
3099
+
3100
+    // virer les fausses url absolues que l'on a mis dans les import
3101
+    if (count($src_faux_abs)) {
3102
+        $contenu = str_replace(array_keys($src_faux_abs), $src_faux_abs, $contenu);
3103
+    }
3104
+
3105
+    if (!ecrire_fichier($f, $contenu)) {
3106
+        return $css;
3107
+    }
3108
+
3109
+    return $f;
3110 3110
 }
3111 3111
 
3112 3112
 
@@ -3129,46 +3129,46 @@  discard block
 block discarded – undo
3129 3129
  *     - Chemin ou URL du fichier CSS source sinon.
3130 3130
  **/
3131 3131
 function url_absolue_css($css) {
3132
-	if (!preg_match(',\.css$,i', $css, $r)) {
3133
-		return $css;
3134
-	}
3132
+    if (!preg_match(',\.css$,i', $css, $r)) {
3133
+        return $css;
3134
+    }
3135 3135
 
3136
-	$url_absolue_css = url_absolue($css);
3136
+    $url_absolue_css = url_absolue($css);
3137 3137
 
3138
-	$f = basename($css, '.css');
3139
-	$f = sous_repertoire(_DIR_VAR, 'cache-css')
3140
-		. preg_replace(',(.*?)(_rtl|_ltr)?$,', "\\1-urlabs-" . substr(md5("$css-urlabs"), 0, 4) . "\\2", $f)
3141
-		. '.css';
3138
+    $f = basename($css, '.css');
3139
+    $f = sous_repertoire(_DIR_VAR, 'cache-css')
3140
+        . preg_replace(',(.*?)(_rtl|_ltr)?$,', "\\1-urlabs-" . substr(md5("$css-urlabs"), 0, 4) . "\\2", $f)
3141
+        . '.css';
3142 3142
 
3143
-	if ((@filemtime($f) > @filemtime($css)) and (_VAR_MODE != 'recalcul')) {
3144
-		return $f;
3145
-	}
3143
+    if ((@filemtime($f) > @filemtime($css)) and (_VAR_MODE != 'recalcul')) {
3144
+        return $f;
3145
+    }
3146 3146
 
3147
-	if ($url_absolue_css == $css) {
3148
-		if (
3149
-			strncmp($GLOBALS['meta']['adresse_site'], $css, $l = strlen($GLOBALS['meta']['adresse_site'])) != 0
3150
-			or !lire_fichier(_DIR_RACINE . substr($css, $l), $contenu)
3151
-		) {
3152
-			include_spip('inc/distant');
3153
-			$contenu = recuperer_url($css);
3154
-			$contenu = $contenu['page'] ?? '';
3155
-			if (!$contenu) {
3156
-				return $css;
3157
-			}
3158
-		}
3159
-	} elseif (!lire_fichier($css, $contenu)) {
3160
-		return $css;
3161
-	}
3147
+    if ($url_absolue_css == $css) {
3148
+        if (
3149
+            strncmp($GLOBALS['meta']['adresse_site'], $css, $l = strlen($GLOBALS['meta']['adresse_site'])) != 0
3150
+            or !lire_fichier(_DIR_RACINE . substr($css, $l), $contenu)
3151
+        ) {
3152
+            include_spip('inc/distant');
3153
+            $contenu = recuperer_url($css);
3154
+            $contenu = $contenu['page'] ?? '';
3155
+            if (!$contenu) {
3156
+                return $css;
3157
+            }
3158
+        }
3159
+    } elseif (!lire_fichier($css, $contenu)) {
3160
+        return $css;
3161
+    }
3162 3162
 
3163
-	// passer les url relatives a la css d'origine en url absolues
3164
-	$contenu = urls_absolues_css($contenu, $css);
3163
+    // passer les url relatives a la css d'origine en url absolues
3164
+    $contenu = urls_absolues_css($contenu, $css);
3165 3165
 
3166
-	// ecrire la css
3167
-	if (!ecrire_fichier($f, $contenu)) {
3168
-		return $css;
3169
-	}
3166
+    // ecrire la css
3167
+    if (!ecrire_fichier($f, $contenu)) {
3168
+        return $css;
3169
+    }
3170 3170
 
3171
-	return $f;
3171
+    return $f;
3172 3172
 }
3173 3173
 
3174 3174
 
@@ -3202,24 +3202,24 @@  discard block
 block discarded – undo
3202 3202
  *     Valeur trouvée ou valeur par défaut.
3203 3203
  **/
3204 3204
 function table_valeur($table, $cle, $defaut = '', $conserver_null = false) {
3205
-	foreach (explode('/', $cle) as $k) {
3206
-		$table = (is_string($table) ? @unserialize($table) : $table);
3205
+    foreach (explode('/', $cle) as $k) {
3206
+        $table = (is_string($table) ? @unserialize($table) : $table);
3207 3207
 
3208
-		if (is_object($table)) {
3209
-			$table = (($k !== '') and isset($table->$k)) ? $table->$k : $defaut;
3210
-		} elseif (is_array($table)) {
3211
-			if ($conserver_null) {
3212
-				$table = array_key_exists($k, $table) ? $table[$k] : $defaut;
3213
-			} else {
3214
-				$table = ($table[$k] ?? $defaut);
3215
-			}
3216
-		} else {
3217
-			$table = $defaut;
3218
-			break;
3219
-		}
3220
-	}
3208
+        if (is_object($table)) {
3209
+            $table = (($k !== '') and isset($table->$k)) ? $table->$k : $defaut;
3210
+        } elseif (is_array($table)) {
3211
+            if ($conserver_null) {
3212
+                $table = array_key_exists($k, $table) ? $table[$k] : $defaut;
3213
+            } else {
3214
+                $table = ($table[$k] ?? $defaut);
3215
+            }
3216
+        } else {
3217
+            $table = $defaut;
3218
+            break;
3219
+        }
3220
+    }
3221 3221
 
3222
-	return $table;
3222
+    return $table;
3223 3223
 }
3224 3224
 
3225 3225
 /**
@@ -3252,22 +3252,22 @@  discard block
 block discarded – undo
3252 3252
  *     - string : expression trouvée.
3253 3253
  **/
3254 3254
 function filtre_match_dist(?string $texte, $expression, $modif = 'UimsS', $capte = 0) {
3255
-	if (intval($modif) and $capte == 0) {
3256
-		$capte = $modif;
3257
-		$modif = 'UimsS';
3258
-	}
3259
-	$expression = str_replace('\/', '/', $expression);
3260
-	$expression = str_replace('/', '\/', $expression);
3255
+    if (intval($modif) and $capte == 0) {
3256
+        $capte = $modif;
3257
+        $modif = 'UimsS';
3258
+    }
3259
+    $expression = str_replace('\/', '/', $expression);
3260
+    $expression = str_replace('/', '\/', $expression);
3261 3261
 
3262
-	if (preg_match('/' . $expression . '/' . $modif, $texte ?? '', $r)) {
3263
-		if (isset($r[$capte])) {
3264
-			return $r[$capte];
3265
-		} else {
3266
-			return true;
3267
-		}
3268
-	}
3262
+    if (preg_match('/' . $expression . '/' . $modif, $texte ?? '', $r)) {
3263
+        if (isset($r[$capte])) {
3264
+            return $r[$capte];
3265
+        } else {
3266
+            return true;
3267
+        }
3268
+    }
3269 3269
 
3270
-	return false;
3270
+    return false;
3271 3271
 }
3272 3272
 
3273 3273
 
@@ -3294,10 +3294,10 @@  discard block
 block discarded – undo
3294 3294
  *     Texte
3295 3295
  **/
3296 3296
 function replace($texte, $expression, $replace = '', $modif = 'UimsS') {
3297
-	$expression = str_replace('\/', '/', $expression);
3298
-	$expression = str_replace('/', '\/', $expression);
3297
+    $expression = str_replace('\/', '/', $expression);
3298
+    $expression = str_replace('/', '\/', $expression);
3299 3299
 
3300
-	return preg_replace('/' . $expression . '/' . $modif, $replace, $texte);
3300
+    return preg_replace('/' . $expression . '/' . $modif, $replace, $texte);
3301 3301
 }
3302 3302
 
3303 3303
 
@@ -3315,25 +3315,25 @@  discard block
 block discarded – undo
3315 3315
  **/
3316 3316
 function traiter_doublons_documents(&$doublons, $letexte) {
3317 3317
 
3318
-	// Verifier dans le texte & les notes (pas beau, helas)
3319
-	$t = $letexte . $GLOBALS['les_notes'];
3318
+    // Verifier dans le texte & les notes (pas beau, helas)
3319
+    $t = $letexte . $GLOBALS['les_notes'];
3320 3320
 
3321
-	if (
3322
-		strstr($t, 'spip_document_') // evite le preg_match_all si inutile
3323
-		and preg_match_all(
3324
-			',<[^>]+\sclass=["\']spip_document_([0-9]+)[\s"\'],imsS',
3325
-			$t,
3326
-			$matches,
3327
-			PREG_PATTERN_ORDER
3328
-		)
3329
-	) {
3330
-		if (!isset($doublons['documents'])) {
3331
-			$doublons['documents'] = '';
3332
-		}
3333
-		$doublons['documents'] .= ',' . join(',', $matches[1]);
3334
-	}
3321
+    if (
3322
+        strstr($t, 'spip_document_') // evite le preg_match_all si inutile
3323
+        and preg_match_all(
3324
+            ',<[^>]+\sclass=["\']spip_document_([0-9]+)[\s"\'],imsS',
3325
+            $t,
3326
+            $matches,
3327
+            PREG_PATTERN_ORDER
3328
+        )
3329
+    ) {
3330
+        if (!isset($doublons['documents'])) {
3331
+            $doublons['documents'] = '';
3332
+        }
3333
+        $doublons['documents'] .= ',' . join(',', $matches[1]);
3334
+    }
3335 3335
 
3336
-	return $letexte;
3336
+    return $letexte;
3337 3337
 }
3338 3338
 
3339 3339
 /**
@@ -3347,7 +3347,7 @@  discard block
 block discarded – undo
3347 3347
  * @return string Chaîne vide
3348 3348
  **/
3349 3349
 function vide($texte) {
3350
-	return '';
3350
+    return '';
3351 3351
 }
3352 3352
 
3353 3353
 //
@@ -3376,23 +3376,23 @@  discard block
 block discarded – undo
3376 3376
  *      Code HTML résultant
3377 3377
  **/
3378 3378
 function env_to_params($env, $ignore_params = []) {
3379
-	$ignore_params = array_merge(
3380
-		['id', 'lang', 'id_document', 'date', 'date_redac', 'align', 'fond', '', 'recurs', 'emb', 'dir_racine'],
3381
-		$ignore_params
3382
-	);
3383
-	if (!is_array($env)) {
3384
-		$env = unserialize($env);
3385
-	}
3386
-	$texte = '';
3387
-	if ($env) {
3388
-		foreach ($env as $i => $j) {
3389
-			if (is_string($j) and !in_array($i, $ignore_params)) {
3390
-				$texte .= "<param name='" . attribut_html($i) . "'\n\tvalue='" . attribut_html($j) . "' />";
3391
-			}
3392
-		}
3393
-	}
3394
-
3395
-	return $texte;
3379
+    $ignore_params = array_merge(
3380
+        ['id', 'lang', 'id_document', 'date', 'date_redac', 'align', 'fond', '', 'recurs', 'emb', 'dir_racine'],
3381
+        $ignore_params
3382
+    );
3383
+    if (!is_array($env)) {
3384
+        $env = unserialize($env);
3385
+    }
3386
+    $texte = '';
3387
+    if ($env) {
3388
+        foreach ($env as $i => $j) {
3389
+            if (is_string($j) and !in_array($i, $ignore_params)) {
3390
+                $texte .= "<param name='" . attribut_html($i) . "'\n\tvalue='" . attribut_html($j) . "' />";
3391
+            }
3392
+        }
3393
+    }
3394
+
3395
+    return $texte;
3396 3396
 }
3397 3397
 
3398 3398
 /**
@@ -3415,23 +3415,23 @@  discard block
 block discarded – undo
3415 3415
  *      Code HTML résultant
3416 3416
  **/
3417 3417
 function env_to_attributs($env, $ignore_params = []) {
3418
-	$ignore_params = array_merge(
3419
-		['id', 'lang', 'id_document', 'date', 'date_redac', 'align', 'fond', '', 'recurs', 'emb', 'dir_racine'],
3420
-		$ignore_params
3421
-	);
3422
-	if (!is_array($env)) {
3423
-		$env = unserialize($env);
3424
-	}
3425
-	$texte = '';
3426
-	if ($env) {
3427
-		foreach ($env as $i => $j) {
3428
-			if (is_string($j) and !in_array($i, $ignore_params)) {
3429
-				$texte .= attribut_html($i) . "='" . attribut_html($j) . "' ";
3430
-			}
3431
-		}
3432
-	}
3418
+    $ignore_params = array_merge(
3419
+        ['id', 'lang', 'id_document', 'date', 'date_redac', 'align', 'fond', '', 'recurs', 'emb', 'dir_racine'],
3420
+        $ignore_params
3421
+    );
3422
+    if (!is_array($env)) {
3423
+        $env = unserialize($env);
3424
+    }
3425
+    $texte = '';
3426
+    if ($env) {
3427
+        foreach ($env as $i => $j) {
3428
+            if (is_string($j) and !in_array($i, $ignore_params)) {
3429
+                $texte .= attribut_html($i) . "='" . attribut_html($j) . "' ";
3430
+            }
3431
+        }
3432
+    }
3433 3433
 
3434
-	return $texte;
3434
+    return $texte;
3435 3435
 }
3436 3436
 
3437 3437
 
@@ -3449,7 +3449,7 @@  discard block
 block discarded – undo
3449 3449
  * @return string Chaînes concaténés
3450 3450
  **/
3451 3451
 function concat(...$args): string {
3452
-	return join('', $args);
3452
+    return join('', $args);
3453 3453
 }
3454 3454
 
3455 3455
 
@@ -3469,23 +3469,23 @@  discard block
 block discarded – undo
3469 3469
  *     Contenu du ou des fichiers, concaténé
3470 3470
  **/
3471 3471
 function charge_scripts($files, $script = true) {
3472
-	$flux = '';
3473
-	foreach (is_array($files) ? $files : explode('|', $files) as $file) {
3474
-		if (!is_string($file)) {
3475
-			continue;
3476
-		}
3477
-		if ($script) {
3478
-			$file = preg_match(',^\w+$,', $file) ? "javascript/$file.js" : '';
3479
-		}
3480
-		if ($file) {
3481
-			$path = find_in_path($file);
3482
-			if ($path) {
3483
-				$flux .= spip_file_get_contents($path);
3484
-			}
3485
-		}
3486
-	}
3487
-
3488
-	return $flux;
3472
+    $flux = '';
3473
+    foreach (is_array($files) ? $files : explode('|', $files) as $file) {
3474
+        if (!is_string($file)) {
3475
+            continue;
3476
+        }
3477
+        if ($script) {
3478
+            $file = preg_match(',^\w+$,', $file) ? "javascript/$file.js" : '';
3479
+        }
3480
+        if ($file) {
3481
+            $path = find_in_path($file);
3482
+            if ($path) {
3483
+                $flux .= spip_file_get_contents($path);
3484
+            }
3485
+        }
3486
+    }
3487
+
3488
+    return $flux;
3489 3489
 }
3490 3490
 
3491 3491
 /**
@@ -3496,22 +3496,22 @@  discard block
 block discarded – undo
3496 3496
  * @return string
3497 3497
  */
3498 3498
 function http_img_variante_svg_si_possible($img_file) {
3499
-	// on peut fournir une icone generique -xx.svg qui fera le job dans toutes les tailles, et qui est prioritaire sur le png
3500
-	// si il y a un .svg a la bonne taille (-16.svg) a cote, on l'utilise en remplacement du -16.png
3501
-	if (
3502
-		preg_match(',-(\d+)[.](png|gif|svg)$,', $img_file, $m)
3503
-		and $variante_svg_generique = substr($img_file, 0, -strlen($m[0])) . '-xx.svg'
3504
-		and file_exists($variante_svg_generique)
3505
-	) {
3506
-		if ($variante_svg_size = substr($variante_svg_generique, 0, -6) . $m[1] . '.svg' and file_exists($variante_svg_size)) {
3507
-			$img_file = $variante_svg_size;
3508
-		}
3509
-		else {
3510
-			$img_file = $variante_svg_generique;
3511
-		}
3512
-	}
3499
+    // on peut fournir une icone generique -xx.svg qui fera le job dans toutes les tailles, et qui est prioritaire sur le png
3500
+    // si il y a un .svg a la bonne taille (-16.svg) a cote, on l'utilise en remplacement du -16.png
3501
+    if (
3502
+        preg_match(',-(\d+)[.](png|gif|svg)$,', $img_file, $m)
3503
+        and $variante_svg_generique = substr($img_file, 0, -strlen($m[0])) . '-xx.svg'
3504
+        and file_exists($variante_svg_generique)
3505
+    ) {
3506
+        if ($variante_svg_size = substr($variante_svg_generique, 0, -6) . $m[1] . '.svg' and file_exists($variante_svg_size)) {
3507
+            $img_file = $variante_svg_size;
3508
+        }
3509
+        else {
3510
+            $img_file = $variante_svg_generique;
3511
+        }
3512
+    }
3513 3513
 
3514
-	return $img_file;
3514
+    return $img_file;
3515 3515
 }
3516 3516
 
3517 3517
 /**
@@ -3533,57 +3533,57 @@  discard block
 block discarded – undo
3533 3533
  */
3534 3534
 function http_img_pack($img, $alt, $atts = '', $title = '', $options = []) {
3535 3535
 
3536
-	$img_file = $img;
3537
-	if ($p = strpos($img_file, '?')) {
3538
-		$img_file = substr($img_file, 0, $p);
3539
-	}
3540
-	if (!isset($options['chemin_image']) or $options['chemin_image'] == true) {
3541
-		$img_file = chemin_image($img);
3542
-	}
3543
-	else {
3544
-		if (!isset($options['variante_svg_si_possible']) or $options['variante_svg_si_possible'] == true) {
3545
-			$img_file = http_img_variante_svg_si_possible($img_file);
3546
-		}
3547
-	}
3548
-	if (stripos($atts, 'width') === false) {
3549
-		// utiliser directement l'info de taille presente dans le nom
3550
-		if (
3551
-			(!isset($options['utiliser_suffixe_size'])
3552
-				or $options['utiliser_suffixe_size'] == true
3553
-			  or strpos($img_file, '-xx.svg') !== false)
3554
-			and (preg_match(',-([0-9]+)[.](png|gif|svg)$,', $img, $regs)
3555
-					 or preg_match(',\?([0-9]+)px$,', $img, $regs))
3556
-		) {
3557
-			$largeur = $hauteur = intval($regs[1]);
3558
-		} else {
3559
-			$taille = taille_image($img_file);
3560
-			[$hauteur, $largeur] = $taille;
3561
-			if (!$hauteur or !$largeur) {
3562
-				return '';
3563
-			}
3564
-		}
3565
-		$atts .= " width='" . $largeur . "' height='" . $hauteur . "'";
3566
-	}
3567
-
3568
-	if (file_exists($img_file)) {
3569
-		$img_file = timestamp($img_file);
3570
-	} elseif ($alternative = $options['alternative'] ?? '') {
3571
-		unset($options['alternative']);
3572
-		return http_img_pack($alternative, $alt, $atts, $title, $options);
3573
-	}
3574
-	if ($alt === false) {
3575
-		$alt = '';
3576
-	}
3577
-	elseif ($alt or $alt === '') {
3578
-		$alt = " alt='" . attribut_html($alt) . "'";
3579
-	}
3580
-	else {
3581
-		$alt = " alt='" . attribut_html($title) . "'";
3582
-	}
3583
-	return "<img src='$img_file'$alt"
3584
-	. ($title ? ' title="' . attribut_html($title) . '"' : '')
3585
-	. ' ' . ltrim($atts)
3586
-	. ' />';
3536
+    $img_file = $img;
3537
+    if ($p = strpos($img_file, '?')) {
3538
+        $img_file = substr($img_file, 0, $p);
3539
+    }
3540
+    if (!isset($options['chemin_image']) or $options['chemin_image'] == true) {
3541
+        $img_file = chemin_image($img);
3542
+    }
3543
+    else {
3544
+        if (!isset($options['variante_svg_si_possible']) or $options['variante_svg_si_possible'] == true) {
3545
+            $img_file = http_img_variante_svg_si_possible($img_file);
3546
+        }
3547
+    }
3548
+    if (stripos($atts, 'width') === false) {
3549
+        // utiliser directement l'info de taille presente dans le nom
3550
+        if (
3551
+            (!isset($options['utiliser_suffixe_size'])
3552
+                or $options['utiliser_suffixe_size'] == true
3553
+              or strpos($img_file, '-xx.svg') !== false)
3554
+            and (preg_match(',-([0-9]+)[.](png|gif|svg)$,', $img, $regs)
3555
+                     or preg_match(',\?([0-9]+)px$,', $img, $regs))
3556
+        ) {
3557
+            $largeur = $hauteur = intval($regs[1]);
3558
+        } else {
3559
+            $taille = taille_image($img_file);
3560
+            [$hauteur, $largeur] = $taille;
3561
+            if (!$hauteur or !$largeur) {
3562
+                return '';
3563
+            }
3564
+        }
3565
+        $atts .= " width='" . $largeur . "' height='" . $hauteur . "'";
3566
+    }
3567
+
3568
+    if (file_exists($img_file)) {
3569
+        $img_file = timestamp($img_file);
3570
+    } elseif ($alternative = $options['alternative'] ?? '') {
3571
+        unset($options['alternative']);
3572
+        return http_img_pack($alternative, $alt, $atts, $title, $options);
3573
+    }
3574
+    if ($alt === false) {
3575
+        $alt = '';
3576
+    }
3577
+    elseif ($alt or $alt === '') {
3578
+        $alt = " alt='" . attribut_html($alt) . "'";
3579
+    }
3580
+    else {
3581
+        $alt = " alt='" . attribut_html($title) . "'";
3582
+    }
3583
+    return "<img src='$img_file'$alt"
3584
+    . ($title ? ' title="' . attribut_html($title) . '"' : '')
3585
+    . ' ' . ltrim($atts)
3586
+    . ' />';
3587 3587
 }
3588 3588
 
3589 3589
 /**
@@ -3596,74 +3596,74 @@  discard block
 block discarded – undo
3596 3596
  * @return string
3597 3597
  */
3598 3598
 function http_style_background($img, $att = '', $size = null, $alternative = '') {
3599
-	if ($size and is_numeric($size)) {
3600
-		$size = trim($size) . 'px';
3601
-	}
3599
+    if ($size and is_numeric($size)) {
3600
+        $size = trim($size) . 'px';
3601
+    }
3602 3602
 
3603
-	if (!$img = chemin_image($img)) {
3604
-		$img = chemin_image($alternative);
3605
-	}
3606
-	return " style='background" .
3607
-		($att ? '' : '-image') . ': url("' . $img . '")' . ($att ? (' ' . $att) : '') . ';'
3608
-		. ($size ? "background-size:{$size};" : '')
3609
-		. "'";
3603
+    if (!$img = chemin_image($img)) {
3604
+        $img = chemin_image($alternative);
3605
+    }
3606
+    return " style='background" .
3607
+        ($att ? '' : '-image') . ': url("' . $img . '")' . ($att ? (' ' . $att) : '') . ';'
3608
+        . ($size ? "background-size:{$size};" : '')
3609
+        . "'";
3610 3610
 }
3611 3611
 
3612 3612
 
3613 3613
 function helper_filtre_balise_img_svg_arguments($alt_or_size, $class_or_size, $size) {
3614
-	$args = [$alt_or_size, $class_or_size, $size];
3615
-	while (is_null(end($args)) and count($args)) {
3616
-		array_pop($args);
3617
-	}
3618
-	if (!count($args)) {
3619
-		return [null, null, null];
3620
-	}
3621
-	if (count($args) < 3) {
3622
-		$maybe_size = array_pop($args);
3623
-		// @2x
3624
-		// @1.5x
3625
-		// 512
3626
-		// 512x*
3627
-		// 512x300
3628
-		if (
3629
-			!strlen($maybe_size)
3630
-			or !preg_match(',^(@\d+(\.\d+)?x|\d+(x\*)?|\d+x\d+)$,', trim($maybe_size))
3631
-		) {
3632
-			$args[] = $maybe_size;
3633
-			$maybe_size = null;
3634
-		}
3635
-		while (count($args) < 2) {
3636
-			$args[] = null; // default alt or class
3637
-		}
3638
-		$args[] = $maybe_size;
3639
-	}
3640
-	return $args;
3614
+    $args = [$alt_or_size, $class_or_size, $size];
3615
+    while (is_null(end($args)) and count($args)) {
3616
+        array_pop($args);
3617
+    }
3618
+    if (!count($args)) {
3619
+        return [null, null, null];
3620
+    }
3621
+    if (count($args) < 3) {
3622
+        $maybe_size = array_pop($args);
3623
+        // @2x
3624
+        // @1.5x
3625
+        // 512
3626
+        // 512x*
3627
+        // 512x300
3628
+        if (
3629
+            !strlen($maybe_size)
3630
+            or !preg_match(',^(@\d+(\.\d+)?x|\d+(x\*)?|\d+x\d+)$,', trim($maybe_size))
3631
+        ) {
3632
+            $args[] = $maybe_size;
3633
+            $maybe_size = null;
3634
+        }
3635
+        while (count($args) < 2) {
3636
+            $args[] = null; // default alt or class
3637
+        }
3638
+        $args[] = $maybe_size;
3639
+    }
3640
+    return $args;
3641 3641
 }
3642 3642
 
3643 3643
 function helper_filtre_balise_img_svg_size($img, $size) {
3644
-	// si size est de la forme '@2x' c'est un coeff multiplicateur sur la densite
3645
-	if (strpos($size, '@') === 0 and substr($size, -1) === 'x') {
3646
-		$coef = floatval(substr($size, 1, -1));
3647
-		[$h, $w] = taille_image($img);
3648
-		$height = intval(round($h / $coef));
3649
-		$width = intval(round($w / $coef));
3650
-	}
3651
-	// sinon c'est une valeur seule si image caree ou largeurxhauteur
3652
-	else {
3653
-		$size = explode('x', $size, 2);
3654
-		$size = array_map('trim', $size);
3655
-		$height = $width = intval(array_shift($size));
3656
-
3657
-		if (count($size) and reset($size)) {
3658
-			$height = array_shift($size);
3659
-			if ($height === '*') {
3660
-				[$h, $w] = taille_image($img);
3661
-				$height = intval(round($h * $width / $w));
3662
-			}
3663
-		}
3664
-	}
3665
-
3666
-	return [$width, $height];
3644
+    // si size est de la forme '@2x' c'est un coeff multiplicateur sur la densite
3645
+    if (strpos($size, '@') === 0 and substr($size, -1) === 'x') {
3646
+        $coef = floatval(substr($size, 1, -1));
3647
+        [$h, $w] = taille_image($img);
3648
+        $height = intval(round($h / $coef));
3649
+        $width = intval(round($w / $coef));
3650
+    }
3651
+    // sinon c'est une valeur seule si image caree ou largeurxhauteur
3652
+    else {
3653
+        $size = explode('x', $size, 2);
3654
+        $size = array_map('trim', $size);
3655
+        $height = $width = intval(array_shift($size));
3656
+
3657
+        if (count($size) and reset($size)) {
3658
+            $height = array_shift($size);
3659
+            if ($height === '*') {
3660
+                [$h, $w] = taille_image($img);
3661
+                $height = intval(round($h * $width / $w));
3662
+            }
3663
+        }
3664
+    }
3665
+
3666
+    return [$width, $height];
3667 3667
 }
3668 3668
 
3669 3669
 /**
@@ -3699,43 +3699,43 @@  discard block
 block discarded – undo
3699 3699
  */
3700 3700
 function filtre_balise_img_dist($img, $alt = '', $class = null, $size = null) {
3701 3701
 
3702
-	[$alt, $class, $size] = helper_filtre_balise_img_svg_arguments($alt, $class, $size);
3703
-
3704
-	$img = trim((string) $img);
3705
-	if (strpos($img, '<img') === 0) {
3706
-		if (!is_null($alt)) {
3707
-			$img = inserer_attribut($img, 'alt', $alt);
3708
-		}
3709
-		if (!is_null($class)) {
3710
-			if (strlen($class)) {
3711
-				$img = inserer_attribut($img, 'class', $class);
3712
-			}
3713
-			else {
3714
-				$img = vider_attribut($img, 'class');
3715
-			}
3716
-		}
3717
-	}
3718
-	else {
3719
-		$img = http_img_pack(
3720
-			$img,
3721
-			$alt,
3722
-			$class ? " class='" . attribut_html($class) . "'" : '',
3723
-			'',
3724
-			['chemin_image' => false, 'utiliser_suffixe_size' => false]
3725
-		);
3726
-		if (is_null($alt)) {
3727
-			$img = vider_attribut($img, 'alt');
3728
-		}
3729
-	}
3730
-
3731
-	if ($img and !is_null($size) and strlen($size = trim($size))) {
3732
-		[$width, $height] = helper_filtre_balise_img_svg_size($img, $size);
3733
-
3734
-		$img = inserer_attribut($img, 'width', $width);
3735
-		$img = inserer_attribut($img, 'height', $height);
3736
-	}
3737
-
3738
-	return $img;
3702
+    [$alt, $class, $size] = helper_filtre_balise_img_svg_arguments($alt, $class, $size);
3703
+
3704
+    $img = trim((string) $img);
3705
+    if (strpos($img, '<img') === 0) {
3706
+        if (!is_null($alt)) {
3707
+            $img = inserer_attribut($img, 'alt', $alt);
3708
+        }
3709
+        if (!is_null($class)) {
3710
+            if (strlen($class)) {
3711
+                $img = inserer_attribut($img, 'class', $class);
3712
+            }
3713
+            else {
3714
+                $img = vider_attribut($img, 'class');
3715
+            }
3716
+        }
3717
+    }
3718
+    else {
3719
+        $img = http_img_pack(
3720
+            $img,
3721
+            $alt,
3722
+            $class ? " class='" . attribut_html($class) . "'" : '',
3723
+            '',
3724
+            ['chemin_image' => false, 'utiliser_suffixe_size' => false]
3725
+        );
3726
+        if (is_null($alt)) {
3727
+            $img = vider_attribut($img, 'alt');
3728
+        }
3729
+    }
3730
+
3731
+    if ($img and !is_null($size) and strlen($size = trim($size))) {
3732
+        [$width, $height] = helper_filtre_balise_img_svg_size($img, $size);
3733
+
3734
+        $img = inserer_attribut($img, 'width', $width);
3735
+        $img = inserer_attribut($img, 'height', $height);
3736
+    }
3737
+
3738
+    return $img;
3739 3739
 }
3740 3740
 
3741 3741
 
@@ -3769,80 +3769,80 @@  discard block
 block discarded – undo
3769 3769
  */
3770 3770
 function filtre_balise_svg_dist($img, $alt = '', $class = null, $size = null) {
3771 3771
 
3772
-	$svg = null;
3773
-	$img = trim($img);
3774
-	$img_file = $img;
3775
-	if (strpos($img, '<svg') === false) {
3776
-		if ($p = strpos($img_file, '?')) {
3777
-			$img_file = substr($img_file, 0, $p);
3778
-		}
3779
-
3780
-		// ne jamais operer directement sur une image distante pour des raisons de perfo
3781
-		// la copie locale a toutes les chances d'etre la ou de resservir
3782
-		if (tester_url_absolue($img_file)) {
3783
-			include_spip('inc/distant');
3784
-			$fichier = copie_locale($img_file);
3785
-			$img_file = ($fichier ? _DIR_RACINE . $fichier : $img_file);
3786
-		}
3787
-
3788
-		if (
3789
-			!$img_file
3790
-			or !file_exists($img_file)
3791
-			or !$svg = file_get_contents($img_file)
3792
-		) {
3793
-			return '';
3794
-		}
3795
-	}
3796
-
3797
-	if (!preg_match(",<svg\b[^>]*>,UimsS", $svg, $match)) {
3798
-		return '';
3799
-	}
3800
-
3801
-	[$alt, $class, $size] = helper_filtre_balise_img_svg_arguments($alt, $class, $size);
3802
-
3803
-	$balise_svg = $match[0];
3804
-	$balise_svg_source = $balise_svg;
3805
-
3806
-	// entete XML à supprimer
3807
-	$svg = preg_replace(',^\s*<\?xml[^>]*\?' . '>,', '', $svg);
3808
-
3809
-	// IE est toujours mon ami
3810
-	$balise_svg = inserer_attribut($balise_svg, 'focusable', 'false');
3811
-
3812
-	// regler la classe
3813
-	if (!is_null($class)) {
3814
-		if (strlen($class)) {
3815
-			$balise_svg = inserer_attribut($balise_svg, 'class', $class);
3816
-		}
3817
-		else {
3818
-			$balise_svg = vider_attribut($balise_svg, 'class');
3819
-		}
3820
-	}
3821
-
3822
-	// regler le alt
3823
-	if ($alt) {
3824
-		$balise_svg = inserer_attribut($balise_svg, 'role', 'img');
3825
-		$id = 'img-svg-title-' . substr(md5("$img_file:$svg:$alt"), 0, 4);
3826
-		$balise_svg = inserer_attribut($balise_svg, 'aria-labelledby', $id);
3827
-		$title = "<title id=\"$id\">" . entites_html($alt) . "</title>\n";
3828
-		$balise_svg .= $title;
3829
-	}
3830
-	else {
3831
-		$balise_svg = inserer_attribut($balise_svg, 'aria-hidden', 'true');
3832
-	}
3833
-
3834
-	$svg = str_replace($balise_svg_source, $balise_svg, $svg);
3835
-
3836
-	if (!is_null($size) and strlen($size = trim($size))) {
3837
-		[$width, $height] = helper_filtre_balise_img_svg_size($svg, $size);
3838
-
3839
-		if (!function_exists('svg_redimensionner')) {
3840
-			include_spip('inc/svg');
3841
-		}
3842
-		$svg = svg_redimensionner($svg, $width, $height);
3843
-	}
3844
-
3845
-	return $svg;
3772
+    $svg = null;
3773
+    $img = trim($img);
3774
+    $img_file = $img;
3775
+    if (strpos($img, '<svg') === false) {
3776
+        if ($p = strpos($img_file, '?')) {
3777
+            $img_file = substr($img_file, 0, $p);
3778
+        }
3779
+
3780
+        // ne jamais operer directement sur une image distante pour des raisons de perfo
3781
+        // la copie locale a toutes les chances d'etre la ou de resservir
3782
+        if (tester_url_absolue($img_file)) {
3783
+            include_spip('inc/distant');
3784
+            $fichier = copie_locale($img_file);
3785
+            $img_file = ($fichier ? _DIR_RACINE . $fichier : $img_file);
3786
+        }
3787
+
3788
+        if (
3789
+            !$img_file
3790
+            or !file_exists($img_file)
3791
+            or !$svg = file_get_contents($img_file)
3792
+        ) {
3793
+            return '';
3794
+        }
3795
+    }
3796
+
3797
+    if (!preg_match(",<svg\b[^>]*>,UimsS", $svg, $match)) {
3798
+        return '';
3799
+    }
3800
+
3801
+    [$alt, $class, $size] = helper_filtre_balise_img_svg_arguments($alt, $class, $size);
3802
+
3803
+    $balise_svg = $match[0];
3804
+    $balise_svg_source = $balise_svg;
3805
+
3806
+    // entete XML à supprimer
3807
+    $svg = preg_replace(',^\s*<\?xml[^>]*\?' . '>,', '', $svg);
3808
+
3809
+    // IE est toujours mon ami
3810
+    $balise_svg = inserer_attribut($balise_svg, 'focusable', 'false');
3811
+
3812
+    // regler la classe
3813
+    if (!is_null($class)) {
3814
+        if (strlen($class)) {
3815
+            $balise_svg = inserer_attribut($balise_svg, 'class', $class);
3816
+        }
3817
+        else {
3818
+            $balise_svg = vider_attribut($balise_svg, 'class');
3819
+        }
3820
+    }
3821
+
3822
+    // regler le alt
3823
+    if ($alt) {
3824
+        $balise_svg = inserer_attribut($balise_svg, 'role', 'img');
3825
+        $id = 'img-svg-title-' . substr(md5("$img_file:$svg:$alt"), 0, 4);
3826
+        $balise_svg = inserer_attribut($balise_svg, 'aria-labelledby', $id);
3827
+        $title = "<title id=\"$id\">" . entites_html($alt) . "</title>\n";
3828
+        $balise_svg .= $title;
3829
+    }
3830
+    else {
3831
+        $balise_svg = inserer_attribut($balise_svg, 'aria-hidden', 'true');
3832
+    }
3833
+
3834
+    $svg = str_replace($balise_svg_source, $balise_svg, $svg);
3835
+
3836
+    if (!is_null($size) and strlen($size = trim($size))) {
3837
+        [$width, $height] = helper_filtre_balise_img_svg_size($svg, $size);
3838
+
3839
+        if (!function_exists('svg_redimensionner')) {
3840
+            include_spip('inc/svg');
3841
+        }
3842
+        $svg = svg_redimensionner($svg, $width, $height);
3843
+    }
3844
+
3845
+    return $svg;
3846 3846
 }
3847 3847
 
3848 3848
 
@@ -3868,18 +3868,18 @@  discard block
 block discarded – undo
3868 3868
  *     Code HTML résultant
3869 3869
  **/
3870 3870
 function filtre_foreach_dist($tableau, $modele = 'foreach') {
3871
-	$texte = '';
3872
-	if (is_array($tableau)) {
3873
-		foreach ($tableau as $k => $v) {
3874
-			$res = recuperer_fond(
3875
-				'modeles/' . $modele,
3876
-				array_merge(['cle' => $k], (is_array($v) ? $v : ['valeur' => $v]))
3877
-			);
3878
-			$texte .= $res;
3879
-		}
3880
-	}
3871
+    $texte = '';
3872
+    if (is_array($tableau)) {
3873
+        foreach ($tableau as $k => $v) {
3874
+            $res = recuperer_fond(
3875
+                'modeles/' . $modele,
3876
+                array_merge(['cle' => $k], (is_array($v) ? $v : ['valeur' => $v]))
3877
+            );
3878
+            $texte .= $res;
3879
+        }
3880
+    }
3881 3881
 
3882
-	return $texte;
3882
+    return $texte;
3883 3883
 }
3884 3884
 
3885 3885
 
@@ -3904,37 +3904,37 @@  discard block
 block discarded – undo
3904 3904
  *         - tout : retourne toutes les informations du plugin actif
3905 3905
  **/
3906 3906
 function filtre_info_plugin_dist($plugin, $type_info, $reload = false) {
3907
-	include_spip('inc/plugin');
3908
-	$plugin = strtoupper($plugin);
3909
-	$plugins_actifs = liste_plugin_actifs();
3910
-
3911
-	if (!$plugin) {
3912
-		return serialize(array_keys($plugins_actifs));
3913
-	} elseif (empty($plugins_actifs[$plugin]) and !$reload) {
3914
-		return '';
3915
-	} elseif (($type_info == 'est_actif') and !$reload) {
3916
-		return $plugins_actifs[$plugin] ? 1 : 0;
3917
-	} elseif (isset($plugins_actifs[$plugin][$type_info]) and !$reload) {
3918
-		return $plugins_actifs[$plugin][$type_info];
3919
-	} else {
3920
-		$get_infos = charger_fonction('get_infos', 'plugins');
3921
-		// On prend en compte les extensions
3922
-		if (!is_dir($plugins_actifs[$plugin]['dir_type'])) {
3923
-			$dir_plugins = constant($plugins_actifs[$plugin]['dir_type']);
3924
-		} else {
3925
-			$dir_plugins = $plugins_actifs[$plugin]['dir_type'];
3926
-		}
3927
-		if (!$infos = $get_infos($plugins_actifs[$plugin]['dir'], $reload, $dir_plugins)) {
3928
-			return '';
3929
-		}
3930
-		if ($type_info == 'tout') {
3931
-			return $infos;
3932
-		} elseif ($type_info == 'est_actif') {
3933
-			return $infos ? 1 : 0;
3934
-		} else {
3935
-			return strval($infos[$type_info]);
3936
-		}
3937
-	}
3907
+    include_spip('inc/plugin');
3908
+    $plugin = strtoupper($plugin);
3909
+    $plugins_actifs = liste_plugin_actifs();
3910
+
3911
+    if (!$plugin) {
3912
+        return serialize(array_keys($plugins_actifs));
3913
+    } elseif (empty($plugins_actifs[$plugin]) and !$reload) {
3914
+        return '';
3915
+    } elseif (($type_info == 'est_actif') and !$reload) {
3916
+        return $plugins_actifs[$plugin] ? 1 : 0;
3917
+    } elseif (isset($plugins_actifs[$plugin][$type_info]) and !$reload) {
3918
+        return $plugins_actifs[$plugin][$type_info];
3919
+    } else {
3920
+        $get_infos = charger_fonction('get_infos', 'plugins');
3921
+        // On prend en compte les extensions
3922
+        if (!is_dir($plugins_actifs[$plugin]['dir_type'])) {
3923
+            $dir_plugins = constant($plugins_actifs[$plugin]['dir_type']);
3924
+        } else {
3925
+            $dir_plugins = $plugins_actifs[$plugin]['dir_type'];
3926
+        }
3927
+        if (!$infos = $get_infos($plugins_actifs[$plugin]['dir'], $reload, $dir_plugins)) {
3928
+            return '';
3929
+        }
3930
+        if ($type_info == 'tout') {
3931
+            return $infos;
3932
+        } elseif ($type_info == 'est_actif') {
3933
+            return $infos ? 1 : 0;
3934
+        } else {
3935
+            return strval($infos[$type_info]);
3936
+        }
3937
+    }
3938 3938
 }
3939 3939
 
3940 3940
 
@@ -3961,9 +3961,9 @@  discard block
 block discarded – undo
3961 3961
  *     Code HTML de l'image de puce de statut à insérer (et du menu de changement si présent)
3962 3962
  */
3963 3963
 function puce_changement_statut($id_objet, $statut, $id_rubrique, $type, $ajax = false) {
3964
-	$puce_statut = charger_fonction('puce_statut', 'inc');
3964
+    $puce_statut = charger_fonction('puce_statut', 'inc');
3965 3965
 
3966
-	return $puce_statut($id_objet, $statut, $id_rubrique, $type, $ajax);
3966
+    return $puce_statut($id_objet, $statut, $id_rubrique, $type, $ajax);
3967 3967
 }
3968 3968
 
3969 3969
 
@@ -3993,19 +3993,19 @@  discard block
 block discarded – undo
3993 3993
  *     Code HTML de l'image de puce de statut à insérer (et du menu de changement si présent)
3994 3994
  */
3995 3995
 function filtre_puce_statut_dist($statut, $objet, $id_objet = 0, $id_parent = 0) {
3996
-	static $puce_statut = null;
3997
-	if (!$puce_statut) {
3998
-		$puce_statut = charger_fonction('puce_statut', 'inc');
3999
-	}
3996
+    static $puce_statut = null;
3997
+    if (!$puce_statut) {
3998
+        $puce_statut = charger_fonction('puce_statut', 'inc');
3999
+    }
4000 4000
 
4001
-	return $puce_statut(
4002
-		$id_objet,
4003
-		$statut,
4004
-		$id_parent,
4005
-		$objet,
4006
-		false,
4007
-		objet_info($objet, 'editable') ? _ACTIVER_PUCE_RAPIDE : false
4008
-	);
4001
+    return $puce_statut(
4002
+        $id_objet,
4003
+        $statut,
4004
+        $id_parent,
4005
+        $objet,
4006
+        false,
4007
+        objet_info($objet, 'editable') ? _ACTIVER_PUCE_RAPIDE : false
4008
+    );
4009 4009
 }
4010 4010
 
4011 4011
 
@@ -4032,98 +4032,98 @@  discard block
 block discarded – undo
4032 4032
  *   hash du contexte
4033 4033
  */
4034 4034
 function encoder_contexte_ajax($c, $form = '', $emboite = null, $ajaxid = '') {
4035
-	$env = null;
4036
-	if (
4037
-		is_string($c)
4038
-		and @unserialize($c) !== false
4039
-	) {
4040
-		$c = unserialize($c);
4041
-	}
4042
-
4043
-	// supprimer les parametres debut_x
4044
-	// pour que la pagination ajax ne soit pas plantee
4045
-	// si on charge la page &debut_x=1 : car alors en cliquant sur l'item 0,
4046
-	// le debut_x=0 n'existe pas, et on resterait sur 1
4047
-	if (is_array($c)) {
4048
-		foreach ($c as $k => $v) {
4049
-			if (strpos($k, 'debut_') === 0) {
4050
-				unset($c[$k]);
4051
-			}
4052
-		}
4053
-	}
4054
-
4055
-	if (!function_exists('calculer_cle_action')) {
4056
-		include_spip('inc/securiser_action');
4057
-	}
4058
-
4059
-	$c = serialize($c);
4060
-	$cle = calculer_cle_action($form . $c);
4061
-	$c = "$cle:$c";
4062
-
4063
-	// on ne stocke pas les contextes dans des fichiers en cache
4064
-	// par defaut, sauf si cette configuration a été forcée
4065
-	// OU que la longueur de l’argument géneré est plus long
4066
-	// que ce qui est toléré.
4067
-	$cache_contextes_ajax = (defined('_CACHE_CONTEXTES_AJAX') and _CACHE_CONTEXTES_AJAX);
4068
-	if (!$cache_contextes_ajax) {
4069
-		$env = $c;
4070
-		if (function_exists('gzdeflate') && function_exists('gzinflate')) {
4071
-			$env = gzdeflate($env);
4072
-		}
4073
-		$env = _xor($env);
4074
-		$env = base64_encode($env);
4075
-		$len = strlen($env);
4076
-		// Si l’url est trop longue pour le navigateur
4077
-		$max_len = _CACHE_CONTEXTES_AJAX_SUR_LONGUEUR;
4078
-		if ($len > $max_len) {
4079
-			$cache_contextes_ajax = true;
4080
-			spip_log(
4081
-				'Contextes AJAX forces en fichiers !'
4082
-				. ' Cela arrive lorsque la valeur du contexte'
4083
-				. " depasse la longueur maximale autorisee ($max_len). Ici : $len.",
4084
-				_LOG_AVERTISSEMENT
4085
-			);
4086
-		}
4087
-		// Sinon si Suhosin est actif et a une la valeur maximale des variables en GET...
4088
-		elseif (
4089
-			$max_len = @ini_get('suhosin.get.max_value_length')
4090
-			and $max_len < $len
4091
-		) {
4092
-			$cache_contextes_ajax = true;
4093
-			spip_log('Contextes AJAX forces en fichiers !'
4094
-				. ' Cela arrive lorsque la valeur du contexte'
4095
-				. ' depasse la longueur maximale autorisee par Suhosin'
4096
-				. " ($max_len) dans 'suhosin.get.max_value_length'. Ici : $len."
4097
-				. ' Vous devriez modifier les parametres de Suhosin'
4098
-				. ' pour accepter au moins 1024 caracteres.', _LOG_AVERTISSEMENT);
4099
-		}
4100
-	}
4101
-
4102
-	if ($cache_contextes_ajax) {
4103
-		$dir = sous_repertoire(_DIR_CACHE, 'contextes');
4104
-		// stocker les contextes sur disque et ne passer qu'un hash dans l'url
4105
-		$md5 = md5($c);
4106
-		ecrire_fichier("$dir/c$md5", $c);
4107
-		$env = $md5;
4108
-	}
4109
-
4110
-	if ($emboite === null) {
4111
-		return $env;
4112
-	}
4113
-	if (!trim($emboite)) {
4114
-		return '';
4115
-	}
4116
-	// toujours encoder l'url source dans le bloc ajax
4117
-	$r = self();
4118
-	$r = ' data-origin="' . $r . '"';
4119
-	$class = 'ajaxbloc';
4120
-	if ($ajaxid and is_string($ajaxid)) {
4121
-		// ajaxid est normalement conforme a un nom de classe css
4122
-		// on ne verifie pas la conformite, mais on passe entites_html par dessus par precaution
4123
-		$class .= ' ajax-id-' . entites_html($ajaxid);
4124
-	}
4125
-
4126
-	return "<div class='$class' " . "data-ajax-env='$env'$r>\n$emboite</div><!--ajaxbloc-->\n";
4035
+    $env = null;
4036
+    if (
4037
+        is_string($c)
4038
+        and @unserialize($c) !== false
4039
+    ) {
4040
+        $c = unserialize($c);
4041
+    }
4042
+
4043
+    // supprimer les parametres debut_x
4044
+    // pour que la pagination ajax ne soit pas plantee
4045
+    // si on charge la page &debut_x=1 : car alors en cliquant sur l'item 0,
4046
+    // le debut_x=0 n'existe pas, et on resterait sur 1
4047
+    if (is_array($c)) {
4048
+        foreach ($c as $k => $v) {
4049
+            if (strpos($k, 'debut_') === 0) {
4050
+                unset($c[$k]);
4051
+            }
4052
+        }
4053
+    }
4054
+
4055
+    if (!function_exists('calculer_cle_action')) {
4056
+        include_spip('inc/securiser_action');
4057
+    }
4058
+
4059
+    $c = serialize($c);
4060
+    $cle = calculer_cle_action($form . $c);
4061
+    $c = "$cle:$c";
4062
+
4063
+    // on ne stocke pas les contextes dans des fichiers en cache
4064
+    // par defaut, sauf si cette configuration a été forcée
4065
+    // OU que la longueur de l’argument géneré est plus long
4066
+    // que ce qui est toléré.
4067
+    $cache_contextes_ajax = (defined('_CACHE_CONTEXTES_AJAX') and _CACHE_CONTEXTES_AJAX);
4068
+    if (!$cache_contextes_ajax) {
4069
+        $env = $c;
4070
+        if (function_exists('gzdeflate') && function_exists('gzinflate')) {
4071
+            $env = gzdeflate($env);
4072
+        }
4073
+        $env = _xor($env);
4074
+        $env = base64_encode($env);
4075
+        $len = strlen($env);
4076
+        // Si l’url est trop longue pour le navigateur
4077
+        $max_len = _CACHE_CONTEXTES_AJAX_SUR_LONGUEUR;
4078
+        if ($len > $max_len) {
4079
+            $cache_contextes_ajax = true;
4080
+            spip_log(
4081
+                'Contextes AJAX forces en fichiers !'
4082
+                . ' Cela arrive lorsque la valeur du contexte'
4083
+                . " depasse la longueur maximale autorisee ($max_len). Ici : $len.",
4084
+                _LOG_AVERTISSEMENT
4085
+            );
4086
+        }
4087
+        // Sinon si Suhosin est actif et a une la valeur maximale des variables en GET...
4088
+        elseif (
4089
+            $max_len = @ini_get('suhosin.get.max_value_length')
4090
+            and $max_len < $len
4091
+        ) {
4092
+            $cache_contextes_ajax = true;
4093
+            spip_log('Contextes AJAX forces en fichiers !'
4094
+                . ' Cela arrive lorsque la valeur du contexte'
4095
+                . ' depasse la longueur maximale autorisee par Suhosin'
4096
+                . " ($max_len) dans 'suhosin.get.max_value_length'. Ici : $len."
4097
+                . ' Vous devriez modifier les parametres de Suhosin'
4098
+                . ' pour accepter au moins 1024 caracteres.', _LOG_AVERTISSEMENT);
4099
+        }
4100
+    }
4101
+
4102
+    if ($cache_contextes_ajax) {
4103
+        $dir = sous_repertoire(_DIR_CACHE, 'contextes');
4104
+        // stocker les contextes sur disque et ne passer qu'un hash dans l'url
4105
+        $md5 = md5($c);
4106
+        ecrire_fichier("$dir/c$md5", $c);
4107
+        $env = $md5;
4108
+    }
4109
+
4110
+    if ($emboite === null) {
4111
+        return $env;
4112
+    }
4113
+    if (!trim($emboite)) {
4114
+        return '';
4115
+    }
4116
+    // toujours encoder l'url source dans le bloc ajax
4117
+    $r = self();
4118
+    $r = ' data-origin="' . $r . '"';
4119
+    $class = 'ajaxbloc';
4120
+    if ($ajaxid and is_string($ajaxid)) {
4121
+        // ajaxid est normalement conforme a un nom de classe css
4122
+        // on ne verifie pas la conformite, mais on passe entites_html par dessus par precaution
4123
+        $class .= ' ajax-id-' . entites_html($ajaxid);
4124
+    }
4125
+
4126
+    return "<div class='$class' " . "data-ajax-env='$env'$r>\n$emboite</div><!--ajaxbloc-->\n";
4127 4127
 }
4128 4128
 
4129 4129
 /**
@@ -4143,37 +4143,37 @@  discard block
 block discarded – undo
4143 4143
  *   - false : erreur de décodage
4144 4144
  */
4145 4145
 function decoder_contexte_ajax($c, $form = '') {
4146
-	if (!function_exists('calculer_cle_action')) {
4147
-		include_spip('inc/securiser_action');
4148
-	}
4149
-	if (
4150
-		((defined('_CACHE_CONTEXTES_AJAX') and _CACHE_CONTEXTES_AJAX) or strlen($c) == 32)
4151
-		and $dir = sous_repertoire(_DIR_CACHE, 'contextes')
4152
-		and lire_fichier("$dir/c$c", $contexte)
4153
-	) {
4154
-		$c = $contexte;
4155
-	} else {
4156
-		$c = @base64_decode($c);
4157
-		$c = _xor($c);
4158
-		if (function_exists('gzdeflate') && function_exists('gzinflate')) {
4159
-			$c = @gzinflate($c);
4160
-		}
4161
-	}
4162
-
4163
-	// extraire la signature en debut de contexte
4164
-	// et la verifier avant de deserializer
4165
-	// format : signature:donneesserializees
4166
-	if ($p = strpos($c, ':')) {
4167
-		$cle = substr($c, 0, $p);
4168
-		$c = substr($c, $p + 1);
4169
-
4170
-		if ($cle == calculer_cle_action($form . $c)) {
4171
-			$env = @unserialize($c);
4172
-			return $env;
4173
-		}
4174
-	}
4175
-
4176
-	return false;
4146
+    if (!function_exists('calculer_cle_action')) {
4147
+        include_spip('inc/securiser_action');
4148
+    }
4149
+    if (
4150
+        ((defined('_CACHE_CONTEXTES_AJAX') and _CACHE_CONTEXTES_AJAX) or strlen($c) == 32)
4151
+        and $dir = sous_repertoire(_DIR_CACHE, 'contextes')
4152
+        and lire_fichier("$dir/c$c", $contexte)
4153
+    ) {
4154
+        $c = $contexte;
4155
+    } else {
4156
+        $c = @base64_decode($c);
4157
+        $c = _xor($c);
4158
+        if (function_exists('gzdeflate') && function_exists('gzinflate')) {
4159
+            $c = @gzinflate($c);
4160
+        }
4161
+    }
4162
+
4163
+    // extraire la signature en debut de contexte
4164
+    // et la verifier avant de deserializer
4165
+    // format : signature:donneesserializees
4166
+    if ($p = strpos($c, ':')) {
4167
+        $cle = substr($c, 0, $p);
4168
+        $c = substr($c, $p + 1);
4169
+
4170
+        if ($cle == calculer_cle_action($form . $c)) {
4171
+            $env = @unserialize($c);
4172
+            return $env;
4173
+        }
4174
+    }
4175
+
4176
+    return false;
4177 4177
 }
4178 4178
 
4179 4179
 
@@ -4191,20 +4191,20 @@  discard block
 block discarded – undo
4191 4191
  *    Message décrypté ou encrypté
4192 4192
  **/
4193 4193
 function _xor($message, $key = null) {
4194
-	if (is_null($key)) {
4195
-		if (!function_exists('calculer_cle_action')) {
4196
-			include_spip('inc/securiser_action');
4197
-		}
4198
-		$key = pack('H*', calculer_cle_action('_xor'));
4199
-	}
4194
+    if (is_null($key)) {
4195
+        if (!function_exists('calculer_cle_action')) {
4196
+            include_spip('inc/securiser_action');
4197
+        }
4198
+        $key = pack('H*', calculer_cle_action('_xor'));
4199
+    }
4200 4200
 
4201
-	$keylen = strlen($key);
4202
-	$messagelen = strlen($message);
4203
-	for ($i = 0; $i < $messagelen; $i++) {
4204
-		$message[$i] = ~($message[$i] ^ $key[$i % $keylen]);
4205
-	}
4201
+    $keylen = strlen($key);
4202
+    $messagelen = strlen($message);
4203
+    for ($i = 0; $i < $messagelen; $i++) {
4204
+        $message[$i] = ~($message[$i] ^ $key[$i % $keylen]);
4205
+    }
4206 4206
 
4207
-	return $message;
4207
+    return $message;
4208 4208
 }
4209 4209
 
4210 4210
 /**
@@ -4218,7 +4218,7 @@  discard block
 block discarded – undo
4218 4218
  * @return string
4219 4219
  */
4220 4220
 function url_reponse_forum($texte) {
4221
- return $texte;
4221
+    return $texte;
4222 4222
 }
4223 4223
 
4224 4224
 /**
@@ -4232,7 +4232,7 @@  discard block
 block discarded – undo
4232 4232
  * @return string
4233 4233
  */
4234 4234
 function url_rss_forum($texte) {
4235
- return $texte;
4235
+    return $texte;
4236 4236
 }
4237 4237
 
4238 4238
 
@@ -4271,37 +4271,37 @@  discard block
 block discarded – undo
4271 4271
  *   Code HTML
4272 4272
  */
4273 4273
 function lien_ou_expose($url, $libelle = null, $on = false, $class = '', $title = '', $rel = '', $evt = '') {
4274
-	if ($on) {
4275
-		$bal = 'strong';
4276
-		$class = '';
4277
-		$att = '';
4278
-		// si $on passe la balise et optionnelement une ou ++classe
4279
-		// a.active span.selected.active etc....
4280
-		if (is_string($on) and (strncmp($on, 'a', 1) == 0 or strncmp($on, 'span', 4) == 0 or strncmp($on, 'strong', 6) == 0)) {
4281
-			$on = explode('.', $on);
4282
-			// on verifie que c'est exactement une des 3 balises a, span ou strong
4283
-			if (in_array(reset($on), ['a', 'span', 'strong'])) {
4284
-				$bal = array_shift($on);
4285
-				$class = implode(' ', $on);
4286
-				if ($bal == 'a') {
4287
-					$att = 'href="#" ';
4288
-				}
4289
-			}
4290
-		}
4291
-		$att .= 'class="' . ($class ? attribut_html($class) . ' ' : '') . (defined('_LIEN_OU_EXPOSE_CLASS_ON') ? _LIEN_OU_EXPOSE_CLASS_ON : 'on') . '"';
4292
-	} else {
4293
-		$bal = 'a';
4294
-		$att = "href='$url'"
4295
-			. ($title ? " title='" . attribut_html($title) . "'" : '')
4296
-			. ($class ? " class='" . attribut_html($class) . "'" : '')
4297
-			. ($rel ? " rel='" . attribut_html($rel) . "'" : '')
4298
-			. $evt;
4299
-	}
4300
-	if ($libelle === null) {
4301
-		$libelle = $url;
4302
-	}
4303
-
4304
-	return "<$bal $att>$libelle</$bal>";
4274
+    if ($on) {
4275
+        $bal = 'strong';
4276
+        $class = '';
4277
+        $att = '';
4278
+        // si $on passe la balise et optionnelement une ou ++classe
4279
+        // a.active span.selected.active etc....
4280
+        if (is_string($on) and (strncmp($on, 'a', 1) == 0 or strncmp($on, 'span', 4) == 0 or strncmp($on, 'strong', 6) == 0)) {
4281
+            $on = explode('.', $on);
4282
+            // on verifie que c'est exactement une des 3 balises a, span ou strong
4283
+            if (in_array(reset($on), ['a', 'span', 'strong'])) {
4284
+                $bal = array_shift($on);
4285
+                $class = implode(' ', $on);
4286
+                if ($bal == 'a') {
4287
+                    $att = 'href="#" ';
4288
+                }
4289
+            }
4290
+        }
4291
+        $att .= 'class="' . ($class ? attribut_html($class) . ' ' : '') . (defined('_LIEN_OU_EXPOSE_CLASS_ON') ? _LIEN_OU_EXPOSE_CLASS_ON : 'on') . '"';
4292
+    } else {
4293
+        $bal = 'a';
4294
+        $att = "href='$url'"
4295
+            . ($title ? " title='" . attribut_html($title) . "'" : '')
4296
+            . ($class ? " class='" . attribut_html($class) . "'" : '')
4297
+            . ($rel ? " rel='" . attribut_html($rel) . "'" : '')
4298
+            . $evt;
4299
+    }
4300
+    if ($libelle === null) {
4301
+        $libelle = $url;
4302
+    }
4303
+
4304
+    return "<$bal $att>$libelle</$bal>";
4305 4305
 }
4306 4306
 
4307 4307
 
@@ -4318,39 +4318,39 @@  discard block
 block discarded – undo
4318 4318
  * @return string : la chaine de langue finale en utilisant la fonction _T()
4319 4319
  */
4320 4320
 function singulier_ou_pluriel($nb, $chaine_un, $chaine_plusieurs, $var = 'nb', $vars = []) {
4321
-	static $local_singulier_ou_pluriel = [];
4322
-
4323
-	// si nb=0 ou pas de $vars valide on retourne une chaine vide, a traiter par un |sinon
4324
-	if (!is_numeric($nb) or $nb == 0) {
4325
-		return '';
4326
-	}
4327
-	if (!is_array($vars)) {
4328
-		return '';
4329
-	}
4330
-
4331
-	$langue = $GLOBALS['spip_lang'];
4332
-	if (!isset($local_singulier_ou_pluriel[$langue])) {
4333
-		$local_singulier_ou_pluriel[$langue] = false;
4334
-		if (
4335
-			$f = charger_fonction("singulier_ou_pluriel_${langue}", 'inc', true)
4336
-			or $f = charger_fonction('singulier_ou_pluriel', 'inc', true)
4337
-		) {
4338
-			$local_singulier_ou_pluriel[$langue] = $f;
4339
-		}
4340
-	}
4341
-
4342
-	// si on a une surcharge on l'utilise
4343
-	if ($local_singulier_ou_pluriel[$langue]) {
4344
-		return ($local_singulier_ou_pluriel[$langue])($nb, $chaine_un, $chaine_plusieurs, $var, $vars);
4345
-	}
4346
-
4347
-	// sinon traitement par defaut
4348
-	$vars[$var] = $nb;
4349
-	if ($nb >= 2) {
4350
-		return _T($chaine_plusieurs, $vars);
4351
-	} else {
4352
-		return _T($chaine_un, $vars);
4353
-	}
4321
+    static $local_singulier_ou_pluriel = [];
4322
+
4323
+    // si nb=0 ou pas de $vars valide on retourne une chaine vide, a traiter par un |sinon
4324
+    if (!is_numeric($nb) or $nb == 0) {
4325
+        return '';
4326
+    }
4327
+    if (!is_array($vars)) {
4328
+        return '';
4329
+    }
4330
+
4331
+    $langue = $GLOBALS['spip_lang'];
4332
+    if (!isset($local_singulier_ou_pluriel[$langue])) {
4333
+        $local_singulier_ou_pluriel[$langue] = false;
4334
+        if (
4335
+            $f = charger_fonction("singulier_ou_pluriel_${langue}", 'inc', true)
4336
+            or $f = charger_fonction('singulier_ou_pluriel', 'inc', true)
4337
+        ) {
4338
+            $local_singulier_ou_pluriel[$langue] = $f;
4339
+        }
4340
+    }
4341
+
4342
+    // si on a une surcharge on l'utilise
4343
+    if ($local_singulier_ou_pluriel[$langue]) {
4344
+        return ($local_singulier_ou_pluriel[$langue])($nb, $chaine_un, $chaine_plusieurs, $var, $vars);
4345
+    }
4346
+
4347
+    // sinon traitement par defaut
4348
+    $vars[$var] = $nb;
4349
+    if ($nb >= 2) {
4350
+        return _T($chaine_plusieurs, $vars);
4351
+    } else {
4352
+        return _T($chaine_un, $vars);
4353
+    }
4354 4354
 }
4355 4355
 
4356 4356
 
@@ -4378,73 +4378,73 @@  discard block
 block discarded – undo
4378 4378
  */
4379 4379
 function prepare_icone_base($type, $lien, $texte, $fond, $fonction = '', $class = '', $javascript = '') {
4380 4380
 
4381
-	$class_lien = $class_bouton = $class;
4382
-
4383
-	// Normaliser la fonction et compléter la classe en fonction
4384
-	if (in_array($fonction, ['del', 'supprimer.gif'])) {
4385
-		$class_lien .= ' danger';
4386
-		$class_bouton .= ' btn_danger';
4387
-	} elseif ($fonction == 'rien.gif') {
4388
-		$fonction = '';
4389
-	} elseif ($fonction == 'delsafe') {
4390
-		$fonction = 'del';
4391
-	}
4392
-
4393
-	$fond_origine = $fond;
4394
-	// Remappage des icone : article-24.png+new => article-new-24.png
4395
-	if ($icone_renommer = charger_fonction('icone_renommer', 'inc', true)) {
4396
-		[$fond, $fonction] = $icone_renommer($fond, $fonction);
4397
-	}
4398
-
4399
-	// Ajouter le type d'objet dans la classe
4400
-	$objet_type = substr(basename($fond), 0, -4);
4401
-	$class_lien .= " $objet_type";
4402
-	$class_bouton .= " $objet_type";
4403
-
4404
-	// Texte
4405
-	$alt = attribut_html($texte);
4406
-	$title = " title=\"$alt\""; // est-ce pertinent de doubler le alt par un title ?
4407
-
4408
-	// Liens : préparer les classes ajax
4409
-	$ajax = '';
4410
-	if ($type === 'lien') {
4411
-		if (strpos($class_lien, 'ajax') !== false) {
4412
-			$ajax = 'ajax';
4413
-			if (strpos($class_lien, 'preload') !== false) {
4414
-				$ajax .= ' preload';
4415
-			}
4416
-			if (strpos($class_lien, 'nocache') !== false) {
4417
-				$ajax .= ' nocache';
4418
-			}
4419
-			$ajax = " class='$ajax'";
4420
-		}
4421
-	}
4422
-
4423
-	// Repérer la taille et l'ajouter dans la classe
4424
-	$size = 24;
4425
-	if (
4426
-		preg_match('/-([0-9]{1,3})[.](gif|png|svg)$/i', $fond, $match)
4427
-		or preg_match('/-([0-9]{1,3})([.](gif|png|svg))?$/i', $fond_origine, $match)
4428
-	) {
4429
-		$size = $match[1];
4430
-	}
4431
-	$class_lien .= " s$size";
4432
-	$class_bouton .= " s$size";
4433
-
4434
-	// Icône
4435
-	$icone = http_img_pack($fond, $alt, "width='$size' height='$size'", '', ['alternative' => "objet-generique-$size.png"]);
4436
-	$icone = '<span class="icone-image' . ($fonction ? " icone-fonction icone-fonction-$fonction" : '') . "\">$icone</span>";
4437
-
4438
-	// Markup final
4439
-	if ($type == 'lien') {
4440
-		return "<span class='icone $class_lien'>"
4441
-		. "<a href='$lien'$title$ajax$javascript>"
4442
-		. $icone
4443
-		. "<b>$texte</b>"
4444
-		. "</a></span>\n";
4445
-	} else {
4446
-		return bouton_action("$icone $texte", $lien, $class_bouton, $javascript, $alt);
4447
-	}
4381
+    $class_lien = $class_bouton = $class;
4382
+
4383
+    // Normaliser la fonction et compléter la classe en fonction
4384
+    if (in_array($fonction, ['del', 'supprimer.gif'])) {
4385
+        $class_lien .= ' danger';
4386
+        $class_bouton .= ' btn_danger';
4387
+    } elseif ($fonction == 'rien.gif') {
4388
+        $fonction = '';
4389
+    } elseif ($fonction == 'delsafe') {
4390
+        $fonction = 'del';
4391
+    }
4392
+
4393
+    $fond_origine = $fond;
4394
+    // Remappage des icone : article-24.png+new => article-new-24.png
4395
+    if ($icone_renommer = charger_fonction('icone_renommer', 'inc', true)) {
4396
+        [$fond, $fonction] = $icone_renommer($fond, $fonction);
4397
+    }
4398
+
4399
+    // Ajouter le type d'objet dans la classe
4400
+    $objet_type = substr(basename($fond), 0, -4);
4401
+    $class_lien .= " $objet_type";
4402
+    $class_bouton .= " $objet_type";
4403
+
4404
+    // Texte
4405
+    $alt = attribut_html($texte);
4406
+    $title = " title=\"$alt\""; // est-ce pertinent de doubler le alt par un title ?
4407
+
4408
+    // Liens : préparer les classes ajax
4409
+    $ajax = '';
4410
+    if ($type === 'lien') {
4411
+        if (strpos($class_lien, 'ajax') !== false) {
4412
+            $ajax = 'ajax';
4413
+            if (strpos($class_lien, 'preload') !== false) {
4414
+                $ajax .= ' preload';
4415
+            }
4416
+            if (strpos($class_lien, 'nocache') !== false) {
4417
+                $ajax .= ' nocache';
4418
+            }
4419
+            $ajax = " class='$ajax'";
4420
+        }
4421
+    }
4422
+
4423
+    // Repérer la taille et l'ajouter dans la classe
4424
+    $size = 24;
4425
+    if (
4426
+        preg_match('/-([0-9]{1,3})[.](gif|png|svg)$/i', $fond, $match)
4427
+        or preg_match('/-([0-9]{1,3})([.](gif|png|svg))?$/i', $fond_origine, $match)
4428
+    ) {
4429
+        $size = $match[1];
4430
+    }
4431
+    $class_lien .= " s$size";
4432
+    $class_bouton .= " s$size";
4433
+
4434
+    // Icône
4435
+    $icone = http_img_pack($fond, $alt, "width='$size' height='$size'", '', ['alternative' => "objet-generique-$size.png"]);
4436
+    $icone = '<span class="icone-image' . ($fonction ? " icone-fonction icone-fonction-$fonction" : '') . "\">$icone</span>";
4437
+
4438
+    // Markup final
4439
+    if ($type == 'lien') {
4440
+        return "<span class='icone $class_lien'>"
4441
+        . "<a href='$lien'$title$ajax$javascript>"
4442
+        . $icone
4443
+        . "<b>$texte</b>"
4444
+        . "</a></span>\n";
4445
+    } else {
4446
+        return bouton_action("$icone $texte", $lien, $class_bouton, $javascript, $alt);
4447
+    }
4448 4448
 }
4449 4449
 
4450 4450
 /**
@@ -4468,7 +4468,7 @@  discard block
 block discarded – undo
4468 4468
  *     Code HTML du lien
4469 4469
  **/
4470 4470
 function icone_base($lien, $texte, $fond, $fonction = '', $class = '', $javascript = '') {
4471
-	return prepare_icone_base('lien', $lien, $texte, $fond, $fonction, $class, $javascript);
4471
+    return prepare_icone_base('lien', $lien, $texte, $fond, $fonction, $class, $javascript);
4472 4472
 }
4473 4473
 
4474 4474
 /**
@@ -4503,7 +4503,7 @@  discard block
 block discarded – undo
4503 4503
  *     Code HTML du lien
4504 4504
  **/
4505 4505
 function filtre_icone_verticale_dist($lien, $texte, $fond, $fonction = '', $class = '', $javascript = '') {
4506
-	return icone_base($lien, $texte, $fond, $fonction, "verticale $class", $javascript);
4506
+    return icone_base($lien, $texte, $fond, $fonction, "verticale $class", $javascript);
4507 4507
 }
4508 4508
 
4509 4509
 /**
@@ -4548,7 +4548,7 @@  discard block
 block discarded – undo
4548 4548
  *     Code HTML du lien
4549 4549
  **/
4550 4550
 function filtre_icone_horizontale_dist($lien, $texte, $fond, $fonction = '', $class = '', $javascript = '') {
4551
-	return icone_base($lien, $texte, $fond, $fonction, "horizontale $class", $javascript);
4551
+    return icone_base($lien, $texte, $fond, $fonction, "horizontale $class", $javascript);
4552 4552
 }
4553 4553
 
4554 4554
 /**
@@ -4579,7 +4579,7 @@  discard block
 block discarded – undo
4579 4579
  *     Code HTML du lien
4580 4580
  **/
4581 4581
 function filtre_bouton_action_horizontal_dist($lien, $texte, $fond, $fonction = '', $class = '', $confirm = '') {
4582
-	return prepare_icone_base('bouton', $lien, $texte, $fond, $fonction, $class, $confirm);
4582
+    return prepare_icone_base('bouton', $lien, $texte, $fond, $fonction, $class, $confirm);
4583 4583
 }
4584 4584
 
4585 4585
 /**
@@ -4610,7 +4610,7 @@  discard block
 block discarded – undo
4610 4610
  *     Code HTML du lien
4611 4611
  */
4612 4612
 function filtre_icone_dist($lien, $texte, $fond, $align = '', $fonction = '', $class = '', $javascript = '') {
4613
-	return icone_base($lien, $texte, $fond, $fonction, "verticale $align $class", $javascript);
4613
+    return icone_base($lien, $texte, $fond, $fonction, "verticale $align $class", $javascript);
4614 4614
 }
4615 4615
 
4616 4616
 
@@ -4632,7 +4632,7 @@  discard block
 block discarded – undo
4632 4632
  * @return array Liste des éléments
4633 4633
  */
4634 4634
 function filtre_explode_dist($a, $b) {
4635
-	return explode($b, (string) $a);
4635
+    return explode($b, (string) $a);
4636 4636
 }
4637 4637
 
4638 4638
 /**
@@ -4653,7 +4653,7 @@  discard block
 block discarded – undo
4653 4653
  * @return string Texte
4654 4654
  */
4655 4655
 function filtre_implode_dist($a, $b) {
4656
-	return is_array($a) ? implode($b, $a) : $a;
4656
+    return is_array($a) ? implode($b, $a) : $a;
4657 4657
 }
4658 4658
 
4659 4659
 /**
@@ -4662,22 +4662,22 @@  discard block
 block discarded – undo
4662 4662
  * @return string Code CSS
4663 4663
  */
4664 4664
 function bando_images_background() {
4665
-	include_spip('inc/bandeau');
4666
-	// recuperer tous les boutons et leurs images
4667
-	$boutons = definir_barre_boutons(definir_barre_contexte(), true, false);
4665
+    include_spip('inc/bandeau');
4666
+    // recuperer tous les boutons et leurs images
4667
+    $boutons = definir_barre_boutons(definir_barre_contexte(), true, false);
4668 4668
 
4669
-	$res = '';
4670
-	foreach ($boutons as $page => $detail) {
4671
-		$selecteur = (in_array($page, ['outils_rapides', 'outils_collaboratifs']) ? '' : '.navigation_avec_icones ');
4672
-		foreach ($detail->sousmenu as $souspage => $sousdetail) {
4673
-			if ($sousdetail->icone and strlen(trim($sousdetail->icone))) {
4674
-				$img = http_img_variante_svg_si_possible($sousdetail->icone);
4675
-				$res .= "\n$selecteur.bando2_$souspage {background-image:url($img);}";
4676
-			}
4677
-		}
4678
-	}
4669
+    $res = '';
4670
+    foreach ($boutons as $page => $detail) {
4671
+        $selecteur = (in_array($page, ['outils_rapides', 'outils_collaboratifs']) ? '' : '.navigation_avec_icones ');
4672
+        foreach ($detail->sousmenu as $souspage => $sousdetail) {
4673
+            if ($sousdetail->icone and strlen(trim($sousdetail->icone))) {
4674
+                $img = http_img_variante_svg_si_possible($sousdetail->icone);
4675
+                $res .= "\n$selecteur.bando2_$souspage {background-image:url($img);}";
4676
+            }
4677
+        }
4678
+    }
4679 4679
 
4680
-	return $res;
4680
+    return $res;
4681 4681
 }
4682 4682
 
4683 4683
 /**
@@ -4702,27 +4702,27 @@  discard block
 block discarded – undo
4702 4702
  */
4703 4703
 function bouton_action($libelle, $url, $class = '', $confirm = '', $title = '', $callback = '') {
4704 4704
 
4705
-	// Classes : dispatcher `ajax` sur le formulaire
4706
-	$class_form = '';
4707
-	if (strpos($class, 'ajax') !== false) {
4708
-		$class_form = 'ajax';
4709
-		$class = str_replace('ajax', '', $class);
4710
-	}
4711
-	$class_btn = 'submit ' . trim($class);
4705
+    // Classes : dispatcher `ajax` sur le formulaire
4706
+    $class_form = '';
4707
+    if (strpos($class, 'ajax') !== false) {
4708
+        $class_form = 'ajax';
4709
+        $class = str_replace('ajax', '', $class);
4710
+    }
4711
+    $class_btn = 'submit ' . trim($class);
4712 4712
 
4713
-	if ($confirm) {
4714
-		$confirm = 'confirm("' . attribut_html($confirm) . '")';
4715
-		if ($callback) {
4716
-			$callback = "$confirm?($callback):false";
4717
-		} else {
4718
-			$callback = $confirm;
4719
-		}
4720
-	}
4721
-	$onclick = $callback ? " onclick='return " . addcslashes($callback, "'") . "'" : '';
4722
-	$title = $title ? " title='$title'" : '';
4713
+    if ($confirm) {
4714
+        $confirm = 'confirm("' . attribut_html($confirm) . '")';
4715
+        if ($callback) {
4716
+            $callback = "$confirm?($callback):false";
4717
+        } else {
4718
+            $callback = $confirm;
4719
+        }
4720
+    }
4721
+    $onclick = $callback ? " onclick='return " . addcslashes($callback, "'") . "'" : '';
4722
+    $title = $title ? " title='$title'" : '';
4723 4723
 
4724
-	return "<form class='bouton_action_post $class_form' method='post' action='$url'><div>" . form_hidden($url)
4725
-	. "<button type='submit' class='$class_btn'$title$onclick>$libelle</button></div></form>";
4724
+    return "<form class='bouton_action_post $class_form' method='post' action='$url'><div>" . form_hidden($url)
4725
+    . "<button type='submit' class='$class_btn'$title$onclick>$libelle</button></div></form>";
4726 4726
 }
4727 4727
 
4728 4728
 /**
@@ -4745,101 +4745,101 @@  discard block
 block discarded – undo
4745 4745
  * @return string
4746 4746
  */
4747 4747
 function generer_objet_info($id_objet, string $type_objet, string $info, string $etoile = '', array $params = []): string {
4748
-	static $trouver_table = null;
4749
-	static $objets;
4750
-
4751
-	// On verifie qu'on a tout ce qu'il faut
4752
-	$id_objet = intval($id_objet);
4753
-	if (!($id_objet and $type_objet and $info)) {
4754
-		return '';
4755
-	}
4756
-
4757
-	// si on a deja note que l'objet n'existe pas, ne pas aller plus loin
4758
-	if (isset($objets[$type_objet]) and $objets[$type_objet] === false) {
4759
-		return '';
4760
-	}
4761
-
4762
-	// Si on demande l'url, on retourne direct la fonction
4763
-	if ($info == 'url') {
4764
-		return generer_objet_url($id_objet, $type_objet, ...$params);
4765
-	}
4766
-
4767
-	// Sinon on va tout chercher dans la table et on garde en memoire
4768
-	$demande_titre = ($info === 'titre');
4769
-	$demande_introduction = ($info === 'introduction');
4770
-
4771
-	// On ne fait la requete que si on a pas deja l'objet ou si on demande le titre mais qu'on ne l'a pas encore
4772
-	if (
4773
-		!isset($objets[$type_objet][$id_objet])
4774
-		or
4775
-		($demande_titre and !isset($objets[$type_objet][$id_objet]['titre']))
4776
-	) {
4777
-		if (!$trouver_table) {
4778
-			$trouver_table = charger_fonction('trouver_table', 'base');
4779
-		}
4780
-		$desc = $trouver_table(table_objet_sql($type_objet));
4781
-		if (!$desc) {
4782
-			return $objets[$type_objet] = false;
4783
-		}
4784
-
4785
-		// Si on demande le titre, on le gere en interne
4786
-		$champ_titre = '';
4787
-		if ($demande_titre) {
4788
-			// si pas de titre declare mais champ titre, il sera peuple par le select *
4789
-			$champ_titre = (!empty($desc['titre'])) ? ', ' . $desc['titre'] : '';
4790
-		}
4791
-		include_spip('base/abstract_sql');
4792
-		include_spip('base/connect_sql');
4793
-		$objets[$type_objet][$id_objet] = sql_fetsel(
4794
-			'*' . $champ_titre,
4795
-			$desc['table_sql'],
4796
-			id_table_objet($type_objet) . ' = ' . intval($id_objet)
4797
-		);
4798
-
4799
-		// Toujours noter la longueur d'introduction, même si pas demandé cette fois-ci
4800
-		$objets[$type_objet]['introduction_longueur'] = $desc['introduction_longueur'] ?? null;
4801
-	}
4802
-
4803
-	// Pour les fonction generer_xxx, si on demande l'introduction,
4804
-	// ajouter la longueur au début des params supplémentaires
4805
-	if ($demande_introduction) {
4806
-		$introduction_longueur = $objets[$type_objet]['introduction_longueur'];
4807
-		array_unshift($params, $introduction_longueur);
4808
-	}
4809
-
4810
-	// Si la fonction generer_TYPE_TRUC existe, on l'utilise pour formater $info_generee
4811
-	if (
4812
-		$generer = charger_fonction("generer_${type_objet}_${info}", '', true)
4813
-		// @deprecated 4.1 generer_TRUC_TYPE
4814
-		or $generer = charger_fonction("generer_${info}_${type_objet}", '', true)
4815
-	) {
4816
-		$info_generee = $generer($id_objet, $objets[$type_objet][$id_objet], ...$params);
4817
-	}
4818
-	// Si la fonction generer_objet_TRUC existe, on l'utilise pour formater $info_generee
4819
-	elseif (
4820
-		$generer = charger_fonction("generer_objet_${info}", '', true)
4821
-		// @deprecated 4.1 generer_TRUC_entite
4822
-		or $generer = charger_fonction("generer_${info}_entite", '', true)
4823
-	) {
4824
-		$info_generee = $generer($id_objet, $type_objet, $objets[$type_objet][$id_objet], ...$params);
4825
-	} // Sinon on prend directement le champ SQL tel quel
4826
-	else {
4827
-		$info_generee = ($objets[$type_objet][$id_objet][$info] ?? '');
4828
-	}
4829
-
4830
-	// On va ensuite appliquer les traitements automatiques si besoin
4831
-	if (!$etoile) {
4832
-		// FIXME: on fournit un ENV minimum avec id et type et connect=''
4833
-		// mais ce fonctionnement est a ameliorer !
4834
-		$info_generee = appliquer_traitement_champ(
4835
-			$info_generee,
4836
-			$info,
4837
-			table_objet($type_objet),
4838
-			['id_objet' => $id_objet, 'objet' => $type_objet, '']
4839
-		);
4840
-	}
4841
-
4842
-	return $info_generee;
4748
+    static $trouver_table = null;
4749
+    static $objets;
4750
+
4751
+    // On verifie qu'on a tout ce qu'il faut
4752
+    $id_objet = intval($id_objet);
4753
+    if (!($id_objet and $type_objet and $info)) {
4754
+        return '';
4755
+    }
4756
+
4757
+    // si on a deja note que l'objet n'existe pas, ne pas aller plus loin
4758
+    if (isset($objets[$type_objet]) and $objets[$type_objet] === false) {
4759
+        return '';
4760
+    }
4761
+
4762
+    // Si on demande l'url, on retourne direct la fonction
4763
+    if ($info == 'url') {
4764
+        return generer_objet_url($id_objet, $type_objet, ...$params);
4765
+    }
4766
+
4767
+    // Sinon on va tout chercher dans la table et on garde en memoire
4768
+    $demande_titre = ($info === 'titre');
4769
+    $demande_introduction = ($info === 'introduction');
4770
+
4771
+    // On ne fait la requete que si on a pas deja l'objet ou si on demande le titre mais qu'on ne l'a pas encore
4772
+    if (
4773
+        !isset($objets[$type_objet][$id_objet])
4774
+        or
4775
+        ($demande_titre and !isset($objets[$type_objet][$id_objet]['titre']))
4776
+    ) {
4777
+        if (!$trouver_table) {
4778
+            $trouver_table = charger_fonction('trouver_table', 'base');
4779
+        }
4780
+        $desc = $trouver_table(table_objet_sql($type_objet));
4781
+        if (!$desc) {
4782
+            return $objets[$type_objet] = false;
4783
+        }
4784
+
4785
+        // Si on demande le titre, on le gere en interne
4786
+        $champ_titre = '';
4787
+        if ($demande_titre) {
4788
+            // si pas de titre declare mais champ titre, il sera peuple par le select *
4789
+            $champ_titre = (!empty($desc['titre'])) ? ', ' . $desc['titre'] : '';
4790
+        }
4791
+        include_spip('base/abstract_sql');
4792
+        include_spip('base/connect_sql');
4793
+        $objets[$type_objet][$id_objet] = sql_fetsel(
4794
+            '*' . $champ_titre,
4795
+            $desc['table_sql'],
4796
+            id_table_objet($type_objet) . ' = ' . intval($id_objet)
4797
+        );
4798
+
4799
+        // Toujours noter la longueur d'introduction, même si pas demandé cette fois-ci
4800
+        $objets[$type_objet]['introduction_longueur'] = $desc['introduction_longueur'] ?? null;
4801
+    }
4802
+
4803
+    // Pour les fonction generer_xxx, si on demande l'introduction,
4804
+    // ajouter la longueur au début des params supplémentaires
4805
+    if ($demande_introduction) {
4806
+        $introduction_longueur = $objets[$type_objet]['introduction_longueur'];
4807
+        array_unshift($params, $introduction_longueur);
4808
+    }
4809
+
4810
+    // Si la fonction generer_TYPE_TRUC existe, on l'utilise pour formater $info_generee
4811
+    if (
4812
+        $generer = charger_fonction("generer_${type_objet}_${info}", '', true)
4813
+        // @deprecated 4.1 generer_TRUC_TYPE
4814
+        or $generer = charger_fonction("generer_${info}_${type_objet}", '', true)
4815
+    ) {
4816
+        $info_generee = $generer($id_objet, $objets[$type_objet][$id_objet], ...$params);
4817
+    }
4818
+    // Si la fonction generer_objet_TRUC existe, on l'utilise pour formater $info_generee
4819
+    elseif (
4820
+        $generer = charger_fonction("generer_objet_${info}", '', true)
4821
+        // @deprecated 4.1 generer_TRUC_entite
4822
+        or $generer = charger_fonction("generer_${info}_entite", '', true)
4823
+    ) {
4824
+        $info_generee = $generer($id_objet, $type_objet, $objets[$type_objet][$id_objet], ...$params);
4825
+    } // Sinon on prend directement le champ SQL tel quel
4826
+    else {
4827
+        $info_generee = ($objets[$type_objet][$id_objet][$info] ?? '');
4828
+    }
4829
+
4830
+    // On va ensuite appliquer les traitements automatiques si besoin
4831
+    if (!$etoile) {
4832
+        // FIXME: on fournit un ENV minimum avec id et type et connect=''
4833
+        // mais ce fonctionnement est a ameliorer !
4834
+        $info_generee = appliquer_traitement_champ(
4835
+            $info_generee,
4836
+            $info,
4837
+            table_objet($type_objet),
4838
+            ['id_objet' => $id_objet, 'objet' => $type_objet, '']
4839
+        );
4840
+    }
4841
+
4842
+    return $info_generee;
4843 4843
 }
4844 4844
 
4845 4845
 /**
@@ -4847,7 +4847,7 @@  discard block
 block discarded – undo
4847 4847
  * @see generer_objet_info
4848 4848
  */
4849 4849
 function generer_info_entite($id_objet, $type_objet, $info, $etoile = '', $params = []) {
4850
-	return generer_objet_info(intval($id_objet), $type_objet, $info, $etoile, $params);
4850
+    return generer_objet_info(intval($id_objet), $type_objet, $info, $etoile, $params);
4851 4851
 }
4852 4852
 
4853 4853
 /**
@@ -4880,36 +4880,36 @@  discard block
 block discarded – undo
4880 4880
  */
4881 4881
 function generer_objet_introduction(int $id_objet, string $type_objet, array $ligne_sql, ?int $introduction_longueur = null, $longueur_ou_suite = null, ?string $suite = null, string $connect = ''): string {
4882 4882
 
4883
-	$descriptif = $ligne_sql['descriptif'] ?? '';
4884
-	$texte = $ligne_sql['texte'] ?? '';
4885
-	// En absence de descriptif, on se rabat sur chapo + texte
4886
-	if (isset($ligne_sql['chapo'])) {
4887
-		$chapo = $ligne_sql['chapo'];
4888
-		$texte = strlen($descriptif) ?
4889
-			'' :
4890
-			"$chapo \n\n $texte";
4891
-	}
4883
+    $descriptif = $ligne_sql['descriptif'] ?? '';
4884
+    $texte = $ligne_sql['texte'] ?? '';
4885
+    // En absence de descriptif, on se rabat sur chapo + texte
4886
+    if (isset($ligne_sql['chapo'])) {
4887
+        $chapo = $ligne_sql['chapo'];
4888
+        $texte = strlen($descriptif) ?
4889
+            '' :
4890
+            "$chapo \n\n $texte";
4891
+    }
4892 4892
 
4893
-	// Longueur en paramètre, sinon celle renseignée dans la description de l'objet, sinon valeur en dur
4894
-	if (!intval($longueur_ou_suite)) {
4895
-		$longueur = intval($introduction_longueur ?: 600);
4896
-	} else {
4897
-		$longueur = intval($longueur_ou_suite);
4898
-	}
4893
+    // Longueur en paramètre, sinon celle renseignée dans la description de l'objet, sinon valeur en dur
4894
+    if (!intval($longueur_ou_suite)) {
4895
+        $longueur = intval($introduction_longueur ?: 600);
4896
+    } else {
4897
+        $longueur = intval($longueur_ou_suite);
4898
+    }
4899 4899
 
4900
-	// On peut optionnellement passer la suite en 1er paramètre de la balise
4901
-	// Ex : #INTRODUCTION{...}
4902
-	if (
4903
-		is_null($suite)
4904
-		and !intval($longueur_ou_suite)
4905
-	) {
4906
-		$suite = $longueur_ou_suite;
4907
-	}
4900
+    // On peut optionnellement passer la suite en 1er paramètre de la balise
4901
+    // Ex : #INTRODUCTION{...}
4902
+    if (
4903
+        is_null($suite)
4904
+        and !intval($longueur_ou_suite)
4905
+    ) {
4906
+        $suite = $longueur_ou_suite;
4907
+    }
4908 4908
 
4909
-	$f = chercher_filtre('introduction');
4910
-	$introduction = $f($descriptif, $texte, $longueur, $connect, $suite);
4909
+    $f = chercher_filtre('introduction');
4910
+    $introduction = $f($descriptif, $texte, $longueur, $connect, $suite);
4911 4911
 
4912
-	return $introduction;
4912
+    return $introduction;
4913 4913
 }
4914 4914
 
4915 4915
 /**
@@ -4917,7 +4917,7 @@  discard block
 block discarded – undo
4917 4917
  * @see generer_objet_introduction
4918 4918
  */
4919 4919
 function generer_introduction_entite($id_objet, $type_objet, $ligne_sql, $introduction_longueur = null, $longueur_ou_suite = null, $suite = null, string $connect = '') {
4920
-	return generer_objet_introduction(intval($id_objet), $type_objet, $ligne_sql, $introduction_longueur, $longueur_ou_suite, $suite, $connect);
4920
+    return generer_objet_introduction(intval($id_objet), $type_objet, $ligne_sql, $introduction_longueur, $longueur_ou_suite, $suite, $connect);
4921 4921
 }
4922 4922
 
4923 4923
 /**
@@ -4931,44 +4931,44 @@  discard block
 block discarded – undo
4931 4931
  * @return string
4932 4932
  */
4933 4933
 function appliquer_traitement_champ($texte, $champ, $table_objet = '', $env = [], string $connect = '') {
4934
-	if (!$champ) {
4935
-		return $texte;
4936
-	}
4934
+    if (!$champ) {
4935
+        return $texte;
4936
+    }
4937 4937
 
4938
-	// On charge les définitions des traitements (inc/texte et fichiers de fonctions)
4939
-	// car il ne faut pas partir du principe que c'est déjà chargé (form ajax, etc)
4940
-	include_fichiers_fonctions();
4938
+    // On charge les définitions des traitements (inc/texte et fichiers de fonctions)
4939
+    // car il ne faut pas partir du principe que c'est déjà chargé (form ajax, etc)
4940
+    include_fichiers_fonctions();
4941 4941
 
4942
-	$champ = strtoupper($champ);
4943
-	$traitements = $GLOBALS['table_des_traitements'][$champ] ?? false;
4944
-	if (!$traitements or !is_array($traitements)) {
4945
-		return $texte;
4946
-	}
4942
+    $champ = strtoupper($champ);
4943
+    $traitements = $GLOBALS['table_des_traitements'][$champ] ?? false;
4944
+    if (!$traitements or !is_array($traitements)) {
4945
+        return $texte;
4946
+    }
4947 4947
 
4948
-	$traitement = '';
4949
-	if ($table_objet and (!isset($traitements[0]) or count($traitements) > 1)) {
4950
-		// necessaire pour prendre en charge les vieux appels avec un table_objet_sql en 3e arg
4951
-		$table_objet = table_objet($table_objet);
4952
-		if (isset($traitements[$table_objet])) {
4953
-			$traitement = $traitements[$table_objet];
4954
-		}
4955
-	}
4956
-	if (!$traitement and isset($traitements[0])) {
4957
-		$traitement = $traitements[0];
4958
-	}
4959
-	// (sinon prendre le premier de la liste par defaut ?)
4948
+    $traitement = '';
4949
+    if ($table_objet and (!isset($traitements[0]) or count($traitements) > 1)) {
4950
+        // necessaire pour prendre en charge les vieux appels avec un table_objet_sql en 3e arg
4951
+        $table_objet = table_objet($table_objet);
4952
+        if (isset($traitements[$table_objet])) {
4953
+            $traitement = $traitements[$table_objet];
4954
+        }
4955
+    }
4956
+    if (!$traitement and isset($traitements[0])) {
4957
+        $traitement = $traitements[0];
4958
+    }
4959
+    // (sinon prendre le premier de la liste par defaut ?)
4960 4960
 
4961
-	if (!$traitement) {
4962
-		return $texte;
4963
-	}
4961
+    if (!$traitement) {
4962
+        return $texte;
4963
+    }
4964 4964
 
4965
-	$traitement = str_replace('%s', "'" . texte_script($texte) . "'", $traitement);
4965
+    $traitement = str_replace('%s', "'" . texte_script($texte) . "'", $traitement);
4966 4966
 
4967
-	// Fournir $connect et $Pile[0] au traitement si besoin
4968
-	$Pile = [0 => $env];
4969
-	eval("\$texte = $traitement;");
4967
+    // Fournir $connect et $Pile[0] au traitement si besoin
4968
+    $Pile = [0 => $env];
4969
+    eval("\$texte = $traitement;");
4970 4970
 
4971
-	return $texte;
4971
+    return $texte;
4972 4972
 }
4973 4973
 
4974 4974
 
@@ -4982,21 +4982,21 @@  discard block
 block discarded – undo
4982 4982
  * @return string
4983 4983
  */
4984 4984
 function generer_objet_lien(int $id_objet, string $objet, int $longueur = 80, string $connect = ''): string {
4985
-	include_spip('inc/liens');
4986
-	$titre = traiter_raccourci_titre($id_objet, $objet, $connect);
4987
-	// lorsque l'objet n'est plus declare (plugin desactive par exemple)
4988
-	// le raccourcis n'est plus valide
4989
-	$titre = typo($titre['titre']) ?? '';
4990
-	// on essaye avec generer_info_entite ?
4991
-	if (!strlen($titre) and !$connect) {
4992
-		$titre = generer_objet_info($id_objet, $objet, 'titre');
4993
-	}
4994
-	if (!strlen($titre)) {
4995
-		$titre = _T('info_sans_titre');
4996
-	}
4997
-	$url = generer_objet_url($id_objet, $objet, '', '', null, '', $connect);
4985
+    include_spip('inc/liens');
4986
+    $titre = traiter_raccourci_titre($id_objet, $objet, $connect);
4987
+    // lorsque l'objet n'est plus declare (plugin desactive par exemple)
4988
+    // le raccourcis n'est plus valide
4989
+    $titre = typo($titre['titre']) ?? '';
4990
+    // on essaye avec generer_info_entite ?
4991
+    if (!strlen($titre) and !$connect) {
4992
+        $titre = generer_objet_info($id_objet, $objet, 'titre');
4993
+    }
4994
+    if (!strlen($titre)) {
4995
+        $titre = _T('info_sans_titre');
4996
+    }
4997
+    $url = generer_objet_url($id_objet, $objet, '', '', null, '', $connect);
4998 4998
 
4999
-	return "<a href='$url' class='$objet'>" . couper($titre, $longueur) . '</a>';
4999
+    return "<a href='$url' class='$objet'>" . couper($titre, $longueur) . '</a>';
5000 5000
 }
5001 5001
 
5002 5002
 /**
@@ -5004,7 +5004,7 @@  discard block
 block discarded – undo
5004 5004
  * @see generer_objet_lien
5005 5005
  */
5006 5006
 function generer_lien_entite($id_objet, $objet, $longueur = 80, $connect = null) {
5007
-	return generer_objet_lien(intval($id_objet), $objet, $longueur, $connect ?? '');
5007
+    return generer_objet_lien(intval($id_objet), $objet, $longueur, $connect ?? '');
5008 5008
 }
5009 5009
 
5010 5010
 /**
@@ -5020,15 +5020,15 @@  discard block
 block discarded – undo
5020 5020
  * @return string
5021 5021
  */
5022 5022
 function wrap($texte, $wrap) {
5023
-	$balises = extraire_balises($wrap);
5024
-	if (preg_match_all(",<([a-z]\w*)\b[^>]*>,UimsS", $wrap, $regs, PREG_PATTERN_ORDER)) {
5025
-		$texte = $wrap . $texte;
5026
-		$regs = array_reverse($regs[1]);
5027
-		$wrap = '</' . implode('></', $regs) . '>';
5028
-		$texte = $texte . $wrap;
5029
-	}
5023
+    $balises = extraire_balises($wrap);
5024
+    if (preg_match_all(",<([a-z]\w*)\b[^>]*>,UimsS", $wrap, $regs, PREG_PATTERN_ORDER)) {
5025
+        $texte = $wrap . $texte;
5026
+        $regs = array_reverse($regs[1]);
5027
+        $wrap = '</' . implode('></', $regs) . '>';
5028
+        $texte = $texte . $wrap;
5029
+    }
5030 5030
 
5031
-	return $texte;
5031
+    return $texte;
5032 5032
 }
5033 5033
 
5034 5034
 
@@ -5048,44 +5048,44 @@  discard block
 block discarded – undo
5048 5048
  * @return array|mixed|string
5049 5049
  */
5050 5050
 function filtre_print_dist($u, $join = '<br />', $indent = 0) {
5051
-	if (is_string($u)) {
5052
-		$u = typo($u);
5051
+    if (is_string($u)) {
5052
+        $u = typo($u);
5053 5053
 
5054
-		return $u;
5055
-	}
5054
+        return $u;
5055
+    }
5056 5056
 
5057
-	// caster $u en array si besoin
5058
-	if (is_object($u)) {
5059
-		$u = (array)$u;
5060
-	}
5057
+    // caster $u en array si besoin
5058
+    if (is_object($u)) {
5059
+        $u = (array)$u;
5060
+    }
5061 5061
 
5062
-	if (is_array($u)) {
5063
-		$out = '';
5064
-		// toutes les cles sont numeriques ?
5065
-		// et aucun enfant n'est un tableau
5066
-		// liste simple separee par des virgules
5067
-		$numeric_keys = array_map('is_numeric', array_keys($u));
5068
-		$array_values = array_map('is_array', $u);
5069
-		$object_values = array_map('is_object', $u);
5070
-		if (
5071
-			array_sum($numeric_keys) == count($numeric_keys)
5072
-			and !array_sum($array_values)
5073
-			and !array_sum($object_values)
5074
-		) {
5075
-			return join(', ', array_map('filtre_print_dist', $u));
5076
-		}
5062
+    if (is_array($u)) {
5063
+        $out = '';
5064
+        // toutes les cles sont numeriques ?
5065
+        // et aucun enfant n'est un tableau
5066
+        // liste simple separee par des virgules
5067
+        $numeric_keys = array_map('is_numeric', array_keys($u));
5068
+        $array_values = array_map('is_array', $u);
5069
+        $object_values = array_map('is_object', $u);
5070
+        if (
5071
+            array_sum($numeric_keys) == count($numeric_keys)
5072
+            and !array_sum($array_values)
5073
+            and !array_sum($object_values)
5074
+        ) {
5075
+            return join(', ', array_map('filtre_print_dist', $u));
5076
+        }
5077 5077
 
5078
-		// sinon on passe a la ligne et on indente
5079
-		$i_str = str_pad('', $indent, ' ');
5080
-		foreach ($u as $k => $v) {
5081
-			$out .= $join . $i_str . "$k: " . filtre_print_dist($v, $join, $indent + 2);
5082
-		}
5078
+        // sinon on passe a la ligne et on indente
5079
+        $i_str = str_pad('', $indent, ' ');
5080
+        foreach ($u as $k => $v) {
5081
+            $out .= $join . $i_str . "$k: " . filtre_print_dist($v, $join, $indent + 2);
5082
+        }
5083 5083
 
5084
-		return $out;
5085
-	}
5084
+        return $out;
5085
+    }
5086 5086
 
5087
-	// on sait pas quoi faire...
5088
-	return $u;
5087
+    // on sait pas quoi faire...
5088
+    return $u;
5089 5089
 }
5090 5090
 
5091 5091
 
@@ -5098,10 +5098,10 @@  discard block
 block discarded – undo
5098 5098
  * @return string|array
5099 5099
  */
5100 5100
 function objet_info($objet, $info) {
5101
-	$table = table_objet_sql($objet);
5102
-	$infos = lister_tables_objets_sql($table);
5101
+    $table = table_objet_sql($objet);
5102
+    $infos = lister_tables_objets_sql($table);
5103 5103
 
5104
-	return ($infos[$info] ?? '');
5104
+    return ($infos[$info] ?? '');
5105 5105
 }
5106 5106
 
5107 5107
 /**
@@ -5116,11 +5116,11 @@  discard block
 block discarded – undo
5116 5116
  *     Texte traduit du comptage, tel que '3 articles'
5117 5117
  */
5118 5118
 function objet_afficher_nb($nb, $objet) {
5119
-	if (!$nb) {
5120
-		return _T(objet_info($objet, 'info_aucun_objet'));
5121
-	} else {
5122
-		return _T(objet_info($objet, $nb == 1 ? 'info_1_objet' : 'info_nb_objets'), ['nb' => $nb]);
5123
-	}
5119
+    if (!$nb) {
5120
+        return _T(objet_info($objet, 'info_aucun_objet'));
5121
+    } else {
5122
+        return _T(objet_info($objet, $nb == 1 ? 'info_1_objet' : 'info_nb_objets'), ['nb' => $nb]);
5123
+    }
5124 5124
 }
5125 5125
 
5126 5126
 /**
@@ -5132,11 +5132,11 @@  discard block
 block discarded – undo
5132 5132
  * @return string
5133 5133
  */
5134 5134
 function objet_icone($objet, $taille = 24, $class = '') {
5135
-	$icone = objet_info($objet, 'icone_objet') . '-' . $taille . '.png';
5136
-	$icone = chemin_image($icone);
5137
-	$balise_img = charger_filtre('balise_img');
5135
+    $icone = objet_info($objet, 'icone_objet') . '-' . $taille . '.png';
5136
+    $icone = chemin_image($icone);
5137
+    $balise_img = charger_filtre('balise_img');
5138 5138
 
5139
-	return $icone ? $balise_img($icone, _T(objet_info($objet, 'texte_objet')), $class, $taille) : '';
5139
+    return $icone ? $balise_img($icone, _T(objet_info($objet, 'texte_objet')), $class, $taille) : '';
5140 5140
 }
5141 5141
 
5142 5142
 /**
@@ -5157,12 +5157,12 @@  discard block
 block discarded – undo
5157 5157
  * @return string
5158 5158
  */
5159 5159
 function objet_T($objet, $chaine, $args = [], $options = []) {
5160
-	$chaine = explode(':', $chaine);
5161
-	if ($t = _T($objet . ':' . end($chaine), $args, array_merge($options, ['force' => false]))) {
5162
-		return $t;
5163
-	}
5164
-	$chaine = implode(':', $chaine);
5165
-	return _T($chaine, $args, $options);
5160
+    $chaine = explode(':', $chaine);
5161
+    if ($t = _T($objet . ':' . end($chaine), $args, array_merge($options, ['force' => false]))) {
5162
+        return $t;
5163
+    }
5164
+    $chaine = implode(':', $chaine);
5165
+    return _T($chaine, $args, $options);
5166 5166
 }
5167 5167
 
5168 5168
 /**
@@ -5176,18 +5176,18 @@  discard block
 block discarded – undo
5176 5176
  * @return string      Code HTML
5177 5177
  */
5178 5178
 function insert_head_css_conditionnel($flux) {
5179
-	if (
5180
-		strpos($flux, '<!-- insert_head_css -->') === false
5181
-		and $p = strpos($flux, '<!-- insert_head -->')
5182
-	) {
5183
-		// plutot avant le premier js externe (jquery) pour etre non bloquant
5184
-		if ($p1 = stripos($flux, '<script src=') and $p1 < $p) {
5185
-			$p = $p1;
5186
-		}
5187
-		$flux = substr_replace($flux, pipeline('insert_head_css', '<!-- insert_head_css -->'), $p, 0);
5188
-	}
5179
+    if (
5180
+        strpos($flux, '<!-- insert_head_css -->') === false
5181
+        and $p = strpos($flux, '<!-- insert_head -->')
5182
+    ) {
5183
+        // plutot avant le premier js externe (jquery) pour etre non bloquant
5184
+        if ($p1 = stripos($flux, '<script src=') and $p1 < $p) {
5185
+            $p = $p1;
5186
+        }
5187
+        $flux = substr_replace($flux, pipeline('insert_head_css', '<!-- insert_head_css -->'), $p, 0);
5188
+    }
5189 5189
 
5190
-	return $flux;
5190
+    return $flux;
5191 5191
 }
5192 5192
 
5193 5193
 /**
@@ -5210,72 +5210,72 @@  discard block
 block discarded – undo
5210 5210
  * @return string
5211 5211
  */
5212 5212
 function produire_fond_statique($fond, $contexte = [], $options = [], string $connect = '') {
5213
-	if (isset($contexte['format'])) {
5214
-		$extension = $contexte['format'];
5215
-		unset($contexte['format']);
5216
-	} else {
5217
-		$extension = 'html';
5218
-		if (preg_match(',[.](css|js|json|xml|svg)$,', $fond, $m)) {
5219
-			$extension = $m[1];
5220
-		}
5221
-	}
5222
-	// recuperer le contenu produit par le squelette
5223
-	$options['raw'] = true;
5224
-	$cache = recuperer_fond($fond, $contexte, $options, $connect);
5225
-
5226
-	// calculer le nom de la css
5227
-	$dir_var = sous_repertoire(_DIR_VAR, 'cache-' . $extension);
5228
-	$nom_safe = preg_replace(',\W,', '_', str_replace('.', '_', $fond));
5229
-	$contexte_implicite = calculer_contexte_implicite();
5230
-
5231
-	// par defaut on hash selon les contextes qui sont a priori moins variables
5232
-	// mais on peut hasher selon le contenu a la demande, si plusieurs contextes produisent un meme contenu
5233
-	// reduit la variabilite du nom et donc le nombre de css concatenees possibles in fine
5234
-	if (isset($options['hash_on_content']) and $options['hash_on_content']) {
5235
-		$hash = md5($contexte_implicite['host'] . '::' . $cache);
5236
-	}
5237
-	else {
5238
-		unset($contexte_implicite['notes']); // pas pertinent pour signaler un changeemnt de contenu pour des css/js
5239
-		ksort($contexte);
5240
-		$hash = md5($fond . json_encode($contexte_implicite, JSON_THROW_ON_ERROR) . json_encode($contexte, JSON_THROW_ON_ERROR) . $connect);
5241
-	}
5242
-	$filename = $dir_var . $extension . "dyn-$nom_safe-" . substr($hash, 0, 8) . ".$extension";
5243
-
5244
-	// mettre a jour le fichier si il n'existe pas
5245
-	// ou trop ancien
5246
-	// le dernier fichier produit est toujours suffixe par .last
5247
-	// et recopie sur le fichier cible uniquement si il change
5248
-	if (
5249
-		!file_exists($filename)
5250
-		or !file_exists($filename . '.last')
5251
-		or (isset($cache['lastmodified']) and $cache['lastmodified'] and filemtime($filename . '.last') < $cache['lastmodified'])
5252
-		or (defined('_VAR_MODE') and _VAR_MODE == 'recalcul')
5253
-	) {
5254
-		$contenu = $cache['texte'];
5255
-		// passer les urls en absolu si c'est une css
5256
-		if ($extension == 'css') {
5257
-			$contenu = urls_absolues_css(
5258
-				$contenu,
5259
-				test_espace_prive() ? generer_url_ecrire('accueil') : generer_url_public($fond)
5260
-			);
5261
-		}
5262
-
5263
-		$comment = '';
5264
-		// ne pas insérer de commentaire sur certains formats
5265
-		if (!in_array($extension, ['json', 'xml', 'svg'])) {
5266
-			$comment = "/* #PRODUIRE{fond=$fond";
5267
-			foreach ($contexte as $k => $v) {
5268
-				$comment .= ",$k=$v";
5269
-			}
5270
-			// pas de date dans le commentaire car sinon ca invalide le md5 et force la maj
5271
-			// mais on peut mettre un md5 du contenu, ce qui donne un aperu rapide si la feuille a change ou non
5272
-			$comment .= "}\n   md5:" . md5($contenu) . " */\n";
5273
-		}
5274
-		// et ecrire le fichier si il change
5275
-		ecrire_fichier_calcule_si_modifie($filename, $comment . $contenu, false, true);
5276
-	}
5277
-
5278
-	return timestamp($filename);
5213
+    if (isset($contexte['format'])) {
5214
+        $extension = $contexte['format'];
5215
+        unset($contexte['format']);
5216
+    } else {
5217
+        $extension = 'html';
5218
+        if (preg_match(',[.](css|js|json|xml|svg)$,', $fond, $m)) {
5219
+            $extension = $m[1];
5220
+        }
5221
+    }
5222
+    // recuperer le contenu produit par le squelette
5223
+    $options['raw'] = true;
5224
+    $cache = recuperer_fond($fond, $contexte, $options, $connect);
5225
+
5226
+    // calculer le nom de la css
5227
+    $dir_var = sous_repertoire(_DIR_VAR, 'cache-' . $extension);
5228
+    $nom_safe = preg_replace(',\W,', '_', str_replace('.', '_', $fond));
5229
+    $contexte_implicite = calculer_contexte_implicite();
5230
+
5231
+    // par defaut on hash selon les contextes qui sont a priori moins variables
5232
+    // mais on peut hasher selon le contenu a la demande, si plusieurs contextes produisent un meme contenu
5233
+    // reduit la variabilite du nom et donc le nombre de css concatenees possibles in fine
5234
+    if (isset($options['hash_on_content']) and $options['hash_on_content']) {
5235
+        $hash = md5($contexte_implicite['host'] . '::' . $cache);
5236
+    }
5237
+    else {
5238
+        unset($contexte_implicite['notes']); // pas pertinent pour signaler un changeemnt de contenu pour des css/js
5239
+        ksort($contexte);
5240
+        $hash = md5($fond . json_encode($contexte_implicite, JSON_THROW_ON_ERROR) . json_encode($contexte, JSON_THROW_ON_ERROR) . $connect);
5241
+    }
5242
+    $filename = $dir_var . $extension . "dyn-$nom_safe-" . substr($hash, 0, 8) . ".$extension";
5243
+
5244
+    // mettre a jour le fichier si il n'existe pas
5245
+    // ou trop ancien
5246
+    // le dernier fichier produit est toujours suffixe par .last
5247
+    // et recopie sur le fichier cible uniquement si il change
5248
+    if (
5249
+        !file_exists($filename)
5250
+        or !file_exists($filename . '.last')
5251
+        or (isset($cache['lastmodified']) and $cache['lastmodified'] and filemtime($filename . '.last') < $cache['lastmodified'])
5252
+        or (defined('_VAR_MODE') and _VAR_MODE == 'recalcul')
5253
+    ) {
5254
+        $contenu = $cache['texte'];
5255
+        // passer les urls en absolu si c'est une css
5256
+        if ($extension == 'css') {
5257
+            $contenu = urls_absolues_css(
5258
+                $contenu,
5259
+                test_espace_prive() ? generer_url_ecrire('accueil') : generer_url_public($fond)
5260
+            );
5261
+        }
5262
+
5263
+        $comment = '';
5264
+        // ne pas insérer de commentaire sur certains formats
5265
+        if (!in_array($extension, ['json', 'xml', 'svg'])) {
5266
+            $comment = "/* #PRODUIRE{fond=$fond";
5267
+            foreach ($contexte as $k => $v) {
5268
+                $comment .= ",$k=$v";
5269
+            }
5270
+            // pas de date dans le commentaire car sinon ca invalide le md5 et force la maj
5271
+            // mais on peut mettre un md5 du contenu, ce qui donne un aperu rapide si la feuille a change ou non
5272
+            $comment .= "}\n   md5:" . md5($contenu) . " */\n";
5273
+        }
5274
+        // et ecrire le fichier si il change
5275
+        ecrire_fichier_calcule_si_modifie($filename, $comment . $contenu, false, true);
5276
+    }
5277
+
5278
+    return timestamp($filename);
5279 5279
 }
5280 5280
 
5281 5281
 /**
@@ -5288,15 +5288,15 @@  discard block
 block discarded – undo
5288 5288
  *    $fichier auquel on a ajouté le timestamp
5289 5289
  */
5290 5290
 function timestamp($fichier) {
5291
-	if (
5292
-		!$fichier
5293
-		or !file_exists($fichier)
5294
-		or !$m = filemtime($fichier)
5295
-	) {
5296
-		return $fichier;
5297
-	}
5291
+    if (
5292
+        !$fichier
5293
+        or !file_exists($fichier)
5294
+        or !$m = filemtime($fichier)
5295
+    ) {
5296
+        return $fichier;
5297
+    }
5298 5298
 
5299
-	return "$fichier?$m";
5299
+    return "$fichier?$m";
5300 5300
 }
5301 5301
 
5302 5302
 /**
@@ -5306,11 +5306,11 @@  discard block
 block discarded – undo
5306 5306
  * @return string
5307 5307
  */
5308 5308
 function supprimer_timestamp($url) {
5309
-	if (strpos($url, '?') === false) {
5310
-		return $url;
5311
-	}
5309
+    if (strpos($url, '?') === false) {
5310
+        return $url;
5311
+    }
5312 5312
 
5313
-	return preg_replace(',\?[[:digit:]]+$,', '', $url);
5313
+    return preg_replace(',\?[[:digit:]]+$,', '', $url);
5314 5314
 }
5315 5315
 
5316 5316
 /**
@@ -5325,9 +5325,9 @@  discard block
 block discarded – undo
5325 5325
  * @return string
5326 5326
  */
5327 5327
 function filtre_nettoyer_titre_email_dist($titre) {
5328
-	include_spip('inc/envoyer_mail');
5328
+    include_spip('inc/envoyer_mail');
5329 5329
 
5330
-	return nettoyer_titre_email($titre);
5330
+    return nettoyer_titre_email($titre);
5331 5331
 }
5332 5332
 
5333 5333
 /**
@@ -5349,27 +5349,27 @@  discard block
 block discarded – undo
5349 5349
  * @return string
5350 5350
  */
5351 5351
 function filtre_chercher_rubrique_dist(
5352
-	$titre,
5353
-	$id_objet,
5354
-	$id_parent,
5355
-	$objet,
5356
-	$id_secteur,
5357
-	$restreint,
5358
-	$actionable = false,
5359
-	$retour_sans_cadre = false
5352
+    $titre,
5353
+    $id_objet,
5354
+    $id_parent,
5355
+    $objet,
5356
+    $id_secteur,
5357
+    $restreint,
5358
+    $actionable = false,
5359
+    $retour_sans_cadre = false
5360 5360
 ) {
5361
-	include_spip('inc/filtres_ecrire');
5361
+    include_spip('inc/filtres_ecrire');
5362 5362
 
5363
-	return chercher_rubrique(
5364
-		$titre,
5365
-		$id_objet,
5366
-		$id_parent,
5367
-		$objet,
5368
-		$id_secteur,
5369
-		$restreint,
5370
-		$actionable,
5371
-		$retour_sans_cadre
5372
-	);
5363
+    return chercher_rubrique(
5364
+        $titre,
5365
+        $id_objet,
5366
+        $id_parent,
5367
+        $objet,
5368
+        $id_secteur,
5369
+        $restreint,
5370
+        $actionable,
5371
+        $retour_sans_cadre
5372
+    );
5373 5373
 }
5374 5374
 
5375 5375
 /**
@@ -5398,56 +5398,56 @@  discard block
 block discarded – undo
5398 5398
  *     Chaîne vide si l'accès est autorisé
5399 5399
  */
5400 5400
 function sinon_interdire_acces($ok = false, $url = '', $statut = 0, $message = null) {
5401
-	if ($ok) {
5402
-		return '';
5403
-	}
5404
-
5405
-	// Vider tous les tampons
5406
-	$level = @ob_get_level();
5407
-	while ($level--) {
5408
-		@ob_end_clean();
5409
-	}
5410
-
5411
-	include_spip('inc/headers');
5412
-
5413
-	// S'il y a une URL, on redirige (si pas de statut, la fonction mettra 302 par défaut)
5414
-	if ($url) {
5415
-		redirige_par_entete($url, '', $statut);
5416
-	}
5417
-
5418
-	// ecriture simplifiee avec message en 3eme argument (= statut 403)
5419
-	if (!is_numeric($statut) and is_null($message)) {
5420
-		$message = $statut;
5421
-		$statut = 0;
5422
-	}
5423
-	if (!$message) {
5424
-		$message = '';
5425
-	}
5426
-	$statut = intval($statut);
5427
-
5428
-	// Si on est dans l'espace privé, on génère du 403 Forbidden par defaut ou du 404
5429
-	if (test_espace_prive()) {
5430
-		if (!$statut or !in_array($statut, [404, 403])) {
5431
-			$statut = 403;
5432
-		}
5433
-		http_response_code(403);
5434
-		$echec = charger_fonction('403', 'exec');
5435
-		$echec($message);
5436
-	} else {
5437
-		// Sinon dans l'espace public on redirige vers une 404 par défaut, car elle toujours présente normalement
5438
-		if (!$statut) {
5439
-			$statut = 404;
5440
-		}
5441
-		// Dans tous les cas on modifie l'entité avec ce qui est demandé
5442
-		http_response_code($statut);
5443
-		// Si le statut est une erreur et qu'il n'y a pas de redirection on va chercher le squelette du même nom
5444
-		if ($statut >= 400) {
5445
-			echo recuperer_fond("$statut", ['erreur' => $message]);
5446
-		}
5447
-	}
5448
-
5449
-
5450
-	exit;
5401
+    if ($ok) {
5402
+        return '';
5403
+    }
5404
+
5405
+    // Vider tous les tampons
5406
+    $level = @ob_get_level();
5407
+    while ($level--) {
5408
+        @ob_end_clean();
5409
+    }
5410
+
5411
+    include_spip('inc/headers');
5412
+
5413
+    // S'il y a une URL, on redirige (si pas de statut, la fonction mettra 302 par défaut)
5414
+    if ($url) {
5415
+        redirige_par_entete($url, '', $statut);
5416
+    }
5417
+
5418
+    // ecriture simplifiee avec message en 3eme argument (= statut 403)
5419
+    if (!is_numeric($statut) and is_null($message)) {
5420
+        $message = $statut;
5421
+        $statut = 0;
5422
+    }
5423
+    if (!$message) {
5424
+        $message = '';
5425
+    }
5426
+    $statut = intval($statut);
5427
+
5428
+    // Si on est dans l'espace privé, on génère du 403 Forbidden par defaut ou du 404
5429
+    if (test_espace_prive()) {
5430
+        if (!$statut or !in_array($statut, [404, 403])) {
5431
+            $statut = 403;
5432
+        }
5433
+        http_response_code(403);
5434
+        $echec = charger_fonction('403', 'exec');
5435
+        $echec($message);
5436
+    } else {
5437
+        // Sinon dans l'espace public on redirige vers une 404 par défaut, car elle toujours présente normalement
5438
+        if (!$statut) {
5439
+            $statut = 404;
5440
+        }
5441
+        // Dans tous les cas on modifie l'entité avec ce qui est demandé
5442
+        http_response_code($statut);
5443
+        // Si le statut est une erreur et qu'il n'y a pas de redirection on va chercher le squelette du même nom
5444
+        if ($statut >= 400) {
5445
+            echo recuperer_fond("$statut", ['erreur' => $message]);
5446
+        }
5447
+    }
5448
+
5449
+
5450
+    exit;
5451 5451
 }
5452 5452
 
5453 5453
 /**
@@ -5458,11 +5458,11 @@  discard block
 block discarded – undo
5458 5458
  * @return string
5459 5459
  */
5460 5460
 function filtre_compacte_dist($source, $format = null) {
5461
-	if (function_exists('minifier')) {
5462
-		return minifier($source, $format);
5463
-	}
5461
+    if (function_exists('minifier')) {
5462
+        return minifier($source, $format);
5463
+    }
5464 5464
 
5465
-	return $source;
5465
+    return $source;
5466 5466
 }
5467 5467
 
5468 5468
 
@@ -5474,31 +5474,31 @@  discard block
 block discarded – undo
5474 5474
  * @return string
5475 5475
  */
5476 5476
 function spip_affiche_mot_de_passe_masque($passe, $afficher_partiellement = false, $portion_pourcent = null) {
5477
-	$l = strlen($passe);
5478
-
5479
-	if ($l <= 8 or !$afficher_partiellement) {
5480
-		if (!$l) {
5481
-			return ''; // montrer qu'il y a pas de mot de passe si il y en a pas
5482
-		}
5483
-		return str_pad('', $afficher_partiellement ? $l : 16, '*');
5484
-	}
5485
-
5486
-	if (is_null($portion_pourcent)) {
5487
-		if (!defined('_SPIP_AFFICHE_MOT_DE_PASSE_MASQUE_PERCENT')) {
5488
-			define('_SPIP_AFFICHE_MOT_DE_PASSE_MASQUE_PERCENT', 20); // 20%
5489
-		}
5490
-		$portion_pourcent = _SPIP_AFFICHE_MOT_DE_PASSE_MASQUE_PERCENT;
5491
-	}
5492
-	if ($portion_pourcent >= 100) {
5493
-		return $passe;
5494
-	}
5495
-	$e = intval(ceil($l * $portion_pourcent / 100 / 2));
5496
-	$e = max($e, 0);
5497
-	$mid = str_pad('', $l - 2 * $e, '*');
5498
-	if ($e > 0 and strlen($mid) > 8) {
5499
-		$mid = '***...***';
5500
-	}
5501
-	return substr($passe, 0, $e) . $mid . ($e > 0 ? substr($passe, -$e) : '');
5477
+    $l = strlen($passe);
5478
+
5479
+    if ($l <= 8 or !$afficher_partiellement) {
5480
+        if (!$l) {
5481
+            return ''; // montrer qu'il y a pas de mot de passe si il y en a pas
5482
+        }
5483
+        return str_pad('', $afficher_partiellement ? $l : 16, '*');
5484
+    }
5485
+
5486
+    if (is_null($portion_pourcent)) {
5487
+        if (!defined('_SPIP_AFFICHE_MOT_DE_PASSE_MASQUE_PERCENT')) {
5488
+            define('_SPIP_AFFICHE_MOT_DE_PASSE_MASQUE_PERCENT', 20); // 20%
5489
+        }
5490
+        $portion_pourcent = _SPIP_AFFICHE_MOT_DE_PASSE_MASQUE_PERCENT;
5491
+    }
5492
+    if ($portion_pourcent >= 100) {
5493
+        return $passe;
5494
+    }
5495
+    $e = intval(ceil($l * $portion_pourcent / 100 / 2));
5496
+    $e = max($e, 0);
5497
+    $mid = str_pad('', $l - 2 * $e, '*');
5498
+    if ($e > 0 and strlen($mid) > 8) {
5499
+        $mid = '***...***';
5500
+    }
5501
+    return substr($passe, 0, $e) . $mid . ($e > 0 ? substr($passe, -$e) : '');
5502 5502
 }
5503 5503
 
5504 5504
 
@@ -5519,64 +5519,64 @@  discard block
 block discarded – undo
5519 5519
  */
5520 5520
 function identifiant_slug($texte, $type = '', $options = []) {
5521 5521
 
5522
-	$original = $texte;
5523
-	$separateur = ($options['separateur'] ?? '_');
5524
-	$longueur_maxi = ($options['longueur_maxi'] ?? 60);
5525
-	$longueur_mini = ($options['longueur_mini'] ?? 0);
5522
+    $original = $texte;
5523
+    $separateur = ($options['separateur'] ?? '_');
5524
+    $longueur_maxi = ($options['longueur_maxi'] ?? 60);
5525
+    $longueur_mini = ($options['longueur_mini'] ?? 0);
5526 5526
 
5527
-	if (!function_exists('translitteration')) {
5528
-		include_spip('inc/charsets');
5529
-	}
5527
+    if (!function_exists('translitteration')) {
5528
+        include_spip('inc/charsets');
5529
+    }
5530 5530
 
5531
-	// pas de balise html
5532
-	if (strpos($texte, '<') !== false) {
5533
-		$texte = strip_tags($texte);
5534
-	}
5535
-	if (strpos($texte, '&') !== false) {
5536
-		$texte = unicode2charset($texte);
5537
-	}
5538
-	// On enlève les espaces indésirables
5539
-	$texte = trim($texte);
5531
+    // pas de balise html
5532
+    if (strpos($texte, '<') !== false) {
5533
+        $texte = strip_tags($texte);
5534
+    }
5535
+    if (strpos($texte, '&') !== false) {
5536
+        $texte = unicode2charset($texte);
5537
+    }
5538
+    // On enlève les espaces indésirables
5539
+    $texte = trim($texte);
5540 5540
 
5541
-	// On enlève les accents et cie
5542
-	$texte = translitteration($texte);
5541
+    // On enlève les accents et cie
5542
+    $texte = translitteration($texte);
5543 5543
 
5544
-	// On remplace tout ce qui n'est pas un mot par un séparateur
5545
-	$texte = preg_replace(',[\W_]+,ms', $separateur, $texte);
5544
+    // On remplace tout ce qui n'est pas un mot par un séparateur
5545
+    $texte = preg_replace(',[\W_]+,ms', $separateur, $texte);
5546 5546
 
5547
-	// nettoyer les doubles occurences du separateur si besoin
5548
-	while (strpos($texte, (string) "$separateur$separateur") !== false) {
5549
-		$texte = str_replace("$separateur$separateur", $separateur, $texte);
5550
-	}
5547
+    // nettoyer les doubles occurences du separateur si besoin
5548
+    while (strpos($texte, (string) "$separateur$separateur") !== false) {
5549
+        $texte = str_replace("$separateur$separateur", $separateur, $texte);
5550
+    }
5551 5551
 
5552
-	// pas de separateur au debut ni a la fin
5553
-	$texte = trim($texte, $separateur);
5552
+    // pas de separateur au debut ni a la fin
5553
+    $texte = trim($texte, $separateur);
5554 5554
 
5555
-	// en minuscules
5556
-	$texte = strtolower($texte);
5555
+    // en minuscules
5556
+    $texte = strtolower($texte);
5557 5557
 
5558
-	switch ($type) {
5559
-		case 'class':
5560
-		case 'id':
5561
-		case 'anchor':
5562
-			if (preg_match(',^\d,', $texte)) {
5563
-				$texte = substr($type, 0, 1) . $texte;
5564
-			}
5565
-	}
5558
+    switch ($type) {
5559
+        case 'class':
5560
+        case 'id':
5561
+        case 'anchor':
5562
+            if (preg_match(',^\d,', $texte)) {
5563
+                $texte = substr($type, 0, 1) . $texte;
5564
+            }
5565
+    }
5566 5566
 
5567
-	if (strlen($texte) > $longueur_maxi) {
5568
-		$texte = substr($texte, 0, $longueur_maxi);
5569
-	}
5567
+    if (strlen($texte) > $longueur_maxi) {
5568
+        $texte = substr($texte, 0, $longueur_maxi);
5569
+    }
5570 5570
 
5571
-	if (strlen($texte) < $longueur_mini and $longueur_mini < $longueur_maxi) {
5572
-		if (preg_match(',^\d,', $texte)) {
5573
-			$texte = ($type ? substr($type, 0, 1) : 's') . $texte;
5574
-		}
5575
-		$texte .= $separateur . md5($original);
5576
-		$texte = substr($texte, 0, $longueur_mini);
5577
-	}
5571
+    if (strlen($texte) < $longueur_mini and $longueur_mini < $longueur_maxi) {
5572
+        if (preg_match(',^\d,', $texte)) {
5573
+            $texte = ($type ? substr($type, 0, 1) : 's') . $texte;
5574
+        }
5575
+        $texte .= $separateur . md5($original);
5576
+        $texte = substr($texte, 0, $longueur_mini);
5577
+    }
5578 5578
 
5579
-	return $texte;
5579
+    return $texte;
5580 5580
 }
5581 5581
 
5582 5582
 
@@ -5597,11 +5597,11 @@  discard block
 block discarded – undo
5597 5597
  * @exemple `<:info_maximum|label_nettoyer:>`
5598 5598
  */
5599 5599
 function label_nettoyer(string $text, bool $ucfirst = true): string {
5600
-	$label = preg_replace('#([\s:]|\&nbsp;)+$#u', '', $text);
5601
-	if ($ucfirst) {
5602
-		$label = spip_ucfirst($label);
5603
-	}
5604
-	return $label;
5600
+    $label = preg_replace('#([\s:]|\&nbsp;)+$#u', '', $text);
5601
+    if ($ucfirst) {
5602
+        $label = spip_ucfirst($label);
5603
+    }
5604
+    return $label;
5605 5605
 }
5606 5606
 
5607 5607
 /**
@@ -5614,8 +5614,8 @@  discard block
 block discarded – undo
5614 5614
  * @exemple `<:info_maximum|label_ponctuer:>`
5615 5615
  */
5616 5616
 function label_ponctuer(string $text, bool $ucfirst = true): string {
5617
-	$label = label_nettoyer($text, $ucfirst);
5618
-	return _T('label_ponctuer', ['label' => $label]);
5617
+    $label = label_nettoyer($text, $ucfirst);
5618
+    return _T('label_ponctuer', ['label' => $label]);
5619 5619
 }
5620 5620
 
5621 5621
 
@@ -5628,19 +5628,19 @@  discard block
 block discarded – undo
5628 5628
  * @return array
5629 5629
  */
5630 5630
 function helper_filtre_objet_lister_enfants_ou_parents($objet, $id_objet, $fonction) {
5631
-	if (!in_array($fonction, ['objet_lister_parents', 'objet_lister_enfants', 'objet_lister_parents_par_type', 'objet_lister_enfants_par_type'])) {
5632
-		return [];
5633
-	}
5631
+    if (!in_array($fonction, ['objet_lister_parents', 'objet_lister_enfants', 'objet_lister_parents_par_type', 'objet_lister_enfants_par_type'])) {
5632
+        return [];
5633
+    }
5634 5634
 
5635
-	// compatibilite signature inversee
5636
-	if (is_numeric($objet) and !is_numeric($id_objet)) {
5637
-		[$objet, $id_objet] = [$id_objet, $objet];
5638
-	}
5635
+    // compatibilite signature inversee
5636
+    if (is_numeric($objet) and !is_numeric($id_objet)) {
5637
+        [$objet, $id_objet] = [$id_objet, $objet];
5638
+    }
5639 5639
 
5640
-	if (!function_exists($fonction)) {
5641
-		include_spip('base/objets');
5642
-	}
5643
-	return $fonction($objet, $id_objet);
5640
+    if (!function_exists($fonction)) {
5641
+        include_spip('base/objets');
5642
+    }
5643
+    return $fonction($objet, $id_objet);
5644 5644
 }
5645 5645
 
5646 5646
 
@@ -5655,7 +5655,7 @@  discard block
 block discarded – undo
5655 5655
  * @return array
5656 5656
  */
5657 5657
 function filtre_objet_lister_parents_dist($objet, $id_objet) {
5658
-	return helper_filtre_objet_lister_enfants_ou_parents($objet, $id_objet, 'objet_lister_parents');
5658
+    return helper_filtre_objet_lister_enfants_ou_parents($objet, $id_objet, 'objet_lister_parents');
5659 5659
 }
5660 5660
 
5661 5661
 /**
@@ -5669,7 +5669,7 @@  discard block
 block discarded – undo
5669 5669
  * @return array
5670 5670
  */
5671 5671
 function filtre_objet_lister_parents_par_type_dist($objet, $id_objet) {
5672
-	return helper_filtre_objet_lister_enfants_ou_parents($objet, $id_objet, 'objet_lister_parents_par_type');
5672
+    return helper_filtre_objet_lister_enfants_ou_parents($objet, $id_objet, 'objet_lister_parents_par_type');
5673 5673
 }
5674 5674
 
5675 5675
 /**
@@ -5683,7 +5683,7 @@  discard block
 block discarded – undo
5683 5683
  * @return array
5684 5684
  */
5685 5685
 function filtre_objet_lister_enfants_dist($objet, $id_objet) {
5686
-	return helper_filtre_objet_lister_enfants_ou_parents($objet, $id_objet, 'objet_lister_enfants');
5686
+    return helper_filtre_objet_lister_enfants_ou_parents($objet, $id_objet, 'objet_lister_enfants');
5687 5687
 }
5688 5688
 
5689 5689
 /**
@@ -5697,5 +5697,5 @@  discard block
 block discarded – undo
5697 5697
  * @return array
5698 5698
  */
5699 5699
 function filtre_objet_lister_enfants_par_type_dist($objet, $id_objet) {
5700
-	return helper_filtre_objet_lister_enfants_ou_parents($objet, $id_objet, 'objet_lister_enfants_par_type');
5700
+    return helper_filtre_objet_lister_enfants_ou_parents($objet, $id_objet, 'objet_lister_enfants_par_type');
5701 5701
 }
Please login to merge, or discard this patch.
ecrire/src/Chiffrer/SpipCles.php 1 patch
Indentation   +162 added lines, -162 removed lines patch added patch discarded remove patch
@@ -14,166 +14,166 @@
 block discarded – undo
14 14
 
15 15
 /** Gestion des clés d’authentification / chiffrement de SPIP */
16 16
 final class SpipCles {
17
-	private static array $instances = [];
18
-
19
-	private string $file = _DIR_ETC . 'cles.php';
20
-	private Cles $cles;
21
-
22
-	public static function instance(string $file = ''): self {
23
-		if (empty(self::$instances[$file])) {
24
-			self::$instances[$file] = new self($file);
25
-		}
26
-		return self::$instances[$file];
27
-	}
28
-
29
-	/**
30
-	 * Retourne le secret du site (shorthand)
31
-	 * @uses self::getSecretSite()
32
-	 */
33
-	public static function secret_du_site(): ?string {
34
-		return (self::instance())->getSecretSite();
35
-	}
36
-
37
-	private function __construct(string $file = '') {
38
-		if ($file) {
39
-			$this->file = $file;
40
-		}
41
-		$this->cles = new Cles($this->read());
42
-	}
43
-
44
-	/**
45
-	 * Renvoyer le secret du site
46
-	 *
47
-	 * Le secret du site doit rester aussi secret que possible, et est eternel
48
-	 * On ne doit pas l'exporter
49
-	 *
50
-	 * Le secret est partagé entre une clé disque et une clé bdd
51
-	 *
52
-	 * @return string
53
-	 */
54
-	public function getSecretSite(bool $autoInit = true): ?string {
55
-		$key = $this->getKey('secret_du_site', $autoInit);
56
-		$meta = $this->getMetaKey('secret_du_site', $autoInit);
57
-		// conserve la même longeur.
58
-		return $key ^ $meta;
59
-	}
60
-
61
-	/** Renvoyer le secret des authentifications */
62
-	public function getSecretAuth(bool $autoInit = false): ?string {
63
-		return $this->getKey('secret_des_auth', $autoInit);
64
-	}
65
-	public function save(): bool {
66
-		return ecrire_fichier_securise($this->file, $this->cles->toJson());
67
-	}
68
-
69
-	/**
70
-	 * Fournir une sauvegarde chiffree des cles (a l'aide d'une autre clé, comme le pass d'un auteur)
71
-	 *
72
-	 * @param string $withKey Clé de chiffrage de la sauvegarde
73
-	 * @return string Contenu de la sauvegarde chiffrée générée
74
-	 */
75
-	public function backup(
76
-		#[\SensitiveParameter]
77
-		string $withKey
78
-	): string {
79
-		if (count($this->cles)) {
80
-			return Chiffrement::chiffrer($this->cles->toJson(), $withKey);
81
-		}
82
-		return '';
83
-	}
84
-
85
-	/**
86
-	 * Restaurer les cles manquantes depuis une sauvegarde chiffree des cles
87
-	 * (si la sauvegarde est bien valide)
88
-	 *
89
-	 * @param string $backup Sauvegarde chiffrée (générée par backup())
90
-	 * @param int $id_auteur
91
-	 * @param string $pass
92
-	 * @return void
93
-	 */
94
-	public function restore(
95
-		string $backup,
96
-		#[\SensitiveParameter]
97
-		string $password_clair,
98
-		#[\SensitiveParameter]
99
-		string $password_hash,
100
-		int $id_auteur
101
-	): bool {
102
-		if (empty($backup)) {
103
-			return false;
104
-		}
105
-
106
-		$sauvegarde = Chiffrement::dechiffrer($backup, $password_clair);
107
-		$json = json_decode($sauvegarde, true);
108
-		if (!$json) {
109
-			return false;
110
-		}
111
-
112
-		// cela semble une sauvegarde valide
113
-		$cles_potentielles = array_map('base64_decode', $json);
114
-
115
-		// il faut faire une double verif sur secret_des_auth
116
-		// pour s'assurer qu'elle permet bien de decrypter le pass de l'auteur qui fournit la sauvegarde
117
-		// et par extension tous les passwords
118
-		if (!empty($cles_potentielles['secret_des_auth'])) {
119
-			if (!Password::verifier($password_clair, $password_hash, $cles_potentielles['secret_des_auth'])) {
120
-				spip_log("Restauration de la cle `secret_des_auth` par id_auteur $id_auteur erronnee, on ignore", 'chiffrer' . _LOG_INFO_IMPORTANTE);
121
-				unset($cles_potentielles['secret_des_auth']);
122
-			}
123
-		}
124
-
125
-		// on merge les cles pour recuperer les cles manquantes
126
-		$restauration = false;
127
-		foreach ($cles_potentielles as $name => $key) {
128
-			if (!$this->cles->has($name)) {
129
-				$this->cles->set($name, $key);
130
-				spip_log("Restauration de la cle $name par id_auteur $id_auteur", 'chiffrer' . _LOG_INFO_IMPORTANTE);
131
-				$restauration = true;
132
-			}
133
-		}
134
-		return $restauration;
135
-	}
136
-
137
-	private function getKey(string $name, bool $autoInit): ?string {
138
-		if ($this->cles->has($name)) {
139
-			return $this->cles->get($name);
140
-		}
141
-		if ($autoInit) {
142
-			$this->cles->generate($name);
143
-			$this->save();
144
-			return $this->cles->get($name);
145
-		}
146
-		return null;
147
-	}
148
-
149
-	private function getMetaKey(string $name, bool $autoInit = true): ?string {
150
-		if (!isset($GLOBALS['meta'][$name])) {
151
-			include_spip('base/abstract_sql');
152
-			$GLOBALS['meta'][$name] = sql_getfetsel('valeur', 'spip_meta', 'nom = ' . sql_quote($name, '', 'string'));
153
-		}
154
-		$key = base64_decode($GLOBALS['meta'][$name] ?? '');
155
-		if (strlen($key) === \SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
156
-			return $key;
157
-		}
158
-		if (!$autoInit) {
159
-			return null;
160
-		}
161
-		$key = Chiffrement::keygen();
162
-		ecrire_meta($name, base64_encode($key), 'non');
163
-		lire_metas(); // au cas ou ecrire_meta() ne fonctionne pas
164
-
165
-		return $key;
166
-	}
167
-
168
-	private function read(): array {
169
-		lire_fichier_securise($this->file, $json);
170
-		if (
171
-			$json
172
-			and $json = \json_decode($json, true)
173
-			and is_array($json)
174
-		) {
175
-			return array_map('base64_decode', $json);
176
-		}
177
-		return [];
178
-	}
17
+    private static array $instances = [];
18
+
19
+    private string $file = _DIR_ETC . 'cles.php';
20
+    private Cles $cles;
21
+
22
+    public static function instance(string $file = ''): self {
23
+        if (empty(self::$instances[$file])) {
24
+            self::$instances[$file] = new self($file);
25
+        }
26
+        return self::$instances[$file];
27
+    }
28
+
29
+    /**
30
+     * Retourne le secret du site (shorthand)
31
+     * @uses self::getSecretSite()
32
+     */
33
+    public static function secret_du_site(): ?string {
34
+        return (self::instance())->getSecretSite();
35
+    }
36
+
37
+    private function __construct(string $file = '') {
38
+        if ($file) {
39
+            $this->file = $file;
40
+        }
41
+        $this->cles = new Cles($this->read());
42
+    }
43
+
44
+    /**
45
+     * Renvoyer le secret du site
46
+     *
47
+     * Le secret du site doit rester aussi secret que possible, et est eternel
48
+     * On ne doit pas l'exporter
49
+     *
50
+     * Le secret est partagé entre une clé disque et une clé bdd
51
+     *
52
+     * @return string
53
+     */
54
+    public function getSecretSite(bool $autoInit = true): ?string {
55
+        $key = $this->getKey('secret_du_site', $autoInit);
56
+        $meta = $this->getMetaKey('secret_du_site', $autoInit);
57
+        // conserve la même longeur.
58
+        return $key ^ $meta;
59
+    }
60
+
61
+    /** Renvoyer le secret des authentifications */
62
+    public function getSecretAuth(bool $autoInit = false): ?string {
63
+        return $this->getKey('secret_des_auth', $autoInit);
64
+    }
65
+    public function save(): bool {
66
+        return ecrire_fichier_securise($this->file, $this->cles->toJson());
67
+    }
68
+
69
+    /**
70
+     * Fournir une sauvegarde chiffree des cles (a l'aide d'une autre clé, comme le pass d'un auteur)
71
+     *
72
+     * @param string $withKey Clé de chiffrage de la sauvegarde
73
+     * @return string Contenu de la sauvegarde chiffrée générée
74
+     */
75
+    public function backup(
76
+        #[\SensitiveParameter]
77
+        string $withKey
78
+    ): string {
79
+        if (count($this->cles)) {
80
+            return Chiffrement::chiffrer($this->cles->toJson(), $withKey);
81
+        }
82
+        return '';
83
+    }
84
+
85
+    /**
86
+     * Restaurer les cles manquantes depuis une sauvegarde chiffree des cles
87
+     * (si la sauvegarde est bien valide)
88
+     *
89
+     * @param string $backup Sauvegarde chiffrée (générée par backup())
90
+     * @param int $id_auteur
91
+     * @param string $pass
92
+     * @return void
93
+     */
94
+    public function restore(
95
+        string $backup,
96
+        #[\SensitiveParameter]
97
+        string $password_clair,
98
+        #[\SensitiveParameter]
99
+        string $password_hash,
100
+        int $id_auteur
101
+    ): bool {
102
+        if (empty($backup)) {
103
+            return false;
104
+        }
105
+
106
+        $sauvegarde = Chiffrement::dechiffrer($backup, $password_clair);
107
+        $json = json_decode($sauvegarde, true);
108
+        if (!$json) {
109
+            return false;
110
+        }
111
+
112
+        // cela semble une sauvegarde valide
113
+        $cles_potentielles = array_map('base64_decode', $json);
114
+
115
+        // il faut faire une double verif sur secret_des_auth
116
+        // pour s'assurer qu'elle permet bien de decrypter le pass de l'auteur qui fournit la sauvegarde
117
+        // et par extension tous les passwords
118
+        if (!empty($cles_potentielles['secret_des_auth'])) {
119
+            if (!Password::verifier($password_clair, $password_hash, $cles_potentielles['secret_des_auth'])) {
120
+                spip_log("Restauration de la cle `secret_des_auth` par id_auteur $id_auteur erronnee, on ignore", 'chiffrer' . _LOG_INFO_IMPORTANTE);
121
+                unset($cles_potentielles['secret_des_auth']);
122
+            }
123
+        }
124
+
125
+        // on merge les cles pour recuperer les cles manquantes
126
+        $restauration = false;
127
+        foreach ($cles_potentielles as $name => $key) {
128
+            if (!$this->cles->has($name)) {
129
+                $this->cles->set($name, $key);
130
+                spip_log("Restauration de la cle $name par id_auteur $id_auteur", 'chiffrer' . _LOG_INFO_IMPORTANTE);
131
+                $restauration = true;
132
+            }
133
+        }
134
+        return $restauration;
135
+    }
136
+
137
+    private function getKey(string $name, bool $autoInit): ?string {
138
+        if ($this->cles->has($name)) {
139
+            return $this->cles->get($name);
140
+        }
141
+        if ($autoInit) {
142
+            $this->cles->generate($name);
143
+            $this->save();
144
+            return $this->cles->get($name);
145
+        }
146
+        return null;
147
+    }
148
+
149
+    private function getMetaKey(string $name, bool $autoInit = true): ?string {
150
+        if (!isset($GLOBALS['meta'][$name])) {
151
+            include_spip('base/abstract_sql');
152
+            $GLOBALS['meta'][$name] = sql_getfetsel('valeur', 'spip_meta', 'nom = ' . sql_quote($name, '', 'string'));
153
+        }
154
+        $key = base64_decode($GLOBALS['meta'][$name] ?? '');
155
+        if (strlen($key) === \SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
156
+            return $key;
157
+        }
158
+        if (!$autoInit) {
159
+            return null;
160
+        }
161
+        $key = Chiffrement::keygen();
162
+        ecrire_meta($name, base64_encode($key), 'non');
163
+        lire_metas(); // au cas ou ecrire_meta() ne fonctionne pas
164
+
165
+        return $key;
166
+    }
167
+
168
+    private function read(): array {
169
+        lire_fichier_securise($this->file, $json);
170
+        if (
171
+            $json
172
+            and $json = \json_decode($json, true)
173
+            and is_array($json)
174
+        ) {
175
+            return array_map('base64_decode', $json);
176
+        }
177
+        return [];
178
+    }
179 179
 }
Please login to merge, or discard this patch.
ecrire/src/Chiffrer/Chiffrement.php 1 patch
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -19,78 +19,78 @@
 block discarded – undo
19 19
  * @link https://www.php.net/manual/fr/book.sodium.php
20 20
  */
21 21
 class Chiffrement {
22
-	/** Chiffre un message en utilisant une clé ou un mot de passe */
23
-	public static function chiffrer(
24
-		string $message,
25
-		#[\SensitiveParameter]
26
-		string $key
27
-	): ?string {
28
-		// create a random salt for key derivation
29
-		$salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);
30
-		$key = self::deriveKeyFromPassword($key, $salt);
31
-		$nonce = random_bytes(\SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
32
-		$padded_message = sodium_pad($message, 16);
33
-		$encrypted = sodium_crypto_secretbox($padded_message, $nonce, $key);
34
-		$encoded = base64_encode($salt . $nonce . $encrypted);
35
-		sodium_memzero($key);
36
-		sodium_memzero($nonce);
37
-		sodium_memzero($salt);
38
-		spip_log("chiffrer($message)=$encoded", 'chiffrer' . _LOG_DEBUG);
39
-		return $encoded;
40
-	}
22
+    /** Chiffre un message en utilisant une clé ou un mot de passe */
23
+    public static function chiffrer(
24
+        string $message,
25
+        #[\SensitiveParameter]
26
+        string $key
27
+    ): ?string {
28
+        // create a random salt for key derivation
29
+        $salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);
30
+        $key = self::deriveKeyFromPassword($key, $salt);
31
+        $nonce = random_bytes(\SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
32
+        $padded_message = sodium_pad($message, 16);
33
+        $encrypted = sodium_crypto_secretbox($padded_message, $nonce, $key);
34
+        $encoded = base64_encode($salt . $nonce . $encrypted);
35
+        sodium_memzero($key);
36
+        sodium_memzero($nonce);
37
+        sodium_memzero($salt);
38
+        spip_log("chiffrer($message)=$encoded", 'chiffrer' . _LOG_DEBUG);
39
+        return $encoded;
40
+    }
41 41
 
42
-	/** Déchiffre un message en utilisant une clé ou un mot de passe */
43
-	public static function dechiffrer(
44
-		string $encoded,
45
-		#[\SensitiveParameter]
46
-		string $key
47
-	): ?string {
48
-		$decoded = base64_decode($encoded);
49
-		$salt = substr($decoded, 0, \SODIUM_CRYPTO_PWHASH_SALTBYTES);
50
-		$nonce = substr($decoded, \SODIUM_CRYPTO_PWHASH_SALTBYTES, \SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
51
-		$encrypted = substr($decoded, \SODIUM_CRYPTO_PWHASH_SALTBYTES + \SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
52
-		$key = self::deriveKeyFromPassword($key, $salt);
53
-		$padded_message = sodium_crypto_secretbox_open($encrypted, $nonce, $key);
54
-		sodium_memzero($key);
55
-		sodium_memzero($nonce);
56
-		sodium_memzero($salt);
57
-		if ($padded_message === false) {
58
-			spip_log("dechiffrer() chiffre corrompu `$encoded`", 'chiffrer' . _LOG_DEBUG);
59
-			return null;
60
-		}
61
-		$message = sodium_unpad($padded_message, 16);
62
-		spip_log("dechiffrer($encoded)=$message", 'chiffrer' . _LOG_DEBUG);
63
-		return $message;
64
-	}
42
+    /** Déchiffre un message en utilisant une clé ou un mot de passe */
43
+    public static function dechiffrer(
44
+        string $encoded,
45
+        #[\SensitiveParameter]
46
+        string $key
47
+    ): ?string {
48
+        $decoded = base64_decode($encoded);
49
+        $salt = substr($decoded, 0, \SODIUM_CRYPTO_PWHASH_SALTBYTES);
50
+        $nonce = substr($decoded, \SODIUM_CRYPTO_PWHASH_SALTBYTES, \SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
51
+        $encrypted = substr($decoded, \SODIUM_CRYPTO_PWHASH_SALTBYTES + \SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
52
+        $key = self::deriveKeyFromPassword($key, $salt);
53
+        $padded_message = sodium_crypto_secretbox_open($encrypted, $nonce, $key);
54
+        sodium_memzero($key);
55
+        sodium_memzero($nonce);
56
+        sodium_memzero($salt);
57
+        if ($padded_message === false) {
58
+            spip_log("dechiffrer() chiffre corrompu `$encoded`", 'chiffrer' . _LOG_DEBUG);
59
+            return null;
60
+        }
61
+        $message = sodium_unpad($padded_message, 16);
62
+        spip_log("dechiffrer($encoded)=$message", 'chiffrer' . _LOG_DEBUG);
63
+        return $message;
64
+    }
65 65
 
66
-	/** Génère une clé de la taille attendue pour le chiffrement */
67
-	public static function keygen(): string {
68
-		return sodium_crypto_secretbox_keygen();
69
-	}
66
+    /** Génère une clé de la taille attendue pour le chiffrement */
67
+    public static function keygen(): string {
68
+        return sodium_crypto_secretbox_keygen();
69
+    }
70 70
 
71
-	/**
72
-	 * Retourne une clé de la taille attendue pour le chiffrement
73
-	 *
74
-	 * Notamment si on utilise un mot de passe comme clé, il faut le hacher
75
-	 * pour servir de clé à la taille correspondante.
76
-	 */
77
-	private static function deriveKeyFromPassword(
78
-		#[\SensitiveParameter]
79
-		string $password,
80
-		string $salt
81
-	): string {
82
-		if (strlen($password) === \SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
83
-			return $password;
84
-		}
85
-		$key = sodium_crypto_pwhash(
86
-			\SODIUM_CRYPTO_SECRETBOX_KEYBYTES,
87
-			$password,
88
-			$salt,
89
-			\SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
90
-			\SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
91
-		);
92
-		sodium_memzero($password);
71
+    /**
72
+     * Retourne une clé de la taille attendue pour le chiffrement
73
+     *
74
+     * Notamment si on utilise un mot de passe comme clé, il faut le hacher
75
+     * pour servir de clé à la taille correspondante.
76
+     */
77
+    private static function deriveKeyFromPassword(
78
+        #[\SensitiveParameter]
79
+        string $password,
80
+        string $salt
81
+    ): string {
82
+        if (strlen($password) === \SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
83
+            return $password;
84
+        }
85
+        $key = sodium_crypto_pwhash(
86
+            \SODIUM_CRYPTO_SECRETBOX_KEYBYTES,
87
+            $password,
88
+            $salt,
89
+            \SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
90
+            \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
91
+        );
92
+        sodium_memzero($password);
93 93
 
94
-		return $key;
95
-	}
94
+        return $key;
95
+    }
96 96
 }
Please login to merge, or discard this patch.