Completed
Push — master ( 15f754...76bd8f )
by cam
01:28
created
ecrire/public/fonctions.php 1 patch
Indentation   +373 added lines, -373 removed lines patch added patch discarded remove patch
@@ -22,7 +22,7 @@  discard block
 block discarded – undo
22 22
  **/
23 23
 
24 24
 if (!defined('_ECRIRE_INC_VERSION')) {
25
-	return;
25
+    return;
26 26
 }
27 27
 
28 28
 // public/interfaces definit des traitements sur les champs qui utilisent des fonctions de inc/texte
@@ -54,75 +54,75 @@  discard block
 block discarded – undo
54 54
  *     Introduction calculée
55 55
  **/
56 56
 function filtre_introduction_dist($descriptif, $texte, $longueur, $connect, $suite = null) {
57
-	// Si un descriptif est envoye, on l'utilise directement
58
-	if (strlen($descriptif)) {
59
-		return appliquer_traitement_champ($descriptif, 'introduction', '', [], $connect);
60
-	}
61
-
62
-	// De preference ce qui est marque <intro>...</intro>
63
-	$intro = '';
64
-	$texte = preg_replace(',(</?)intro>,i', "\\1intro>", $texte); // minuscules
65
-	while ($fin = strpos($texte, '</intro>')) {
66
-		$zone = substr($texte, 0, $fin);
67
-		$texte = substr($texte, $fin + strlen('</intro>'));
68
-		if (($deb = strpos($zone, '<intro>')) || str_starts_with($zone, '<intro>')) {
69
-			$zone = substr($zone, $deb + 7);
70
-		}
71
-		$intro .= $zone;
72
-	}
73
-
74
-	// [12025] On ne *PEUT* pas couper simplement ici car c'est du texte brut,
75
-	// qui inclus raccourcis et modeles
76
-	// un simple <articlexx> peut etre ensuite transforme en 1000 lignes ...
77
-	// par ailleurs le nettoyage des raccourcis ne tient pas compte
78
-	// des surcharges et enrichissement de propre
79
-	// couper doit se faire apres propre
80
-	//$texte = nettoyer_raccourcis_typo($intro ? $intro : $texte, $connect);
81
-
82
-	// Cependant pour des questions de perfs on coupe quand meme, en prenant
83
-	// large et en se mefiant des tableaux #1323
84
-
85
-	if (strlen($intro)) {
86
-		$texte = $intro;
87
-	} else {
88
-		if (
89
-			!str_contains("\n" . $texte, "\n|")
90
-			&& strlen($texte) > 2.5 * $longueur
91
-		) {
92
-			if (str_contains($texte, '<multi')) {
93
-				$texte = extraire_multi($texte);
94
-			}
95
-			$texte = couper($texte, 2 * $longueur);
96
-		}
97
-	}
98
-
99
-	// ne pas tenir compte des notes
100
-	if ($notes = charger_fonction('notes', 'inc', true)) {
101
-		$notes('', 'empiler');
102
-	}
103
-	// Supprimer les modèles avant le propre afin d'éviter qu'ils n'ajoutent du texte indésirable
104
-	// dans l'introduction.
105
-	$texte = supprime_img($texte, '');
106
-	$texte = appliquer_traitement_champ($texte, 'introduction', '', [], $connect);
107
-
108
-	if ($notes) {
109
-		$notes('', 'depiler');
110
-	}
111
-
112
-	if (is_null($suite) && defined('_INTRODUCTION_SUITE')) {
113
-		$suite = _INTRODUCTION_SUITE;
114
-	}
115
-	$texte = couper($texte, $longueur, $suite);
116
-	// comme on a coupe il faut repasser la typo (on a perdu les insecables)
117
-	$texte = typo($texte, true, $connect, []);
118
-
119
-	// et reparagrapher si necessaire (coherence avec le cas descriptif)
120
-	// une introduction a tojours un <p>
121
-	if ($GLOBALS['toujours_paragrapher']) { // Fermer les paragraphes
122
-	$texte = paragrapher($texte, $GLOBALS['toujours_paragrapher']);
123
-	}
124
-
125
-	return $texte;
57
+    // Si un descriptif est envoye, on l'utilise directement
58
+    if (strlen($descriptif)) {
59
+        return appliquer_traitement_champ($descriptif, 'introduction', '', [], $connect);
60
+    }
61
+
62
+    // De preference ce qui est marque <intro>...</intro>
63
+    $intro = '';
64
+    $texte = preg_replace(',(</?)intro>,i', "\\1intro>", $texte); // minuscules
65
+    while ($fin = strpos($texte, '</intro>')) {
66
+        $zone = substr($texte, 0, $fin);
67
+        $texte = substr($texte, $fin + strlen('</intro>'));
68
+        if (($deb = strpos($zone, '<intro>')) || str_starts_with($zone, '<intro>')) {
69
+            $zone = substr($zone, $deb + 7);
70
+        }
71
+        $intro .= $zone;
72
+    }
73
+
74
+    // [12025] On ne *PEUT* pas couper simplement ici car c'est du texte brut,
75
+    // qui inclus raccourcis et modeles
76
+    // un simple <articlexx> peut etre ensuite transforme en 1000 lignes ...
77
+    // par ailleurs le nettoyage des raccourcis ne tient pas compte
78
+    // des surcharges et enrichissement de propre
79
+    // couper doit se faire apres propre
80
+    //$texte = nettoyer_raccourcis_typo($intro ? $intro : $texte, $connect);
81
+
82
+    // Cependant pour des questions de perfs on coupe quand meme, en prenant
83
+    // large et en se mefiant des tableaux #1323
84
+
85
+    if (strlen($intro)) {
86
+        $texte = $intro;
87
+    } else {
88
+        if (
89
+            !str_contains("\n" . $texte, "\n|")
90
+            && strlen($texte) > 2.5 * $longueur
91
+        ) {
92
+            if (str_contains($texte, '<multi')) {
93
+                $texte = extraire_multi($texte);
94
+            }
95
+            $texte = couper($texte, 2 * $longueur);
96
+        }
97
+    }
98
+
99
+    // ne pas tenir compte des notes
100
+    if ($notes = charger_fonction('notes', 'inc', true)) {
101
+        $notes('', 'empiler');
102
+    }
103
+    // Supprimer les modèles avant le propre afin d'éviter qu'ils n'ajoutent du texte indésirable
104
+    // dans l'introduction.
105
+    $texte = supprime_img($texte, '');
106
+    $texte = appliquer_traitement_champ($texte, 'introduction', '', [], $connect);
107
+
108
+    if ($notes) {
109
+        $notes('', 'depiler');
110
+    }
111
+
112
+    if (is_null($suite) && defined('_INTRODUCTION_SUITE')) {
113
+        $suite = _INTRODUCTION_SUITE;
114
+    }
115
+    $texte = couper($texte, $longueur, $suite);
116
+    // comme on a coupe il faut repasser la typo (on a perdu les insecables)
117
+    $texte = typo($texte, true, $connect, []);
118
+
119
+    // et reparagrapher si necessaire (coherence avec le cas descriptif)
120
+    // une introduction a tojours un <p>
121
+    if ($GLOBALS['toujours_paragrapher']) { // Fermer les paragraphes
122
+    $texte = paragrapher($texte, $GLOBALS['toujours_paragrapher']);
123
+    }
124
+
125
+    return $texte;
126 126
 }
127 127
 
128 128
 
@@ -157,64 +157,64 @@  discard block
 block discarded – undo
157 157
  *     Code HTML de la pagination
158 158
  **/
159 159
 function filtre_pagination_dist(
160
-	$total,
161
-	$nom,
162
-	$position,
163
-	$pas,
164
-	$liste = true,
165
-	$modele = '',
166
-	string $connect = '',
167
-	$env = []
160
+    $total,
161
+    $nom,
162
+    $position,
163
+    $pas,
164
+    $liste = true,
165
+    $modele = '',
166
+    string $connect = '',
167
+    $env = []
168 168
 ) {
169
-	static $ancres = [];
170
-	if ($pas < 1) {
171
-		return '';
172
-	}
173
-	$ancre = 'pagination' . $nom; // #pagination_articles
174
-	$debut = 'debut' . $nom; // 'debut_articles'
175
-
176
-	// n'afficher l'ancre qu'une fois
177
-	$bloc_ancre = isset($ancres[$ancre]) ? '' : ($ancres[$ancre] = "<a id='" . $ancre . "' class='pagination_ancre'></a>");
178
-	// liste = false : on ne veut que l'ancre
179
-	if (!$liste) {
180
-		return $ancres[$ancre];
181
-	}
182
-
183
-	$self = (empty($env['self']) ? self() : $env['self']);
184
-	$pagination = [
185
-		'debut' => $debut,
186
-		'url' => parametre_url($self, 'fragment', ''), // nettoyer l'id ahah eventuel
187
-		'total' => $total,
188
-		'position' => (int) $position,
189
-		'pas' => $pas,
190
-		'nombre_pages' => floor(($total - 1) / $pas) + 1,
191
-		'page_courante' => floor((int) $position / $pas) + 1,
192
-		'ancre' => $ancre,
193
-		'bloc_ancre' => $bloc_ancre
194
-	];
195
-	if (is_array($env)) {
196
-		$pagination = array_merge($env, $pagination);
197
-	}
198
-
199
-	// Pas de pagination
200
-	if ($pagination['nombre_pages'] <= 1) {
201
-		return '';
202
-	}
203
-
204
-	if ($modele) {
205
-		$pagination['type_pagination'] = $modele;
206
-		$modele = trouver_fond('pagination_' . $modele, 'modeles') ? '_' . $modele : '';
207
-	}
208
-
209
-	if (!defined('_PAGINATION_NOMBRE_LIENS_MAX')) {
210
-		define('_PAGINATION_NOMBRE_LIENS_MAX', 10);
211
-	}
212
-	if (!defined('_PAGINATION_NOMBRE_LIENS_MAX_ECRIRE')) {
213
-		define('_PAGINATION_NOMBRE_LIENS_MAX_ECRIRE', 5);
214
-	}
215
-
216
-
217
-	return recuperer_fond("modeles/pagination$modele", $pagination, ['trim' => true], $connect);
169
+    static $ancres = [];
170
+    if ($pas < 1) {
171
+        return '';
172
+    }
173
+    $ancre = 'pagination' . $nom; // #pagination_articles
174
+    $debut = 'debut' . $nom; // 'debut_articles'
175
+
176
+    // n'afficher l'ancre qu'une fois
177
+    $bloc_ancre = isset($ancres[$ancre]) ? '' : ($ancres[$ancre] = "<a id='" . $ancre . "' class='pagination_ancre'></a>");
178
+    // liste = false : on ne veut que l'ancre
179
+    if (!$liste) {
180
+        return $ancres[$ancre];
181
+    }
182
+
183
+    $self = (empty($env['self']) ? self() : $env['self']);
184
+    $pagination = [
185
+        'debut' => $debut,
186
+        'url' => parametre_url($self, 'fragment', ''), // nettoyer l'id ahah eventuel
187
+        'total' => $total,
188
+        'position' => (int) $position,
189
+        'pas' => $pas,
190
+        'nombre_pages' => floor(($total - 1) / $pas) + 1,
191
+        'page_courante' => floor((int) $position / $pas) + 1,
192
+        'ancre' => $ancre,
193
+        'bloc_ancre' => $bloc_ancre
194
+    ];
195
+    if (is_array($env)) {
196
+        $pagination = array_merge($env, $pagination);
197
+    }
198
+
199
+    // Pas de pagination
200
+    if ($pagination['nombre_pages'] <= 1) {
201
+        return '';
202
+    }
203
+
204
+    if ($modele) {
205
+        $pagination['type_pagination'] = $modele;
206
+        $modele = trouver_fond('pagination_' . $modele, 'modeles') ? '_' . $modele : '';
207
+    }
208
+
209
+    if (!defined('_PAGINATION_NOMBRE_LIENS_MAX')) {
210
+        define('_PAGINATION_NOMBRE_LIENS_MAX', 10);
211
+    }
212
+    if (!defined('_PAGINATION_NOMBRE_LIENS_MAX_ECRIRE')) {
213
+        define('_PAGINATION_NOMBRE_LIENS_MAX_ECRIRE', 5);
214
+    }
215
+
216
+
217
+    return recuperer_fond("modeles/pagination$modele", $pagination, ['trim' => true], $connect);
218 218
 }
219 219
 
220 220
 
@@ -233,38 +233,38 @@  discard block
 block discarded – undo
233 233
  *     Liste (première page, dernière page).
234 234
  **/
235 235
 function filtre_bornes_pagination_dist($courante, $nombre, $max = 10) {
236
-	if ($max <= 0 || $max >= $nombre) {
237
-		return [1, $nombre];
238
-	}
239
-	if ($max <= 1) {
240
-		return [$courante, $courante];
241
-	}
242
-
243
-	$premiere = max(1, $courante - floor(($max - 1) / 2));
244
-	$derniere = min($nombre, $premiere + $max - 2);
245
-	$premiere = $derniere == $nombre ? $derniere - $max + 1 : $premiere;
246
-
247
-	return [$premiere, $derniere];
236
+    if ($max <= 0 || $max >= $nombre) {
237
+        return [1, $nombre];
238
+    }
239
+    if ($max <= 1) {
240
+        return [$courante, $courante];
241
+    }
242
+
243
+    $premiere = max(1, $courante - floor(($max - 1) / 2));
244
+    $derniere = min($nombre, $premiere + $max - 2);
245
+    $premiere = $derniere == $nombre ? $derniere - $max + 1 : $premiere;
246
+
247
+    return [$premiere, $derniere];
248 248
 }
249 249
 
250 250
 function filtre_pagination_affiche_texte_lien_page_dist($type_pagination, $numero_page, $rang_item) {
251
-	if ($numero_page === 'tous') {
252
-		return '&#8734;';
253
-	}
254
-	if ($numero_page === 'prev') {
255
-		return '&lt;';
256
-	}
257
-	if ($numero_page === 'next') {
258
-		return '&gt;';
259
-	}
260
-
261
-	return match ($type_pagination) {
262
-		'resultats' => $rang_item + 1, // 1 11 21 31...
263
-		'naturel' => $rang_item ?: 1, // 1 10 20 30...
264
-		'rang' => $rang_item, // 0 10 20 30...
265
-		'page', 'prive' => $numero_page, // 1 2 3 4 5...
266
-		default => $numero_page, // 1 2 3 4 5...
267
-	};
251
+    if ($numero_page === 'tous') {
252
+        return '&#8734;';
253
+    }
254
+    if ($numero_page === 'prev') {
255
+        return '&lt;';
256
+    }
257
+    if ($numero_page === 'next') {
258
+        return '&gt;';
259
+    }
260
+
261
+    return match ($type_pagination) {
262
+        'resultats' => $rang_item + 1, // 1 11 21 31...
263
+        'naturel' => $rang_item ?: 1, // 1 10 20 30...
264
+        'rang' => $rang_item, // 0 10 20 30...
265
+        'page', 'prive' => $numero_page, // 1 2 3 4 5...
266
+        default => $numero_page, // 1 2 3 4 5...
267
+    };
268 268
 }
269 269
 
270 270
 /**
@@ -277,15 +277,15 @@  discard block
 block discarded – undo
277 277
  **/
278 278
 function lister_objets_avec_logos($type) {
279 279
 
280
-	$objet = objet_type($type);
281
-	$ids = sql_allfetsel('L.id_objet', 'spip_documents AS D JOIN spip_documents_liens AS L ON L.id_document=D.id_document', 'D.mode=' . sql_quote('logoon') . ' AND L.objet=' . sql_quote($objet));
282
-	if ($ids) {
283
-		$ids = array_column($ids, 'id_objet');
284
-		return implode(',', $ids);
285
-	}
286
-	else {
287
-		return '0';
288
-	}
280
+    $objet = objet_type($type);
281
+    $ids = sql_allfetsel('L.id_objet', 'spip_documents AS D JOIN spip_documents_liens AS L ON L.id_document=D.id_document', 'D.mode=' . sql_quote('logoon') . ' AND L.objet=' . sql_quote($objet));
282
+    if ($ids) {
283
+        $ids = array_column($ids, 'id_objet');
284
+        return implode(',', $ids);
285
+    }
286
+    else {
287
+        return '0';
288
+    }
289 289
 }
290 290
 
291 291
 
@@ -301,14 +301,14 @@  discard block
 block discarded – undo
301 301
  *     Code HTML des notes
302 302
  **/
303 303
 function calculer_notes() {
304
-	$r = '';
305
-	if ($notes = charger_fonction('notes', 'inc', true)) {
306
-		$r = $notes([]);
307
-		$notes('', 'depiler');
308
-		$notes('', 'empiler');
309
-	}
310
-
311
-	return $r;
304
+    $r = '';
305
+    if ($notes = charger_fonction('notes', 'inc', true)) {
306
+        $r = $notes([]);
307
+        $notes('', 'depiler');
308
+        $notes('', 'empiler');
309
+    }
310
+
311
+    return $r;
312 312
 }
313 313
 
314 314
 
@@ -325,10 +325,10 @@  discard block
 block discarded – undo
325 325
  * @return string
326 326
  */
327 327
 function retrouver_rang_lien($objet_source, $ids, $objet_lie, $idl, $objet_lien) {
328
-	$res = lister_objets_liens($objet_source, $objet_lie, $idl, $objet_lien);
329
-	$res = array_column($res, 'rang_lien', $objet_source);
328
+    $res = lister_objets_liens($objet_source, $objet_lie, $idl, $objet_lien);
329
+    $res = array_column($res, 'rang_lien', $objet_source);
330 330
 
331
-	return ($res[$ids] ?? '');
331
+    return ($res[$ids] ?? '');
332 332
 }
333 333
 
334 334
 
@@ -345,19 +345,19 @@  discard block
 block discarded – undo
345 345
  * @private
346 346
  */
347 347
 function lister_objets_liens($objet_source, $objet, $id_objet, $objet_lien) {
348
-	static $liens = [];
349
-	if (!isset($liens["$objet_source-$objet-$id_objet-$objet_lien"])) {
350
-		include_spip('action/editer_liens');
351
-		// quand $objet == $objet_lien == $objet_source on reste sur le cas par defaut de $objet_lien == $objet_source
352
-		if ($objet_lien == $objet && $objet_lien !== $objet_source) {
353
-			$res = objet_trouver_liens([$objet => $id_objet], [$objet_source => '*']);
354
-		} else {
355
-			$res = objet_trouver_liens([$objet_source => '*'], [$objet => $id_objet]);
356
-		}
357
-
358
-		$liens["$objet_source-$objet-$id_objet-$objet_lien"] = $res;
359
-	}
360
-	return $liens["$objet_source-$objet-$id_objet-$objet_lien"];
348
+    static $liens = [];
349
+    if (!isset($liens["$objet_source-$objet-$id_objet-$objet_lien"])) {
350
+        include_spip('action/editer_liens');
351
+        // quand $objet == $objet_lien == $objet_source on reste sur le cas par defaut de $objet_lien == $objet_source
352
+        if ($objet_lien == $objet && $objet_lien !== $objet_source) {
353
+            $res = objet_trouver_liens([$objet => $id_objet], [$objet_source => '*']);
354
+        } else {
355
+            $res = objet_trouver_liens([$objet_source => '*'], [$objet => $id_objet]);
356
+        }
357
+
358
+        $liens["$objet_source-$objet-$id_objet-$objet_lien"] = $res;
359
+    }
360
+    return $liens["$objet_source-$objet-$id_objet-$objet_lien"];
361 361
 }
362 362
 
363 363
 /**
@@ -371,24 +371,24 @@  discard block
 block discarded – undo
371 371
  * @return int|string
372 372
  */
373 373
 function calculer_rang_smart($titre, $objet_source, $id, $env) {
374
-	// Cas du #RANG utilisé dans #FORMULAIRE_EDITER_LIENS -> attraper le rang du lien
375
-	// permet de voir le rang du lien si il y en a un en base, meme avant un squelette xxxx-lies.html ne gerant pas les liens
376
-	if (
377
-		isset($env['form']) && $env['form']
378
-		&& isset($env['_objet_lien']) && $env['_objet_lien']
379
-		&& (function_exists('lien_triables') || include_spip('action/editer_liens'))
380
-		&& ($r = objet_associable($env['_objet_lien']))
381
-		&& ([$p, $table_lien] = $r)
382
-		&& lien_triables($table_lien)
383
-		&& isset($env['objet']) && $env['objet']
384
-		&& isset($env['id_objet']) && $env['id_objet']
385
-		&& $objet_source
386
-		&& ($id = (int) $id)
387
-	) {
388
-		$rang = retrouver_rang_lien($objet_source, $id, $env['objet'], $env['id_objet'], $env['_objet_lien']);
389
-		return ($rang ?: '');
390
-	}
391
-	return recuperer_numero($titre);
374
+    // Cas du #RANG utilisé dans #FORMULAIRE_EDITER_LIENS -> attraper le rang du lien
375
+    // permet de voir le rang du lien si il y en a un en base, meme avant un squelette xxxx-lies.html ne gerant pas les liens
376
+    if (
377
+        isset($env['form']) && $env['form']
378
+        && isset($env['_objet_lien']) && $env['_objet_lien']
379
+        && (function_exists('lien_triables') || include_spip('action/editer_liens'))
380
+        && ($r = objet_associable($env['_objet_lien']))
381
+        && ([$p, $table_lien] = $r)
382
+        && lien_triables($table_lien)
383
+        && isset($env['objet']) && $env['objet']
384
+        && isset($env['id_objet']) && $env['id_objet']
385
+        && $objet_source
386
+        && ($id = (int) $id)
387
+    ) {
388
+        $rang = retrouver_rang_lien($objet_source, $id, $env['objet'], $env['id_objet'], $env['_objet_lien']);
389
+        return ($rang ?: '');
390
+    }
391
+    return recuperer_numero($titre);
392 392
 }
393 393
 
394 394
 /**
@@ -417,78 +417,78 @@  discard block
 block discarded – undo
417 417
  */
418 418
 function calculer_balise_tri(string $champ_ou_sens, string $libelle, string $classe, string $tri_nom, string $tri_champ, string $tri_sens, $liste_tri_sens_defaut, string $nom_pagination = ''): string {
419 419
 
420
-	$url = self('&');
421
-	$tri_sens = (int) $tri_sens;
422
-	$alias_sens = [
423
-		'<' => -1,
424
-		'>' => 1,
425
-		'inverse' => -1,
426
-	];
427
-
428
-	// Normaliser la liste des sens de tri par défaut
429
-	// On ajoute un jocker pour les champs non présents dans la liste
430
-	// avec la valeur du 1er item de la liste, idem critère {tri}
431
-	if (is_array($liste_tri_sens_defaut)) {
432
-		$liste_tri_sens_defaut['*'] = array_values($liste_tri_sens_defaut)[0];
433
-	} else {
434
-		$liste_tri_sens_defaut = [
435
-			'*' => (int) ($alias_sens[$liste_tri_sens_defaut] ?? $liste_tri_sens_defaut),
436
-		];
437
-	}
438
-
439
-	// Les sens de tri actuel et nouveau :
440
-	// Soit c'est un sens fixe donné en paramètre (< ou >)
441
-	$is_sens_fixe = array_key_exists($champ_ou_sens, $alias_sens);
442
-	if ($is_sens_fixe) {
443
-		$tri_sens_actuel = $tri_sens;
444
-		$tri_sens_nouveau = $alias_sens[$champ_ou_sens];
445
-	// Soit c'est le champ utilisé actuellement pour le tri → on inverse le sens
446
-	} elseif ($champ_ou_sens === $tri_champ) {
447
-		$tri_sens_actuel = $tri_sens;
448
-		$tri_sens_nouveau = $tri_sens * -1;
449
-	// Sinon c'est un nouveau champ, et on prend son tri par défaut
450
-	} else {
451
-		$tri_sens_actuel = $tri_sens_nouveau = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']);
452
-	}
453
-
454
-	// URL : ajouter le champ sur lequel porte le tri
455
-	if (!$is_sens_fixe) {
456
-		$param_tri = "tri$tri_nom";
457
-		$url = parametre_url($url, $param_tri, $champ_ou_sens);
458
-	}
459
-
460
-	// URL : n'ajouter le sens de tri que si nécessaire,
461
-	// c.à.d différent du sens par défaut pour le champ
462
-	$param_sens = "sens$tri_nom";
463
-	$tri_sens_defaut_champ = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']);
464
-	if ($tri_sens_nouveau !== $tri_sens_defaut_champ) {
465
-		$url = parametre_url($url, $param_sens, $tri_sens_nouveau);
466
-	} else {
467
-		$url = parametre_url($url, $param_sens, '');
468
-	}
469
-
470
-	// Drapeau pour garder en session ?
471
-	$param_memo = ($is_sens_fixe ? $param_sens : $param_tri);
472
-	$url = parametre_url($url, 'var_memotri', str_starts_with($tri_nom, 'session') ? $param_memo : '');
473
-
474
-	// Classes : on indique le sens de tri et l'item exposé
475
-	if (!$is_sens_fixe) {
476
-		$classe .= ' item-tri item-tri_' . ($tri_sens_actuel === 1 ? 'asc' : 'desc');
477
-	}
478
-	if ($champ_ou_sens === $tri_champ) {
479
-		$classe .= ' item-tri_actif';
480
-	}
481
-
482
-	// Si on n'est pas en mode "Tout afficher" de la pagination
483
-	if ($nom_pagination && parametre_url($url, 'debut' . $nom_pagination) !== '-1') {
484
-		// reset la pagination quand on change de mode ou de sens de tri
485
-		$url = parametre_url($url, 'debut' . $nom_pagination, '');
486
-	}
487
-
488
-	// Lien
489
-	$balise = lien_ou_expose($url, $libelle, false, $classe);
490
-
491
-	return $balise;
420
+    $url = self('&');
421
+    $tri_sens = (int) $tri_sens;
422
+    $alias_sens = [
423
+        '<' => -1,
424
+        '>' => 1,
425
+        'inverse' => -1,
426
+    ];
427
+
428
+    // Normaliser la liste des sens de tri par défaut
429
+    // On ajoute un jocker pour les champs non présents dans la liste
430
+    // avec la valeur du 1er item de la liste, idem critère {tri}
431
+    if (is_array($liste_tri_sens_defaut)) {
432
+        $liste_tri_sens_defaut['*'] = array_values($liste_tri_sens_defaut)[0];
433
+    } else {
434
+        $liste_tri_sens_defaut = [
435
+            '*' => (int) ($alias_sens[$liste_tri_sens_defaut] ?? $liste_tri_sens_defaut),
436
+        ];
437
+    }
438
+
439
+    // Les sens de tri actuel et nouveau :
440
+    // Soit c'est un sens fixe donné en paramètre (< ou >)
441
+    $is_sens_fixe = array_key_exists($champ_ou_sens, $alias_sens);
442
+    if ($is_sens_fixe) {
443
+        $tri_sens_actuel = $tri_sens;
444
+        $tri_sens_nouveau = $alias_sens[$champ_ou_sens];
445
+    // Soit c'est le champ utilisé actuellement pour le tri → on inverse le sens
446
+    } elseif ($champ_ou_sens === $tri_champ) {
447
+        $tri_sens_actuel = $tri_sens;
448
+        $tri_sens_nouveau = $tri_sens * -1;
449
+    // Sinon c'est un nouveau champ, et on prend son tri par défaut
450
+    } else {
451
+        $tri_sens_actuel = $tri_sens_nouveau = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']);
452
+    }
453
+
454
+    // URL : ajouter le champ sur lequel porte le tri
455
+    if (!$is_sens_fixe) {
456
+        $param_tri = "tri$tri_nom";
457
+        $url = parametre_url($url, $param_tri, $champ_ou_sens);
458
+    }
459
+
460
+    // URL : n'ajouter le sens de tri que si nécessaire,
461
+    // c.à.d différent du sens par défaut pour le champ
462
+    $param_sens = "sens$tri_nom";
463
+    $tri_sens_defaut_champ = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']);
464
+    if ($tri_sens_nouveau !== $tri_sens_defaut_champ) {
465
+        $url = parametre_url($url, $param_sens, $tri_sens_nouveau);
466
+    } else {
467
+        $url = parametre_url($url, $param_sens, '');
468
+    }
469
+
470
+    // Drapeau pour garder en session ?
471
+    $param_memo = ($is_sens_fixe ? $param_sens : $param_tri);
472
+    $url = parametre_url($url, 'var_memotri', str_starts_with($tri_nom, 'session') ? $param_memo : '');
473
+
474
+    // Classes : on indique le sens de tri et l'item exposé
475
+    if (!$is_sens_fixe) {
476
+        $classe .= ' item-tri item-tri_' . ($tri_sens_actuel === 1 ? 'asc' : 'desc');
477
+    }
478
+    if ($champ_ou_sens === $tri_champ) {
479
+        $classe .= ' item-tri_actif';
480
+    }
481
+
482
+    // Si on n'est pas en mode "Tout afficher" de la pagination
483
+    if ($nom_pagination && parametre_url($url, 'debut' . $nom_pagination) !== '-1') {
484
+        // reset la pagination quand on change de mode ou de sens de tri
485
+        $url = parametre_url($url, 'debut' . $nom_pagination, '');
486
+    }
487
+
488
+    // Lien
489
+    $balise = lien_ou_expose($url, $libelle, false, $classe);
490
+
491
+    return $balise;
492 492
 }
493 493
 
494 494
 
@@ -504,7 +504,7 @@  discard block
 block discarded – undo
504 504
  * @return string
505 505
  */
506 506
 function tri_protege_champ($t) {
507
-	return preg_replace(',[^\s\w.+\[\]],', '', $t);
507
+    return preg_replace(',[^\s\w.+\[\]],', '', $t);
508 508
 }
509 509
 
510 510
 /**
@@ -517,39 +517,39 @@  discard block
 block discarded – undo
517 517
  * @return string
518 518
  */
519 519
 function tri_champ_order($t, $from = null, $senstri = '') {
520
-	if (str_starts_with($t, 'multi ')) {
521
-		return 'multi' . $senstri;
522
-	}
523
-
524
-	$champ = $t;
525
-
526
-	$prefixe = '';
527
-	foreach (['num ', 'sinum '] as $p) {
528
-		if (str_starts_with($t, $p)) {
529
-			$champ = substr($t, strlen($p));
530
-			$prefixe = $p;
531
-		}
532
-	}
533
-
534
-	// enlever les autres espaces non evacues par tri_protege_champ
535
-	$champ = preg_replace(',\s,', '', $champ);
536
-
537
-	if (is_array($from)) {
538
-		$trouver_table = charger_fonction('trouver_table', 'base');
539
-		foreach ($from as $idt => $table_sql) {
540
-			if (
541
-				($desc = $trouver_table($table_sql)) && isset($desc['field'][$champ])
542
-			) {
543
-				$champ = "$idt.$champ";
544
-				break;
545
-			}
546
-		}
547
-	}
548
-	return match ($prefixe) {
549
-		'num ' => "CASE( 0+$champ ) WHEN 0 THEN 1 ELSE 0 END{$senstri}, 0+$champ{$senstri}",
550
-		'sinum ' => "CASE( 0+$champ ) WHEN 0 THEN 1 ELSE 0 END{$senstri}",
551
-		default => $champ . $senstri,
552
-	};
520
+    if (str_starts_with($t, 'multi ')) {
521
+        return 'multi' . $senstri;
522
+    }
523
+
524
+    $champ = $t;
525
+
526
+    $prefixe = '';
527
+    foreach (['num ', 'sinum '] as $p) {
528
+        if (str_starts_with($t, $p)) {
529
+            $champ = substr($t, strlen($p));
530
+            $prefixe = $p;
531
+        }
532
+    }
533
+
534
+    // enlever les autres espaces non evacues par tri_protege_champ
535
+    $champ = preg_replace(',\s,', '', $champ);
536
+
537
+    if (is_array($from)) {
538
+        $trouver_table = charger_fonction('trouver_table', 'base');
539
+        foreach ($from as $idt => $table_sql) {
540
+            if (
541
+                ($desc = $trouver_table($table_sql)) && isset($desc['field'][$champ])
542
+            ) {
543
+                $champ = "$idt.$champ";
544
+                break;
545
+            }
546
+        }
547
+    }
548
+    return match ($prefixe) {
549
+        'num ' => "CASE( 0+$champ ) WHEN 0 THEN 1 ELSE 0 END{$senstri}, 0+$champ{$senstri}",
550
+        'sinum ' => "CASE( 0+$champ ) WHEN 0 THEN 1 ELSE 0 END{$senstri}",
551
+        default => $champ . $senstri,
552
+    };
553 553
 }
554 554
 
555 555
 /**
@@ -563,17 +563,17 @@  discard block
 block discarded – undo
563 563
  * @return string
564 564
  */
565 565
 function tri_champ_select($t) {
566
-	if (str_starts_with($t, 'multi ')) {
567
-		$t = substr($t, 6);
568
-		$t = preg_replace(',\s,', '', $t);
566
+    if (str_starts_with($t, 'multi ')) {
567
+        $t = substr($t, 6);
568
+        $t = preg_replace(',\s,', '', $t);
569 569
 
570
-		return sql_multi($t, $GLOBALS['spip_lang']);
571
-	}
572
-	if (trim($t) == 'hasard') {
573
-		return 'rand() AS hasard';
574
-	}
570
+        return sql_multi($t, $GLOBALS['spip_lang']);
571
+    }
572
+    if (trim($t) == 'hasard') {
573
+        return 'rand() AS hasard';
574
+    }
575 575
 
576
-	return "''";
576
+    return "''";
577 577
 }
578 578
 
579 579
 /**
@@ -585,15 +585,15 @@  discard block
 block discarded – undo
585 585
  * @return string
586 586
  */
587 587
 function formate_liste_critere_par_ordre_liste($valeurs, $serveur = '') {
588
-	if (!is_array($valeurs)) {
589
-		return '';
590
-	}
591
-	$f = sql_serveur('quote', $serveur, true);
592
-	if (!is_string($f) || !$f) {
593
-		return '';
594
-	}
595
-
596
-	return implode(',', array_map($f, array_unique($valeurs)));
588
+    if (!is_array($valeurs)) {
589
+        return '';
590
+    }
591
+    $f = sql_serveur('quote', $serveur, true);
592
+    if (!is_string($f) || !$f) {
593
+        return '';
594
+    }
595
+
596
+    return implode(',', array_map($f, array_unique($valeurs)));
597 597
 }
598 598
 
599 599
 /**
@@ -616,22 +616,22 @@  discard block
 block discarded – undo
616 616
  *     Valeur $defaut sinon.
617 617
  **/
618 618
 function appliquer_filtre_sinon($arg, $filtre, $args, mixed $defaut = '') {
619
-	// Si c'est un filtre d'image, on utilise image_filtrer()
620
-	// Attention : les 2 premiers arguments sont inversés dans ce cas
621
-	if (trouver_filtre_matrice($filtre) && str_starts_with($filtre, 'image_')) {
622
-		include_spip('inc/filtres_images_lib_mini');
623
-		$args[1] = $args[0];
624
-		$args[0] = $filtre;
625
-		return image_graver(image_filtrer($args));
626
-	}
627
-
628
-	$f = chercher_filtre($filtre);
629
-	if (!$f) {
630
-		return $defaut;
631
-	}
632
-	array_shift($args); // enlever $arg
633
-	array_shift($args); // enlever $filtre
634
-	return $f($arg, ...$args);
619
+    // Si c'est un filtre d'image, on utilise image_filtrer()
620
+    // Attention : les 2 premiers arguments sont inversés dans ce cas
621
+    if (trouver_filtre_matrice($filtre) && str_starts_with($filtre, 'image_')) {
622
+        include_spip('inc/filtres_images_lib_mini');
623
+        $args[1] = $args[0];
624
+        $args[0] = $filtre;
625
+        return image_graver(image_filtrer($args));
626
+    }
627
+
628
+    $f = chercher_filtre($filtre);
629
+    if (!$f) {
630
+        return $defaut;
631
+    }
632
+    array_shift($args); // enlever $arg
633
+    array_shift($args); // enlever $filtre
634
+    return $f($arg, ...$args);
635 635
 }
636 636
 
637 637
 /**
@@ -641,30 +641,30 @@  discard block
 block discarded – undo
641 641
  * @return string
642 642
  */
643 643
 function filtre_styles_inline_page_login_pass_dist(&$Pile, ...$dummy) {
644
-	$styles = '';
645
-	include_spip('inc/config');
646
-	if ($couleur = lire_config('couleur_login')) {
647
-		include_spip('inc/filtres_images_mini');
648
-		$hs = couleur_hex_to_hsl($couleur, 'h, s');
649
-		$l = couleur_hex_to_hsl($couleur, 'l');
650
-		$styles .= ":root {--spip-login-color-theme--hs: {$hs};--spip-login-color-theme--l: {$l};}\n";
651
-	}
652
-	$logo_bg = _DIR_IMG . 'spip_fond_login.jpg';
653
-	if (file_exists($logo_bg)) {
654
-		include_spip('inc/filtres_images_mini');
655
-		$logo_mini = image_reduire($logo_bg, 64, 64);
656
-		$logo_mini = extraire_attribut($logo_mini, 'src');
657
-		$embarque_fichier = charger_filtre('embarque_fichier');
658
-		$logo_mini = $embarque_fichier($logo_mini);
659
-		$logo_bg = timestamp($logo_bg);
660
-		$styles .= ".page_login, .page_spip_pass {background-image:url($logo_bg), url($logo_mini);}\n";
661
-		$Pile[0]['body_class'] = 'fond_image';
662
-	}
663
-	else {
664
-		$Pile[0]['body_class'] = 'sans_fond';
665
-	}
666
-	if ($styles) {
667
-		$styles = "<style type='text/css'>$styles</style>";
668
-	}
669
-	return $styles;
644
+    $styles = '';
645
+    include_spip('inc/config');
646
+    if ($couleur = lire_config('couleur_login')) {
647
+        include_spip('inc/filtres_images_mini');
648
+        $hs = couleur_hex_to_hsl($couleur, 'h, s');
649
+        $l = couleur_hex_to_hsl($couleur, 'l');
650
+        $styles .= ":root {--spip-login-color-theme--hs: {$hs};--spip-login-color-theme--l: {$l};}\n";
651
+    }
652
+    $logo_bg = _DIR_IMG . 'spip_fond_login.jpg';
653
+    if (file_exists($logo_bg)) {
654
+        include_spip('inc/filtres_images_mini');
655
+        $logo_mini = image_reduire($logo_bg, 64, 64);
656
+        $logo_mini = extraire_attribut($logo_mini, 'src');
657
+        $embarque_fichier = charger_filtre('embarque_fichier');
658
+        $logo_mini = $embarque_fichier($logo_mini);
659
+        $logo_bg = timestamp($logo_bg);
660
+        $styles .= ".page_login, .page_spip_pass {background-image:url($logo_bg), url($logo_mini);}\n";
661
+        $Pile[0]['body_class'] = 'fond_image';
662
+    }
663
+    else {
664
+        $Pile[0]['body_class'] = 'sans_fond';
665
+    }
666
+    if ($styles) {
667
+        $styles = "<style type='text/css'>$styles</style>";
668
+    }
669
+    return $styles;
670 670
 }
Please login to merge, or discard this patch.
ecrire/public/balises.php 1 patch
Indentation   +943 added lines, -943 removed lines patch added patch discarded remove patch
@@ -27,7 +27,7 @@  discard block
 block discarded – undo
27 27
  **/
28 28
 
29 29
 if (!defined('_ECRIRE_INC_VERSION')) {
30
-	return;
30
+    return;
31 31
 }
32 32
 
33 33
 /**
@@ -47,16 +47,16 @@  discard block
 block discarded – undo
47 47
  *     Code PHP si cet argument est présent, sinon null
48 48
  **/
49 49
 function interprete_argument_balise(int $n, Champ $p): ?string {
50
-	if (($p->param) && (!$p->param[0][0]) && ((is_countable($p->param[0]) ? count($p->param[0]) : 0) > $n)) {
51
-		return calculer_liste(
52
-			$p->param[0][$n],
53
-			$p->descr,
54
-			$p->boucles,
55
-			$p->id_boucle
56
-		);
57
-	}
50
+    if (($p->param) && (!$p->param[0][0]) && ((is_countable($p->param[0]) ? count($p->param[0]) : 0) > $n)) {
51
+        return calculer_liste(
52
+            $p->param[0][$n],
53
+            $p->descr,
54
+            $p->boucles,
55
+            $p->id_boucle
56
+        );
57
+    }
58 58
 
59
-	return null;
59
+    return null;
60 60
 }
61 61
 
62 62
 
@@ -76,10 +76,10 @@  discard block
 block discarded – undo
76 76
  *     Pile complétée par le code à générer
77 77
  **/
78 78
 function balise_NOM_SITE_SPIP_dist($p) {
79
-	$p->code = "\$GLOBALS['meta']['nom_site']";
79
+    $p->code = "\$GLOBALS['meta']['nom_site']";
80 80
 
81
-	#$p->interdire_scripts = true;
82
-	return $p;
81
+    #$p->interdire_scripts = true;
82
+    return $p;
83 83
 }
84 84
 
85 85
 /**
@@ -95,10 +95,10 @@  discard block
 block discarded – undo
95 95
  *     Pile complétée par le code à générer
96 96
  **/
97 97
 function balise_EMAIL_WEBMASTER_dist($p) {
98
-	$p->code = "\$GLOBALS['meta']['email_webmaster']";
98
+    $p->code = "\$GLOBALS['meta']['email_webmaster']";
99 99
 
100
-	#$p->interdire_scripts = true;
101
-	return $p;
100
+    #$p->interdire_scripts = true;
101
+    return $p;
102 102
 }
103 103
 
104 104
 /**
@@ -114,10 +114,10 @@  discard block
 block discarded – undo
114 114
  *     Pile complétée par le code à générer
115 115
  **/
116 116
 function balise_DESCRIPTIF_SITE_SPIP_dist($p) {
117
-	$p->code = "\$GLOBALS['meta']['descriptif_site']";
117
+    $p->code = "\$GLOBALS['meta']['descriptif_site']";
118 118
 
119
-	#$p->interdire_scripts = true;
120
-	return $p;
119
+    #$p->interdire_scripts = true;
120
+    return $p;
121 121
 }
122 122
 
123 123
 
@@ -138,10 +138,10 @@  discard block
 block discarded – undo
138 138
  *     Pile complétée par le code à générer
139 139
  **/
140 140
 function balise_CHARSET_dist($p) {
141
-	$p->code = "\$GLOBALS['meta']['charset']";
141
+    $p->code = "\$GLOBALS['meta']['charset']";
142 142
 
143
-	#$p->interdire_scripts = true;
144
-	return $p;
143
+    #$p->interdire_scripts = true;
144
+    return $p;
145 145
 }
146 146
 
147 147
 /**
@@ -166,11 +166,11 @@  discard block
 block discarded – undo
166 166
  *     Pile complétée par le code à générer
167 167
  **/
168 168
 function balise_LANG_LEFT_dist($p) {
169
-	$_lang = champ_sql('lang', $p);
170
-	$p->code = "lang_dir($_lang, 'left','right')";
171
-	$p->interdire_scripts = false;
169
+    $_lang = champ_sql('lang', $p);
170
+    $p->code = "lang_dir($_lang, 'left','right')";
171
+    $p->interdire_scripts = false;
172 172
 
173
-	return $p;
173
+    return $p;
174 174
 }
175 175
 
176 176
 /**
@@ -190,11 +190,11 @@  discard block
 block discarded – undo
190 190
  *     Pile complétée par le code à générer
191 191
  **/
192 192
 function balise_LANG_RIGHT_dist($p) {
193
-	$_lang = champ_sql('lang', $p);
194
-	$p->code = "lang_dir($_lang, 'right','left')";
195
-	$p->interdire_scripts = false;
193
+    $_lang = champ_sql('lang', $p);
194
+    $p->code = "lang_dir($_lang, 'right','left')";
195
+    $p->interdire_scripts = false;
196 196
 
197
-	return $p;
197
+    return $p;
198 198
 }
199 199
 
200 200
 /**
@@ -219,11 +219,11 @@  discard block
 block discarded – undo
219 219
  *     Pile complétée par le code à générer
220 220
  **/
221 221
 function balise_LANG_DIR_dist($p) {
222
-	$_lang = champ_sql('lang', $p);
223
-	$p->code = "lang_dir($_lang, 'ltr','rtl')";
224
-	$p->interdire_scripts = false;
222
+    $_lang = champ_sql('lang', $p);
223
+    $p->code = "lang_dir($_lang, 'ltr','rtl')";
224
+    $p->interdire_scripts = false;
225 225
 
226
-	return $p;
226
+    return $p;
227 227
 }
228 228
 
229 229
 
@@ -240,10 +240,10 @@  discard block
 block discarded – undo
240 240
  *     Pile complétée par le code à générer
241 241
  **/
242 242
 function balise_PUCE_dist($p) {
243
-	$p->code = 'definir_puce()';
244
-	$p->interdire_scripts = false;
243
+    $p->code = 'definir_puce()';
244
+    $p->interdire_scripts = false;
245 245
 
246
-	return $p;
246
+    return $p;
247 247
 }
248 248
 
249 249
 
@@ -267,9 +267,9 @@  discard block
 block discarded – undo
267 267
  *     Pile completée du code PHP d'exécution de la balise
268 268
  */
269 269
 function balise_DATE_dist($p) {
270
-	$p->code = champ_sql('date', $p);
270
+    $p->code = champ_sql('date', $p);
271 271
 
272
-	return $p;
272
+    return $p;
273 273
 }
274 274
 
275 275
 
@@ -289,10 +289,10 @@  discard block
 block discarded – undo
289 289
  *     Pile completée du code PHP d'exécution de la balise
290 290
  */
291 291
 function balise_DATE_REDAC_dist($p) {
292
-	$p->code = champ_sql('date_redac', $p);
293
-	$p->interdire_scripts = false;
292
+    $p->code = champ_sql('date_redac', $p);
293
+    $p->interdire_scripts = false;
294 294
 
295
-	return $p;
295
+    return $p;
296 296
 }
297 297
 
298 298
 /**
@@ -311,10 +311,10 @@  discard block
 block discarded – undo
311 311
  *     Pile completée du code PHP d'exécution de la balise
312 312
  */
313 313
 function balise_DATE_MODIF_dist($p) {
314
-	$p->code = champ_sql('date_modif', $p);
315
-	$p->interdire_scripts = false;
314
+    $p->code = champ_sql('date_modif', $p);
315
+    $p->interdire_scripts = false;
316 316
 
317
-	return $p;
317
+    return $p;
318 318
 }
319 319
 
320 320
 /**
@@ -332,13 +332,13 @@  discard block
 block discarded – undo
332 332
  *     Pile completée du code PHP d'exécution de la balise
333 333
  */
334 334
 function balise_DATE_NOUVEAUTES_dist($p) {
335
-	$p->code = "((\$GLOBALS['meta']['quoi_de_neuf'] == 'oui'
335
+    $p->code = "((\$GLOBALS['meta']['quoi_de_neuf'] == 'oui'
336 336
 	AND isset(\$GLOBALS['meta']['dernier_envoi_neuf'])) ?
337 337
 	\$GLOBALS['meta']['dernier_envoi_neuf'] :
338 338
 	\"'0000-00-00'\")";
339
-	$p->interdire_scripts = false;
339
+    $p->interdire_scripts = false;
340 340
 
341
-	return $p;
341
+    return $p;
342 342
 }
343 343
 
344 344
 
@@ -356,11 +356,11 @@  discard block
 block discarded – undo
356 356
  *     Pile completée du code PHP d'exécution de la balise
357 357
  */
358 358
 function balise_DOSSIER_SQUELETTE_dist($p) {
359
-	$code = substr(addslashes(dirname($p->descr['sourcefile'])), strlen(_DIR_RACINE));
360
-	$p->code = "_DIR_RACINE . '$code'" .
361
-		$p->interdire_scripts = false;
359
+    $code = substr(addslashes(dirname($p->descr['sourcefile'])), strlen(_DIR_RACINE));
360
+    $p->code = "_DIR_RACINE . '$code'" .
361
+        $p->interdire_scripts = false;
362 362
 
363
-	return $p;
363
+    return $p;
364 364
 }
365 365
 
366 366
 /**
@@ -375,11 +375,11 @@  discard block
 block discarded – undo
375 375
  *     Pile completée du code PHP d'exécution de la balise
376 376
  */
377 377
 function balise_SQUELETTE_dist($p) {
378
-	$code = addslashes($p->descr['sourcefile']);
379
-	$p->code = "'$code'" .
380
-		$p->interdire_scripts = false;
378
+    $code = addslashes($p->descr['sourcefile']);
379
+    $p->code = "'$code'" .
380
+        $p->interdire_scripts = false;
381 381
 
382
-	return $p;
382
+    return $p;
383 383
 }
384 384
 
385 385
 /**
@@ -398,10 +398,10 @@  discard block
 block discarded – undo
398 398
  *     Pile completée du code PHP d'exécution de la balise
399 399
  */
400 400
 function balise_SPIP_VERSION_dist($p) {
401
-	$p->code = 'spip_version()';
402
-	$p->interdire_scripts = false;
401
+    $p->code = 'spip_version()';
402
+    $p->interdire_scripts = false;
403 403
 
404
-	return $p;
404
+    return $p;
405 405
 }
406 406
 
407 407
 
@@ -427,18 +427,18 @@  discard block
 block discarded – undo
427 427
  *     Pile complétée par le code à générer
428 428
  **/
429 429
 function balise_NOM_SITE_dist($p) {
430
-	if (!$p->etoile) {
431
-		$p->code = 'supprimer_numero(calculer_url(' .
432
-			champ_sql('url_site', $p) . ',' .
433
-			champ_sql('nom_site', $p) .
434
-			", 'titre', \$connect, false))";
435
-	} else {
436
-		$p->code = champ_sql('nom_site', $p);
437
-	}
430
+    if (!$p->etoile) {
431
+        $p->code = 'supprimer_numero(calculer_url(' .
432
+            champ_sql('url_site', $p) . ',' .
433
+            champ_sql('nom_site', $p) .
434
+            ", 'titre', \$connect, false))";
435
+    } else {
436
+        $p->code = champ_sql('nom_site', $p);
437
+    }
438 438
 
439
-	$p->interdire_scripts = true;
439
+    $p->interdire_scripts = true;
440 440
 
441
-	return $p;
441
+    return $p;
442 442
 }
443 443
 
444 444
 
@@ -455,11 +455,11 @@  discard block
 block discarded – undo
455 455
  *     Pile complétée par le code à générer
456 456
  **/
457 457
 function balise_NOTES_dist($p) {
458
-	// Recuperer les notes
459
-	$p->code = 'calculer_notes()';
458
+    // Recuperer les notes
459
+    $p->code = 'calculer_notes()';
460 460
 
461
-	#$p->interdire_scripts = true;
462
-	return $p;
461
+    #$p->interdire_scripts = true;
462
+    return $p;
463 463
 }
464 464
 
465 465
 
@@ -481,10 +481,10 @@  discard block
 block discarded – undo
481 481
  *     Pile complétée par le code à générer
482 482
  **/
483 483
 function balise_RECHERCHE_dist($p) {
484
-	$p->code = 'entites_html(_request("recherche"))';
485
-	$p->interdire_scripts = false;
484
+    $p->code = 'entites_html(_request("recherche"))';
485
+    $p->interdire_scripts = false;
486 486
 
487
-	return $p;
487
+    return $p;
488 488
 }
489 489
 
490 490
 
@@ -502,18 +502,18 @@  discard block
 block discarded – undo
502 502
  *     Pile complétée par le code à générer
503 503
  **/
504 504
 function balise_COMPTEUR_BOUCLE_dist($p) {
505
-	$b = index_boucle_mere($p);
506
-	if ($b === '') {
507
-		$msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
508
-		erreur_squelette($msg, $p);
509
-		return null;
510
-	} else {
511
-		$p->code = "(\$Numrows['$b']['compteur_boucle'] ?? 0)";
512
-		$p->boucles[$b]->cptrows = true;
513
-		$p->interdire_scripts = false;
505
+    $b = index_boucle_mere($p);
506
+    if ($b === '') {
507
+        $msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
508
+        erreur_squelette($msg, $p);
509
+        return null;
510
+    } else {
511
+        $p->code = "(\$Numrows['$b']['compteur_boucle'] ?? 0)";
512
+        $p->boucles[$b]->cptrows = true;
513
+        $p->interdire_scripts = false;
514 514
 
515
-		return $p;
516
-	}
515
+        return $p;
516
+    }
517 517
 }
518 518
 
519 519
 /**
@@ -531,17 +531,17 @@  discard block
 block discarded – undo
531 531
  *     Pile complétée par le code à générer
532 532
  **/
533 533
 function balise_TOTAL_BOUCLE_dist($p) {
534
-	$b = index_boucle_mere($p);
535
-	if ($b === '') {
536
-		$msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
537
-		erreur_squelette($msg, $p);
538
-	} else {
539
-		$p->code = "(\$Numrows['$b']['total'] ?? 0)";
540
-		$p->boucles[$b]->numrows = true;
541
-		$p->interdire_scripts = false;
542
-	}
534
+    $b = index_boucle_mere($p);
535
+    if ($b === '') {
536
+        $msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
537
+        erreur_squelette($msg, $p);
538
+    } else {
539
+        $p->code = "(\$Numrows['$b']['total'] ?? 0)";
540
+        $p->boucles[$b]->numrows = true;
541
+        $p->interdire_scripts = false;
542
+    }
543 543
 
544
-	return $p;
544
+    return $p;
545 545
 }
546 546
 
547 547
 
@@ -561,7 +561,7 @@  discard block
 block discarded – undo
561 561
  *     Pile complétée par le code à générer
562 562
  **/
563 563
 function balise_POINTS_dist($p) {
564
-	return rindex_pile($p, 'points', 'recherche');
564
+    return rindex_pile($p, 'points', 'recherche');
565 565
 }
566 566
 
567 567
 
@@ -582,12 +582,12 @@  discard block
 block discarded – undo
582 582
  *     Pile complétée par le code à générer
583 583
  **/
584 584
 function balise_POPULARITE_ABSOLUE_dist($p) {
585
-	$p->code = 'ceil(' .
586
-		champ_sql('popularite', $p) .
587
-		')';
588
-	$p->interdire_scripts = false;
585
+    $p->code = 'ceil(' .
586
+        champ_sql('popularite', $p) .
587
+        ')';
588
+    $p->interdire_scripts = false;
589 589
 
590
-	return $p;
590
+    return $p;
591 591
 }
592 592
 
593 593
 /**
@@ -607,10 +607,10 @@  discard block
 block discarded – undo
607 607
  *     Pile complétée par le code à générer
608 608
  **/
609 609
 function balise_POPULARITE_SITE_dist($p) {
610
-	$p->code = 'ceil($GLOBALS["meta"][\'popularite_total\'])';
611
-	$p->interdire_scripts = false;
610
+    $p->code = 'ceil($GLOBALS["meta"][\'popularite_total\'])';
611
+    $p->interdire_scripts = false;
612 612
 
613
-	return $p;
613
+    return $p;
614 614
 }
615 615
 
616 616
 /**
@@ -631,10 +631,10 @@  discard block
 block discarded – undo
631 631
  *     Pile complétée par le code à générer
632 632
  **/
633 633
 function balise_POPULARITE_MAX_dist($p) {
634
-	$p->code = 'ceil($GLOBALS["meta"][\'popularite_max\'])';
635
-	$p->interdire_scripts = false;
634
+    $p->code = 'ceil($GLOBALS["meta"][\'popularite_max\'])';
635
+    $p->interdire_scripts = false;
636 636
 
637
-	return $p;
637
+    return $p;
638 638
 }
639 639
 
640 640
 
@@ -660,15 +660,15 @@  discard block
 block discarded – undo
660 660
  *     Pile complétée par le code à générer
661 661
  **/
662 662
 function balise_VALEUR_dist($p) {
663
-	$b = $p->nom_boucle ?: $p->id_boucle;
664
-	$p->code = index_pile($p->id_boucle, 'valeur', $p->boucles, $b);
663
+    $b = $p->nom_boucle ?: $p->id_boucle;
664
+    $p->code = index_pile($p->id_boucle, 'valeur', $p->boucles, $b);
665 665
 ;
666
-	if (($v = interprete_argument_balise(1, $p)) !== null) {
667
-		$p->code = 'table_valeur(' . $p->code . ', ' . $v . ')';
668
-	}
669
-	$p->interdire_scripts = true;
666
+    if (($v = interprete_argument_balise(1, $p)) !== null) {
667
+        $p->code = 'table_valeur(' . $p->code . ', ' . $v . ')';
668
+    }
669
+    $p->interdire_scripts = true;
670 670
 
671
-	return $p;
671
+    return $p;
672 672
 }
673 673
 
674 674
 /**
@@ -697,16 +697,16 @@  discard block
 block discarded – undo
697 697
  *     Pile complétée par le code à générer
698 698
  **/
699 699
 function balise_EXPOSE_dist($p) {
700
-	$on = "'on'";
701
-	$off = "''";
702
-	if (($v = interprete_argument_balise(1, $p)) !== null) {
703
-		$on = $v;
704
-		if (($v = interprete_argument_balise(2, $p)) !== null) {
705
-			$off = $v;
706
-		}
707
-	}
700
+    $on = "'on'";
701
+    $off = "''";
702
+    if (($v = interprete_argument_balise(1, $p)) !== null) {
703
+        $on = $v;
704
+        if (($v = interprete_argument_balise(2, $p)) !== null) {
705
+            $off = $v;
706
+        }
707
+    }
708 708
 
709
-	return calculer_balise_expose($p, $on, $off);
709
+    return calculer_balise_expose($p, $on, $off);
710 710
 }
711 711
 
712 712
 /**
@@ -724,35 +724,35 @@  discard block
 block discarded – undo
724 724
  *     Pile complétée par le code à générer
725 725
  **/
726 726
 function calculer_balise_expose($p, $on, $off) {
727
-	$b = index_boucle($p);
728
-	if (empty($p->boucles[$b]->primary)) {
729
-		$msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
730
-		erreur_squelette($msg, $p);
731
-	} else {
732
-		$key = $p->boucles[$b]->primary;
733
-		$type = $p->boucles[$p->id_boucle]->primary;
734
-		$desc = $p->boucles[$b]->show;
735
-		$connect = sql_quote($p->boucles[$b]->sql_serveur);
727
+    $b = index_boucle($p);
728
+    if (empty($p->boucles[$b]->primary)) {
729
+        $msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
730
+        erreur_squelette($msg, $p);
731
+    } else {
732
+        $key = $p->boucles[$b]->primary;
733
+        $type = $p->boucles[$p->id_boucle]->primary;
734
+        $desc = $p->boucles[$b]->show;
735
+        $connect = sql_quote($p->boucles[$b]->sql_serveur);
736 736
 
737
-		// Ne pas utiliser champ_sql, on jongle avec le nom boucle explicite
738
-		$c = index_pile($p->id_boucle, $type, $p->boucles);
737
+        // Ne pas utiliser champ_sql, on jongle avec le nom boucle explicite
738
+        $c = index_pile($p->id_boucle, $type, $p->boucles);
739 739
 
740
-		if (isset($desc['field']['id_parent'])) {
741
-			$parent = 0; // pour if (!$parent) dans calculer_expose
742
-		} elseif (isset($desc['field']['id_rubrique'])) {
743
-			$parent = index_pile($p->id_boucle, 'id_rubrique', $p->boucles, $b);
744
-		} elseif (isset($desc['field']['id_groupe'])) {
745
-			$parent = index_pile($p->id_boucle, 'id_groupe', $p->boucles, $b);
746
-		} else {
747
-			$parent = "''";
748
-		}
740
+        if (isset($desc['field']['id_parent'])) {
741
+            $parent = 0; // pour if (!$parent) dans calculer_expose
742
+        } elseif (isset($desc['field']['id_rubrique'])) {
743
+            $parent = index_pile($p->id_boucle, 'id_rubrique', $p->boucles, $b);
744
+        } elseif (isset($desc['field']['id_groupe'])) {
745
+            $parent = index_pile($p->id_boucle, 'id_groupe', $p->boucles, $b);
746
+        } else {
747
+            $parent = "''";
748
+        }
749 749
 
750
-		$p->code = "(calcul_exposer($c, '$type', \$Pile[0], $parent, '$key', $connect) ? $on : $off)";
751
-	}
750
+        $p->code = "(calcul_exposer($c, '$type', \$Pile[0], $parent, '$key', $connect) ? $on : $off)";
751
+    }
752 752
 
753
-	$p->interdire_scripts = false;
753
+    $p->interdire_scripts = false;
754 754
 
755
-	return $p;
755
+    return $p;
756 756
 }
757 757
 
758 758
 
@@ -793,46 +793,46 @@  discard block
 block discarded – undo
793 793
  **/
794 794
 function balise_INTRODUCTION_dist($p) {
795 795
 
796
-	$type_objet = $p->type_requete;
797
-	$cle_objet = id_table_objet($type_objet);
798
-	$_id_objet = champ_sql($cle_objet, $p);
799
-
800
-	// Récupérer les valeurs sql nécessaires : descriptif, texte et chapo
801
-	// ainsi que le longueur d'introduction donnée dans la description de l'objet.
802
-	$_introduction_longueur = 'null';
803
-	$_ligne = 'array(';
804
-	$trouver_table = charger_fonction('trouver_table', 'base');
805
-	if ($desc = $trouver_table(table_objet_sql($type_objet))) {
806
-		if (isset($desc['field']['descriptif'])) {
807
-			$_ligne .= "'descriptif' => " . champ_sql('descriptif', $p) . ',';
808
-		}
809
-		if (isset($desc['field']['texte'])) {
810
-			$_ligne .= "'texte' => " . champ_sql('texte', $p) . ',';
811
-		}
812
-		if (isset($desc['field']['chapo'])) {
813
-			$_ligne .= "'chapo' => " . champ_sql('chapo', $p) . ',';
814
-		}
815
-		if (isset($desc['introduction_longueur'])) {
816
-			$_introduction_longueur = "'" . $desc['introduction_longueur'] . "'";
817
-		}
818
-	}
819
-	$_ligne .= ')';
820
-
821
-	// Récupérer la longueur et la suite passés en paramètres
822
-	$_longueur_ou_suite = 'null';
823
-	if (($v1 = interprete_argument_balise(1, $p)) !== null) {
824
-		$_longueur_ou_suite = $v1;
825
-	}
826
-	$_suite = 'null';
827
-	if (($v2 = interprete_argument_balise(2, $p)) !== null) {
828
-		$_suite = $v2;
829
-	}
830
-
831
-	$p->code = "generer_objet_introduction((int)$_id_objet, '$type_objet', $_ligne, $_introduction_longueur, $_longueur_ou_suite, $_suite, \$connect)";
832
-
833
-	#$p->interdire_scripts = true;
834
-	$p->etoile = '*'; // propre est deja fait dans le calcul de l'intro
835
-	return $p;
796
+    $type_objet = $p->type_requete;
797
+    $cle_objet = id_table_objet($type_objet);
798
+    $_id_objet = champ_sql($cle_objet, $p);
799
+
800
+    // Récupérer les valeurs sql nécessaires : descriptif, texte et chapo
801
+    // ainsi que le longueur d'introduction donnée dans la description de l'objet.
802
+    $_introduction_longueur = 'null';
803
+    $_ligne = 'array(';
804
+    $trouver_table = charger_fonction('trouver_table', 'base');
805
+    if ($desc = $trouver_table(table_objet_sql($type_objet))) {
806
+        if (isset($desc['field']['descriptif'])) {
807
+            $_ligne .= "'descriptif' => " . champ_sql('descriptif', $p) . ',';
808
+        }
809
+        if (isset($desc['field']['texte'])) {
810
+            $_ligne .= "'texte' => " . champ_sql('texte', $p) . ',';
811
+        }
812
+        if (isset($desc['field']['chapo'])) {
813
+            $_ligne .= "'chapo' => " . champ_sql('chapo', $p) . ',';
814
+        }
815
+        if (isset($desc['introduction_longueur'])) {
816
+            $_introduction_longueur = "'" . $desc['introduction_longueur'] . "'";
817
+        }
818
+    }
819
+    $_ligne .= ')';
820
+
821
+    // Récupérer la longueur et la suite passés en paramètres
822
+    $_longueur_ou_suite = 'null';
823
+    if (($v1 = interprete_argument_balise(1, $p)) !== null) {
824
+        $_longueur_ou_suite = $v1;
825
+    }
826
+    $_suite = 'null';
827
+    if (($v2 = interprete_argument_balise(2, $p)) !== null) {
828
+        $_suite = $v2;
829
+    }
830
+
831
+    $p->code = "generer_objet_introduction((int)$_id_objet, '$type_objet', $_ligne, $_introduction_longueur, $_longueur_ou_suite, $_suite, \$connect)";
832
+
833
+    #$p->interdire_scripts = true;
834
+    $p->etoile = '*'; // propre est deja fait dans le calcul de l'intro
835
+    return $p;
836 836
 }
837 837
 
838 838
 
@@ -852,15 +852,15 @@  discard block
 block discarded – undo
852 852
  *     Pile complétée par le code à générer
853 853
  **/
854 854
 function balise_LANG_dist($p) {
855
-	$_lang = champ_sql('lang', $p);
856
-	if (!$p->etoile) {
857
-		$p->code = "spip_htmlentities($_lang ? $_lang : \$GLOBALS['spip_lang'])";
858
-	} else {
859
-		$p->code = "spip_htmlentities($_lang)";
860
-	}
861
-	$p->interdire_scripts = false;
855
+    $_lang = champ_sql('lang', $p);
856
+    if (!$p->etoile) {
857
+        $p->code = "spip_htmlentities($_lang ? $_lang : \$GLOBALS['spip_lang'])";
858
+    } else {
859
+        $p->code = "spip_htmlentities($_lang)";
860
+    }
861
+    $p->interdire_scripts = false;
862 862
 
863
-	return $p;
863
+    return $p;
864 864
 }
865 865
 
866 866
 /**
@@ -882,45 +882,45 @@  discard block
 block discarded – undo
882 882
  *     Pile complétée par le code à générer
883 883
  */
884 884
 function balise_LESAUTEURS_dist($p) {
885
-	// Cherche le champ 'lesauteurs' dans la pile
886
-	$_lesauteurs = champ_sql('lesauteurs', $p, '');
887
-
888
-	// Si le champ n'existe pas (cas de spip_articles), on applique
889
-	// le modele lesauteurs.html en passant id_article dans le contexte;
890
-	// dans le cas contraire on prend le champ 'lesauteurs'
891
-	// (cf extension sites/)
892
-	if ($_lesauteurs) {
893
-		$p->code = "safehtml($_lesauteurs)";
894
-		// $p->interdire_scripts = true;
895
-	} else {
896
-		if (!$p->id_boucle) {
897
-			$connect = '';
898
-			$objet = 'article';
899
-			$id_table_objet = 'id_article';
900
-		} else {
901
-			$b = $p->nom_boucle ?: $p->id_boucle;
902
-			$connect = $p->boucles[$b]->sql_serveur;
903
-			$type_boucle = $p->boucles[$b]->type_requete;
904
-			$objet = objet_type($type_boucle);
905
-			$id_table_objet = id_table_objet($type_boucle);
906
-		}
907
-		$c = memoriser_contexte_compil($p);
908
-
909
-		$p->code = sprintf(
910
-			CODE_RECUPERER_FOND,
911
-			"'modeles/lesauteurs'",
912
-			"array('objet'=>'" . $objet .
913
-			"','id_objet' => " . champ_sql($id_table_objet, $p) .
914
-			",'$id_table_objet' => " . champ_sql($id_table_objet, $p) .
915
-			($objet == 'article' ? '' : ",'id_article' => " . champ_sql('id_article', $p)) .
916
-			')',
917
-			"'trim'=>true, 'compil'=>array($c)",
918
-			_q($connect)
919
-		);
920
-		$p->interdire_scripts = false; // securite apposee par recuperer_fond()
921
-	}
922
-
923
-	return $p;
885
+    // Cherche le champ 'lesauteurs' dans la pile
886
+    $_lesauteurs = champ_sql('lesauteurs', $p, '');
887
+
888
+    // Si le champ n'existe pas (cas de spip_articles), on applique
889
+    // le modele lesauteurs.html en passant id_article dans le contexte;
890
+    // dans le cas contraire on prend le champ 'lesauteurs'
891
+    // (cf extension sites/)
892
+    if ($_lesauteurs) {
893
+        $p->code = "safehtml($_lesauteurs)";
894
+        // $p->interdire_scripts = true;
895
+    } else {
896
+        if (!$p->id_boucle) {
897
+            $connect = '';
898
+            $objet = 'article';
899
+            $id_table_objet = 'id_article';
900
+        } else {
901
+            $b = $p->nom_boucle ?: $p->id_boucle;
902
+            $connect = $p->boucles[$b]->sql_serveur;
903
+            $type_boucle = $p->boucles[$b]->type_requete;
904
+            $objet = objet_type($type_boucle);
905
+            $id_table_objet = id_table_objet($type_boucle);
906
+        }
907
+        $c = memoriser_contexte_compil($p);
908
+
909
+        $p->code = sprintf(
910
+            CODE_RECUPERER_FOND,
911
+            "'modeles/lesauteurs'",
912
+            "array('objet'=>'" . $objet .
913
+            "','id_objet' => " . champ_sql($id_table_objet, $p) .
914
+            ",'$id_table_objet' => " . champ_sql($id_table_objet, $p) .
915
+            ($objet == 'article' ? '' : ",'id_article' => " . champ_sql('id_article', $p)) .
916
+            ')',
917
+            "'trim'=>true, 'compil'=>array($c)",
918
+            _q($connect)
919
+        );
920
+        $p->interdire_scripts = false; // securite apposee par recuperer_fond()
921
+    }
922
+
923
+    return $p;
924 924
 }
925 925
 
926 926
 
@@ -947,76 +947,76 @@  discard block
 block discarded – undo
947 947
  *     Pile complétée par le code à générer
948 948
  */
949 949
 function balise_RANG_dist($p) {
950
-	$b = index_boucle($p);
951
-	if ($b === '') {
952
-		$msg = [
953
-			'zbug_champ_hors_boucle',
954
-			['champ' => '#RANG']
955
-		];
956
-		erreur_squelette($msg, $p);
957
-	} else {
958
-		// chercher d'abord un champ sql rang (mais pas dans le env : defaut '' si on trouve pas de champ sql)
959
-		// dans la boucle immediatement englobante uniquement
960
-		// sinon on compose le champ calcule
961
-		$_rang = champ_sql('rang', $p, '', false);
962
-
963
-		// si pas trouve de champ sql rang :
964
-		if (!$_rang || $_rang == "''") {
965
-			$boucle = &$p->boucles[$b];
966
-
967
-			// on gere le cas ou #RANG est une extraction du numero dans le titre
968
-			$trouver_table = charger_fonction('trouver_table', 'base');
969
-			$desc = $trouver_table($boucle->id_table);
970
-			$_titre = ''; # où extraire le numero ?
971
-
972
-			if (isset($desc['titre'])) {
973
-				$t = $desc['titre'];
974
-				if (
975
-					// Soit on trouve avec la déclaration de la lang AVANT
976
-					preg_match(';(?:lang\s*,)\s*(.*?titre)\s*(,|$);', $t, $m)
977
-					// Soit on prend depuis le début
978
-					|| preg_match(';^(.*?titre)\s*(,|$);', $t, $m)
979
-				) {
980
-					$m = preg_replace(',as\s+titre$,i', '', $m[1]);
981
-					$m = trim($m);
982
-					if ($m != "''") {
983
-						if (!preg_match(',\W,', $m)) {
984
-							$m = $boucle->id_table . ".$m";
985
-						}
986
-
987
-						$m .= ' AS titre_rang';
988
-
989
-						$boucle->select[] = $m;
990
-						$_titre = '$Pile[$SP][\'titre_rang\']';
991
-					}
992
-				}
993
-			}
994
-
995
-			// si on n'a rien trouvé, on utilise le champ titre classique
996
-			if (!$_titre) {
997
-				$_titre = champ_sql('titre', $p);
998
-			}
999
-
1000
-			// et on recupere aussi les infos de liaison si on est en train d'editer les liens justement
1001
-			// cas des formulaires xxx_lies utilises par #FORMULAIRE_EDITER_LIENS
1002
-			$type_boucle = $boucle->type_requete;
1003
-			$objet = objet_type($type_boucle);
1004
-			$id_table_objet = id_table_objet($type_boucle);
1005
-			$_primary = champ_sql($id_table_objet, $p, '', false);
1006
-			$_env = '$Pile[0]';
1007
-
1008
-			if (!$_titre) {$_titre = "''";
1009
-			}
1010
-			if (!$_primary) {$_primary = "''";
1011
-			}
1012
-			$_rang = "calculer_rang_smart($_titre, '$objet', $_primary, $_env)";
1013
-		}
1014
-
1015
-		$p->code = $_rang;
1016
-		$p->interdire_scripts = false;
1017
-	}
1018
-
1019
-	return $p;
950
+    $b = index_boucle($p);
951
+    if ($b === '') {
952
+        $msg = [
953
+            'zbug_champ_hors_boucle',
954
+            ['champ' => '#RANG']
955
+        ];
956
+        erreur_squelette($msg, $p);
957
+    } else {
958
+        // chercher d'abord un champ sql rang (mais pas dans le env : defaut '' si on trouve pas de champ sql)
959
+        // dans la boucle immediatement englobante uniquement
960
+        // sinon on compose le champ calcule
961
+        $_rang = champ_sql('rang', $p, '', false);
962
+
963
+        // si pas trouve de champ sql rang :
964
+        if (!$_rang || $_rang == "''") {
965
+            $boucle = &$p->boucles[$b];
966
+
967
+            // on gere le cas ou #RANG est une extraction du numero dans le titre
968
+            $trouver_table = charger_fonction('trouver_table', 'base');
969
+            $desc = $trouver_table($boucle->id_table);
970
+            $_titre = ''; # où extraire le numero ?
971
+
972
+            if (isset($desc['titre'])) {
973
+                $t = $desc['titre'];
974
+                if (
975
+                    // Soit on trouve avec la déclaration de la lang AVANT
976
+                    preg_match(';(?:lang\s*,)\s*(.*?titre)\s*(,|$);', $t, $m)
977
+                    // Soit on prend depuis le début
978
+                    || preg_match(';^(.*?titre)\s*(,|$);', $t, $m)
979
+                ) {
980
+                    $m = preg_replace(',as\s+titre$,i', '', $m[1]);
981
+                    $m = trim($m);
982
+                    if ($m != "''") {
983
+                        if (!preg_match(',\W,', $m)) {
984
+                            $m = $boucle->id_table . ".$m";
985
+                        }
986
+
987
+                        $m .= ' AS titre_rang';
988
+
989
+                        $boucle->select[] = $m;
990
+                        $_titre = '$Pile[$SP][\'titre_rang\']';
991
+                    }
992
+                }
993
+            }
994
+
995
+            // si on n'a rien trouvé, on utilise le champ titre classique
996
+            if (!$_titre) {
997
+                $_titre = champ_sql('titre', $p);
998
+            }
999
+
1000
+            // et on recupere aussi les infos de liaison si on est en train d'editer les liens justement
1001
+            // cas des formulaires xxx_lies utilises par #FORMULAIRE_EDITER_LIENS
1002
+            $type_boucle = $boucle->type_requete;
1003
+            $objet = objet_type($type_boucle);
1004
+            $id_table_objet = id_table_objet($type_boucle);
1005
+            $_primary = champ_sql($id_table_objet, $p, '', false);
1006
+            $_env = '$Pile[0]';
1007
+
1008
+            if (!$_titre) {$_titre = "''";
1009
+            }
1010
+            if (!$_primary) {$_primary = "''";
1011
+            }
1012
+            $_rang = "calculer_rang_smart($_titre, '$objet', $_primary, $_env)";
1013
+        }
1014
+
1015
+        $p->code = $_rang;
1016
+        $p->interdire_scripts = false;
1017
+    }
1018
+
1019
+    return $p;
1020 1020
 }
1021 1021
 
1022 1022
 
@@ -1038,12 +1038,12 @@  discard block
 block discarded – undo
1038 1038
  *     Pile complétée par le code à générer
1039 1039
  **/
1040 1040
 function balise_POPULARITE_dist($p) {
1041
-	$_popularite = champ_sql('popularite', $p);
1042
-	$p->code = "(ceil(min(100, 100 * $_popularite
1041
+    $_popularite = champ_sql('popularite', $p);
1042
+    $p->code = "(ceil(min(100, 100 * $_popularite
1043 1043
 	/ max(1 , 0 + \$GLOBALS['meta']['popularite_max']))))";
1044
-	$p->interdire_scripts = false;
1044
+    $p->interdire_scripts = false;
1045 1045
 
1046
-	return $p;
1046
+    return $p;
1047 1047
 }
1048 1048
 
1049 1049
 /**
@@ -1054,8 +1054,8 @@  discard block
 block discarded – undo
1054 1054
  * l'absence peut-être due à une faute de frappe dans le contexte inclus.
1055 1055
  */
1056 1056
 define(
1057
-	'CODE_PAGINATION',
1058
-	'%s($Numrows["%s"]["grand_total"],
1057
+    'CODE_PAGINATION',
1058
+    '%s($Numrows["%s"]["grand_total"],
1059 1059
  		%s,
1060 1060
 		isset($Pile[0][%4$s])?$Pile[0][%4$s]:intval(_request(%4$s)),
1061 1061
 		%5$s, %6$s, %7$s, %8$s, array(%9$s))'
@@ -1092,75 +1092,75 @@  discard block
 block discarded – undo
1092 1092
  *     Pile complétée par le code à générer
1093 1093
  */
1094 1094
 function balise_PAGINATION_dist($p, $liste = 'true') {
1095
-	$b = index_boucle_mere($p);
1096
-
1097
-	// s'il n'y a pas de nom de boucle, on ne peut pas paginer
1098
-	if ($b === '') {
1099
-		$msg = [
1100
-			'zbug_champ_hors_boucle',
1101
-			['champ' => $liste ? 'PAGINATION' : 'ANCRE_PAGINATION']
1102
-		];
1103
-		erreur_squelette($msg, $p);
1104
-
1105
-		return $p;
1106
-	}
1107
-
1108
-	// s'il n'y a pas de mode_partie, c'est qu'on se trouve
1109
-	// dans un boucle recursive ou qu'on a oublie le critere {pagination}
1110
-	if (!$p->boucles[$b]->mode_partie) {
1111
-		if (!$p->boucles[$b]->table_optionnelle) {
1112
-			$msg = [
1113
-				'zbug_pagination_sans_critere',
1114
-				['champ' => '#PAGINATION']
1115
-			];
1116
-			erreur_squelette($msg, $p);
1117
-		}
1118
-
1119
-		return $p;
1120
-	}
1121
-
1122
-	// a priori true
1123
-	// si false, le compilo va bloquer sur des syntaxes avec un filtre sans argument qui suit la balise
1124
-	// si true, les arguments simples (sans truc=chose) vont degager
1125
-	$_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $p->id_boucle, false, false);
1126
-	if (is_countable($_contexte) ? count($_contexte) : 0) {
1127
-		$key = key($_contexte);
1128
-		if (is_numeric($key)) {
1129
-			array_shift($_contexte);
1130
-			$__modele = interprete_argument_balise(1, $p);
1131
-		}
1132
-	}
1133
-
1134
-	if (is_countable($_contexte) ? count($_contexte) : 0) {
1135
-		$code_contexte = implode(',', $_contexte);
1136
-	} else {
1137
-		$code_contexte = '';
1138
-	}
1139
-
1140
-	$connect = $p->boucles[$b]->sql_serveur;
1141
-	$pas = $p->boucles[$b]->total_parties;
1142
-	$f_pagination = chercher_filtre('pagination');
1143
-	$type = $p->boucles[$b]->modificateur['debut_nom'];
1144
-	$modif = ($type[0] !== "'") ? "'debut'.$type"
1145
-		: ("'debut" . substr($type, 1));
1146
-
1147
-	$p->code = sprintf(
1148
-		CODE_PAGINATION,
1149
-		$f_pagination,
1150
-		$b,
1151
-		$type,
1152
-		$modif,
1153
-		$pas,
1154
-		$liste,
1155
-		((isset($__modele) && $__modele) ? $__modele : "''"),
1156
-		_q($connect),
1157
-		$code_contexte
1158
-	);
1159
-
1160
-	$p->boucles[$b]->numrows = true;
1161
-	$p->interdire_scripts = false;
1162
-
1163
-	return $p;
1095
+    $b = index_boucle_mere($p);
1096
+
1097
+    // s'il n'y a pas de nom de boucle, on ne peut pas paginer
1098
+    if ($b === '') {
1099
+        $msg = [
1100
+            'zbug_champ_hors_boucle',
1101
+            ['champ' => $liste ? 'PAGINATION' : 'ANCRE_PAGINATION']
1102
+        ];
1103
+        erreur_squelette($msg, $p);
1104
+
1105
+        return $p;
1106
+    }
1107
+
1108
+    // s'il n'y a pas de mode_partie, c'est qu'on se trouve
1109
+    // dans un boucle recursive ou qu'on a oublie le critere {pagination}
1110
+    if (!$p->boucles[$b]->mode_partie) {
1111
+        if (!$p->boucles[$b]->table_optionnelle) {
1112
+            $msg = [
1113
+                'zbug_pagination_sans_critere',
1114
+                ['champ' => '#PAGINATION']
1115
+            ];
1116
+            erreur_squelette($msg, $p);
1117
+        }
1118
+
1119
+        return $p;
1120
+    }
1121
+
1122
+    // a priori true
1123
+    // si false, le compilo va bloquer sur des syntaxes avec un filtre sans argument qui suit la balise
1124
+    // si true, les arguments simples (sans truc=chose) vont degager
1125
+    $_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $p->id_boucle, false, false);
1126
+    if (is_countable($_contexte) ? count($_contexte) : 0) {
1127
+        $key = key($_contexte);
1128
+        if (is_numeric($key)) {
1129
+            array_shift($_contexte);
1130
+            $__modele = interprete_argument_balise(1, $p);
1131
+        }
1132
+    }
1133
+
1134
+    if (is_countable($_contexte) ? count($_contexte) : 0) {
1135
+        $code_contexte = implode(',', $_contexte);
1136
+    } else {
1137
+        $code_contexte = '';
1138
+    }
1139
+
1140
+    $connect = $p->boucles[$b]->sql_serveur;
1141
+    $pas = $p->boucles[$b]->total_parties;
1142
+    $f_pagination = chercher_filtre('pagination');
1143
+    $type = $p->boucles[$b]->modificateur['debut_nom'];
1144
+    $modif = ($type[0] !== "'") ? "'debut'.$type"
1145
+        : ("'debut" . substr($type, 1));
1146
+
1147
+    $p->code = sprintf(
1148
+        CODE_PAGINATION,
1149
+        $f_pagination,
1150
+        $b,
1151
+        $type,
1152
+        $modif,
1153
+        $pas,
1154
+        $liste,
1155
+        ((isset($__modele) && $__modele) ? $__modele : "''"),
1156
+        _q($connect),
1157
+        $code_contexte
1158
+    );
1159
+
1160
+    $p->boucles[$b]->numrows = true;
1161
+    $p->interdire_scripts = false;
1162
+
1163
+    return $p;
1164 1164
 }
1165 1165
 
1166 1166
 
@@ -1187,11 +1187,11 @@  discard block
 block discarded – undo
1187 1187
  *     Pile complétée par le code à générer
1188 1188
  **/
1189 1189
 function balise_ANCRE_PAGINATION_dist($p) {
1190
-	if ($f = charger_fonction('PAGINATION', 'balise', true)) {
1191
-		return $f($p, $liste = 'false');
1192
-	} else {
1193
-		return null;
1194
-	} // ou une erreur ?
1190
+    if ($f = charger_fonction('PAGINATION', 'balise', true)) {
1191
+        return $f($p, $liste = 'false');
1192
+    } else {
1193
+        return null;
1194
+    } // ou une erreur ?
1195 1195
 }
1196 1196
 
1197 1197
 
@@ -1212,17 +1212,17 @@  discard block
 block discarded – undo
1212 1212
  *     Pile complétée par le code à générer
1213 1213
  **/
1214 1214
 function balise_GRAND_TOTAL_dist($p) {
1215
-	$b = index_boucle_mere($p);
1216
-	if ($b === '') {
1217
-		$msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
1218
-		erreur_squelette($msg, $p);
1219
-	} else {
1220
-		$p->code = "(\$Numrows['$b']['grand_total'] ?? \$Numrows['$b']['total'] ?? 0)";
1221
-		$p->boucles[$b]->numrows = true;
1222
-		$p->interdire_scripts = false;
1223
-	}
1215
+    $b = index_boucle_mere($p);
1216
+    if ($b === '') {
1217
+        $msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
1218
+        erreur_squelette($msg, $p);
1219
+    } else {
1220
+        $p->code = "(\$Numrows['$b']['grand_total'] ?? \$Numrows['$b']['total'] ?? 0)";
1221
+        $p->boucles[$b]->numrows = true;
1222
+        $p->interdire_scripts = false;
1223
+    }
1224 1224
 
1225
-	return $p;
1225
+    return $p;
1226 1226
 }
1227 1227
 
1228 1228
 
@@ -1250,10 +1250,10 @@  discard block
 block discarded – undo
1250 1250
  *     Pile complétée par le code à générer
1251 1251
  **/
1252 1252
 function balise_SELF_dist($p) {
1253
-	$p->code = 'self()';
1254
-	$p->interdire_scripts = false;
1253
+    $p->code = 'self()';
1254
+    $p->interdire_scripts = false;
1255 1255
 
1256
-	return $p;
1256
+    return $p;
1257 1257
 }
1258 1258
 
1259 1259
 
@@ -1280,17 +1280,17 @@  discard block
 block discarded – undo
1280 1280
  *     Pile complétée par le code à générer
1281 1281
  **/
1282 1282
 function balise_CHEMIN_dist($p) {
1283
-	$arg = interprete_argument_balise(1, $p);
1284
-	if (!$arg) {
1285
-		$msg = ['zbug_balise_sans_argument', ['balise' => ' CHEMIN']];
1286
-		erreur_squelette($msg, $p);
1287
-	} else {
1288
-		$p->code = 'find_in_path((string)' . $arg . ')';
1289
-	}
1283
+    $arg = interprete_argument_balise(1, $p);
1284
+    if (!$arg) {
1285
+        $msg = ['zbug_balise_sans_argument', ['balise' => ' CHEMIN']];
1286
+        erreur_squelette($msg, $p);
1287
+    } else {
1288
+        $p->code = 'find_in_path((string)' . $arg . ')';
1289
+    }
1290 1290
 
1291
-	$p->interdire_scripts = false;
1291
+    $p->interdire_scripts = false;
1292 1292
 
1293
-	return $p;
1293
+    return $p;
1294 1294
 }
1295 1295
 
1296 1296
 /**
@@ -1315,16 +1315,16 @@  discard block
 block discarded – undo
1315 1315
  *     Pile complétée par le code à générer
1316 1316
  **/
1317 1317
 function balise_CHEMIN_IMAGE_dist($p) {
1318
-	$arg = interprete_argument_balise(1, $p);
1319
-	if (!$arg) {
1320
-		$msg = ['zbug_balise_sans_argument', ['balise' => ' CHEMIN_IMAGE']];
1321
-		erreur_squelette($msg, $p);
1322
-	} else {
1323
-		$p->code = 'chemin_image((string)' . $arg . ')';
1324
-	}
1318
+    $arg = interprete_argument_balise(1, $p);
1319
+    if (!$arg) {
1320
+        $msg = ['zbug_balise_sans_argument', ['balise' => ' CHEMIN_IMAGE']];
1321
+        erreur_squelette($msg, $p);
1322
+    } else {
1323
+        $p->code = 'chemin_image((string)' . $arg . ')';
1324
+    }
1325 1325
 
1326
-	$p->interdire_scripts = false;
1327
-	return $p;
1326
+    $p->interdire_scripts = false;
1327
+    return $p;
1328 1328
 }
1329 1329
 
1330 1330
 
@@ -1362,36 +1362,36 @@  discard block
 block discarded – undo
1362 1362
  **/
1363 1363
 function balise_ENV_dist($p, $src = null) {
1364 1364
 
1365
-	// cle du tableau desiree
1366
-	$_nom = interprete_argument_balise(1, $p);
1367
-	// valeur par defaut
1368
-	$_sinon = interprete_argument_balise(2, $p);
1365
+    // cle du tableau desiree
1366
+    $_nom = interprete_argument_balise(1, $p);
1367
+    // valeur par defaut
1368
+    $_sinon = interprete_argument_balise(2, $p);
1369 1369
 
1370
-	// $src est un tableau de donnees sources eventuellement transmis
1371
-	// en absence, on utilise l'environnement du squelette $Pile[0]
1370
+    // $src est un tableau de donnees sources eventuellement transmis
1371
+    // en absence, on utilise l'environnement du squelette $Pile[0]
1372 1372
 
1373
-	if (!$_nom) {
1374
-		// cas de #ENV sans argument : on retourne le serialize() du tableau
1375
-		// une belle fonction [(#ENV|affiche_env)] serait pratique
1376
-		if ($src) {
1377
-			$p->code = '(is_array($a = (' . $src . ')) ? serialize($a) : "")';
1378
-		} else {
1379
-			$p->code = 'serialize($Pile[0]??[])';
1380
-		}
1381
-	} else {
1382
-		if (!$src) {
1383
-			$src = '$Pile[0]??[]';
1384
-		}
1385
-		if ($_sinon) {
1386
-			$p->code = "sinon(table_valeur($src, (string)$_nom, null), $_sinon)";
1387
-		} else {
1388
-			$p->code = "table_valeur($src, (string)$_nom, null)";
1389
-		}
1390
-	}
1373
+    if (!$_nom) {
1374
+        // cas de #ENV sans argument : on retourne le serialize() du tableau
1375
+        // une belle fonction [(#ENV|affiche_env)] serait pratique
1376
+        if ($src) {
1377
+            $p->code = '(is_array($a = (' . $src . ')) ? serialize($a) : "")';
1378
+        } else {
1379
+            $p->code = 'serialize($Pile[0]??[])';
1380
+        }
1381
+    } else {
1382
+        if (!$src) {
1383
+            $src = '$Pile[0]??[]';
1384
+        }
1385
+        if ($_sinon) {
1386
+            $p->code = "sinon(table_valeur($src, (string)$_nom, null), $_sinon)";
1387
+        } else {
1388
+            $p->code = "table_valeur($src, (string)$_nom, null)";
1389
+        }
1390
+    }
1391 1391
 
1392
-	#$p->interdire_scripts = true;
1392
+    #$p->interdire_scripts = true;
1393 1393
 
1394
-	return $p;
1394
+    return $p;
1395 1395
 }
1396 1396
 
1397 1397
 /**
@@ -1421,16 +1421,16 @@  discard block
 block discarded – undo
1421 1421
  *     Pile completée du code PHP d'exécution de la balise
1422 1422
  */
1423 1423
 function balise_CONFIG_dist($p) {
1424
-	if (!$arg = interprete_argument_balise(1, $p)) {
1425
-		$arg = "''";
1426
-	}
1427
-	$_sinon = interprete_argument_balise(2, $p);
1428
-	$_unserialize = sinon(interprete_argument_balise(3, $p), 'false');
1424
+    if (!$arg = interprete_argument_balise(1, $p)) {
1425
+        $arg = "''";
1426
+    }
1427
+    $_sinon = interprete_argument_balise(2, $p);
1428
+    $_unserialize = sinon(interprete_argument_balise(3, $p), 'false');
1429 1429
 
1430
-	$p->code = '(include_spip(\'inc/config\')?lire_config(' . $arg . ',' .
1431
-		($_sinon && $_sinon != "''" ? $_sinon : 'null') . ',' . $_unserialize . "):'')";
1430
+    $p->code = '(include_spip(\'inc/config\')?lire_config(' . $arg . ',' .
1431
+        ($_sinon && $_sinon != "''" ? $_sinon : 'null') . ',' . $_unserialize . "):'')";
1432 1432
 
1433
-	return $p;
1433
+    return $p;
1434 1434
 }
1435 1435
 
1436 1436
 
@@ -1453,10 +1453,10 @@  discard block
 block discarded – undo
1453 1453
  *     Pile completée du code PHP d'exécution de la balise
1454 1454
  */
1455 1455
 function balise_CONNECT_dist($p) {
1456
-	$p->code = '($connect ? $connect : NULL)';
1457
-	$p->interdire_scripts = false;
1456
+    $p->code = '($connect ? $connect : NULL)';
1457
+    $p->interdire_scripts = false;
1458 1458
 
1459
-	return $p;
1459
+    return $p;
1460 1460
 }
1461 1461
 
1462 1462
 
@@ -1484,15 +1484,15 @@  discard block
 block discarded – undo
1484 1484
  *     Pile completée du code PHP d'exécution de la balise
1485 1485
  **/
1486 1486
 function balise_SESSION_dist($p) {
1487
-	$p->descr['session'] = true;
1487
+    $p->descr['session'] = true;
1488 1488
 
1489
-	$f = function_exists('balise_ENV')
1490
-		? 'balise_ENV'
1491
-		: 'balise_ENV_dist';
1489
+    $f = function_exists('balise_ENV')
1490
+        ? 'balise_ENV'
1491
+        : 'balise_ENV_dist';
1492 1492
 
1493
-	$p = $f($p, '$GLOBALS["visiteur_session"]??[]');
1493
+    $p = $f($p, '$GLOBALS["visiteur_session"]??[]');
1494 1494
 
1495
-	return $p;
1495
+    return $p;
1496 1496
 }
1497 1497
 
1498 1498
 
@@ -1515,18 +1515,18 @@  discard block
 block discarded – undo
1515 1515
  *     Pile completée du code PHP d'exécution de la balise
1516 1516
  **/
1517 1517
 function balise_SESSION_SET_dist($p) {
1518
-	$_nom = interprete_argument_balise(1, $p);
1519
-	$_val = interprete_argument_balise(2, $p);
1520
-	if (!$_nom || !$_val) {
1521
-		$err_b_s_a = ['zbug_balise_sans_argument', ['balise' => 'SESSION_SET']];
1522
-		erreur_squelette($err_b_s_a, $p);
1523
-	} else {
1524
-		$p->code = '(include_spip("inc/session") AND session_set(' . $_nom . ',' . $_val . '))';
1525
-	}
1518
+    $_nom = interprete_argument_balise(1, $p);
1519
+    $_val = interprete_argument_balise(2, $p);
1520
+    if (!$_nom || !$_val) {
1521
+        $err_b_s_a = ['zbug_balise_sans_argument', ['balise' => 'SESSION_SET']];
1522
+        erreur_squelette($err_b_s_a, $p);
1523
+    } else {
1524
+        $p->code = '(include_spip("inc/session") AND session_set(' . $_nom . ',' . $_val . '))';
1525
+    }
1526 1526
 
1527
-	$p->interdire_scripts = false;
1527
+    $p->interdire_scripts = false;
1528 1528
 
1529
-	return $p;
1529
+    return $p;
1530 1530
 }
1531 1531
 
1532 1532
 
@@ -1557,30 +1557,30 @@  discard block
 block discarded – undo
1557 1557
  *     Pile completée du code PHP d'exécution de la balise
1558 1558
  **/
1559 1559
 function balise_EVAL_dist($p) {
1560
-	$php = interprete_argument_balise(1, $p);
1561
-	if ($php) {
1562
-		# optimisation sur les #EVAL{une expression sans #BALISE}
1563
-		# attention au commentaire "// x signes" qui precede
1564
-		if (
1565
-			preg_match(
1566
-				",^([[:space:]]*//[^\n]*\n)'([^']+)'$,ms",
1567
-				$php,
1568
-				$r
1569
-			)
1570
-		) {
1571
-			$p->code = /* $r[1]. */
1572
-				'(' . $r[2] . ')';
1573
-		} else {
1574
-			$p->code = "eval('return '.$php.';')";
1575
-		}
1576
-	} else {
1577
-		$msg = ['zbug_balise_sans_argument', ['balise' => ' EVAL']];
1578
-		erreur_squelette($msg, $p);
1579
-	}
1580
-
1581
-	#$p->interdire_scripts = true;
1582
-
1583
-	return $p;
1560
+    $php = interprete_argument_balise(1, $p);
1561
+    if ($php) {
1562
+        # optimisation sur les #EVAL{une expression sans #BALISE}
1563
+        # attention au commentaire "// x signes" qui precede
1564
+        if (
1565
+            preg_match(
1566
+                ",^([[:space:]]*//[^\n]*\n)'([^']+)'$,ms",
1567
+                $php,
1568
+                $r
1569
+            )
1570
+        ) {
1571
+            $p->code = /* $r[1]. */
1572
+                '(' . $r[2] . ')';
1573
+        } else {
1574
+            $p->code = "eval('return '.$php.';')";
1575
+        }
1576
+    } else {
1577
+        $msg = ['zbug_balise_sans_argument', ['balise' => ' EVAL']];
1578
+        erreur_squelette($msg, $p);
1579
+    }
1580
+
1581
+    #$p->interdire_scripts = true;
1582
+
1583
+    return $p;
1584 1584
 }
1585 1585
 
1586 1586
 
@@ -1610,19 +1610,19 @@  discard block
 block discarded – undo
1610 1610
  **/
1611 1611
 function balise_CHAMP_SQL_dist($p) {
1612 1612
 
1613
-	if (
1614
-		$p->param
1615
-		&& isset($p->param[0][1][0])
1616
-		&& ($champ = ($p->param[0][1][0]->texte))
1617
-	) {
1618
-		$p->code = champ_sql($champ, $p);
1619
-	} else {
1620
-		$err_b_s_a = ['zbug_balise_sans_argument', ['balise' => ' CHAMP_SQL']];
1621
-		erreur_squelette($err_b_s_a, $p);
1622
-	}
1613
+    if (
1614
+        $p->param
1615
+        && isset($p->param[0][1][0])
1616
+        && ($champ = ($p->param[0][1][0]->texte))
1617
+    ) {
1618
+        $p->code = champ_sql($champ, $p);
1619
+    } else {
1620
+        $err_b_s_a = ['zbug_balise_sans_argument', ['balise' => ' CHAMP_SQL']];
1621
+        erreur_squelette($err_b_s_a, $p);
1622
+    }
1623 1623
 
1624
-	#$p->interdire_scripts = true;
1625
-	return $p;
1624
+    #$p->interdire_scripts = true;
1625
+    return $p;
1626 1626
 }
1627 1627
 
1628 1628
 /**
@@ -1648,13 +1648,13 @@  discard block
 block discarded – undo
1648 1648
  *     Pile complétée par le code à générer
1649 1649
  **/
1650 1650
 function balise_VAL_dist($p) {
1651
-	$p->code = interprete_argument_balise(1, $p) ?? '';
1652
-	if (!strlen($p->code)) {
1653
-		$p->code = "''";
1654
-	}
1655
-	$p->interdire_scripts = false;
1651
+    $p->code = interprete_argument_balise(1, $p) ?? '';
1652
+    if (!strlen($p->code)) {
1653
+        $p->code = "''";
1654
+    }
1655
+    $p->interdire_scripts = false;
1656 1656
 
1657
-	return $p;
1657
+    return $p;
1658 1658
 }
1659 1659
 
1660 1660
 /**
@@ -1683,10 +1683,10 @@  discard block
 block discarded – undo
1683 1683
  *     Pile complétée par le code à générer
1684 1684
  **/
1685 1685
 function balise_REM_dist($p) {
1686
-	$p->code = "''";
1687
-	$p->interdire_scripts = false;
1686
+    $p->code = "''";
1687
+    $p->interdire_scripts = false;
1688 1688
 
1689
-	return $p;
1689
+    return $p;
1690 1690
 }
1691 1691
 
1692 1692
 /**
@@ -1696,10 +1696,10 @@  discard block
 block discarded – undo
1696 1696
  * @return mixed
1697 1697
  */
1698 1698
 function balise_NULL_dist($p) {
1699
-	$p->code = 'null';
1700
-	$p->interdire_scripts = false;
1699
+    $p->code = 'null';
1700
+    $p->interdire_scripts = false;
1701 1701
 
1702
-	return $p;
1702
+    return $p;
1703 1703
 }
1704 1704
 
1705 1705
 
@@ -1723,18 +1723,18 @@  discard block
 block discarded – undo
1723 1723
  **/
1724 1724
 function balise_HTTP_HEADER_dist($p) {
1725 1725
 
1726
-	$header = interprete_argument_balise(1, $p);
1727
-	if (!$header) {
1728
-		$err_b_s_a = ['zbug_balise_sans_argument', ['balise' => 'HTTP_HEADER']];
1729
-		erreur_squelette($err_b_s_a, $p);
1730
-	} else {
1731
-		$p->code = "'<'.'?php header(' . _q("
1732
-			. $header
1733
-			. ") . '); ?'.'>'";
1734
-	}
1735
-	$p->interdire_scripts = false;
1726
+    $header = interprete_argument_balise(1, $p);
1727
+    if (!$header) {
1728
+        $err_b_s_a = ['zbug_balise_sans_argument', ['balise' => 'HTTP_HEADER']];
1729
+        erreur_squelette($err_b_s_a, $p);
1730
+    } else {
1731
+        $p->code = "'<'.'?php header(' . _q("
1732
+            . $header
1733
+            . ") . '); ?'.'>'";
1734
+    }
1735
+    $p->interdire_scripts = false;
1736 1736
 
1737
-	return $p;
1737
+    return $p;
1738 1738
 }
1739 1739
 
1740 1740
 
@@ -1759,22 +1759,22 @@  discard block
 block discarded – undo
1759 1759
  *     Pile complétée par le code à générer
1760 1760
  **/
1761 1761
 function balise_FILTRE_dist($p) {
1762
-	if ($p->param) {
1763
-		$args = [];
1764
-		foreach ($p->param as $i => $ignore) {
1765
-			$args[] = interprete_argument_balise($i + 1, $p);
1766
-		}
1767
-		$p->code = "'<' . '"
1768
-			. '?php header("X-Spip-Filtre: \'.'
1769
-			. join('.\'|\'.', $args)
1770
-			. " . '\"); ?'.'>'";
1762
+    if ($p->param) {
1763
+        $args = [];
1764
+        foreach ($p->param as $i => $ignore) {
1765
+            $args[] = interprete_argument_balise($i + 1, $p);
1766
+        }
1767
+        $p->code = "'<' . '"
1768
+            . '?php header("X-Spip-Filtre: \'.'
1769
+            . join('.\'|\'.', $args)
1770
+            . " . '\"); ?'.'>'";
1771 1771
 
1772
-		$p->interdire_scripts = false;
1772
+        $p->interdire_scripts = false;
1773 1773
 
1774
-		return $p;
1775
-	}
1774
+        return $p;
1775
+    }
1776 1776
 
1777
-	return null;
1777
+    return null;
1778 1778
 }
1779 1779
 
1780 1780
 
@@ -1810,55 +1810,55 @@  discard block
 block discarded – undo
1810 1810
  **/
1811 1811
 function balise_CACHE_dist($p) {
1812 1812
 
1813
-	if ($p->param) {
1814
-		$duree = valeur_numerique($p->param[0][1][0]->texte);
1815
-
1816
-		// noter la duree du cache dans un entete proprietaire
1817
-
1818
-		$code = "'<'.'" . '?php header("X-Spip-Cache: '
1819
-			. $duree
1820
-			. '"); ?' . "'.'>'";
1821
-
1822
-		// Remplir le header Cache-Control
1823
-		// cas #CACHE{0}
1824
-		if ($duree == 0) {
1825
-			$code .= ".'<'.'"
1826
-				. '?php header("Cache-Control: no-cache, must-revalidate"); ?'
1827
-				. "'.'><'.'"
1828
-				. '?php header("Pragma: no-cache"); ?'
1829
-				. "'.'>'";
1830
-		}
1831
-
1832
-		// recuperer les parametres suivants
1833
-		$i = 1;
1834
-		while (isset($p->param[0][++$i])) {
1835
-			$pa = ($p->param[0][$i][0]->texte);
1836
-
1837
-			if (
1838
-				$pa == 'cache-client'
1839
-				&& $duree > 0
1840
-			) {
1841
-				$code .= ".'<'.'" . '?php header("Cache-Control: max-age='
1842
-					. $duree
1843
-					. '"); ?' . "'.'>'";
1844
-				// il semble logique, si on cache-client, de ne pas invalider
1845
-				$pa = 'statique';
1846
-			}
1847
-
1848
-			if (
1849
-				$pa == 'statique'
1850
-				&& $duree > 0
1851
-			) {
1852
-				$code .= ".'<'.'" . '?php header("X-Spip-Statique: oui"); ?' . "'.'>'";
1853
-			}
1854
-		}
1855
-	} else {
1856
-		$code = "''";
1857
-	}
1858
-	$p->code = $code;
1859
-	$p->interdire_scripts = false;
1860
-
1861
-	return $p;
1813
+    if ($p->param) {
1814
+        $duree = valeur_numerique($p->param[0][1][0]->texte);
1815
+
1816
+        // noter la duree du cache dans un entete proprietaire
1817
+
1818
+        $code = "'<'.'" . '?php header("X-Spip-Cache: '
1819
+            . $duree
1820
+            . '"); ?' . "'.'>'";
1821
+
1822
+        // Remplir le header Cache-Control
1823
+        // cas #CACHE{0}
1824
+        if ($duree == 0) {
1825
+            $code .= ".'<'.'"
1826
+                . '?php header("Cache-Control: no-cache, must-revalidate"); ?'
1827
+                . "'.'><'.'"
1828
+                . '?php header("Pragma: no-cache"); ?'
1829
+                . "'.'>'";
1830
+        }
1831
+
1832
+        // recuperer les parametres suivants
1833
+        $i = 1;
1834
+        while (isset($p->param[0][++$i])) {
1835
+            $pa = ($p->param[0][$i][0]->texte);
1836
+
1837
+            if (
1838
+                $pa == 'cache-client'
1839
+                && $duree > 0
1840
+            ) {
1841
+                $code .= ".'<'.'" . '?php header("Cache-Control: max-age='
1842
+                    . $duree
1843
+                    . '"); ?' . "'.'>'";
1844
+                // il semble logique, si on cache-client, de ne pas invalider
1845
+                $pa = 'statique';
1846
+            }
1847
+
1848
+            if (
1849
+                $pa == 'statique'
1850
+                && $duree > 0
1851
+            ) {
1852
+                $code .= ".'<'.'" . '?php header("X-Spip-Statique: oui"); ?' . "'.'>'";
1853
+            }
1854
+        }
1855
+    } else {
1856
+        $code = "''";
1857
+    }
1858
+    $p->code = $code;
1859
+    $p->interdire_scripts = false;
1860
+
1861
+    return $p;
1862 1862
 }
1863 1863
 
1864 1864
 
@@ -1890,13 +1890,13 @@  discard block
 block discarded – undo
1890 1890
  *     Pile complétée par le code à générer
1891 1891
  */
1892 1892
 function balise_INSERT_HEAD_dist($p) {
1893
-	$p->code = "'<'.'"
1894
-		. '?php header("X-Spip-Filtre: insert_head_css_conditionnel"); ?'
1895
-		. "'.'>'";
1896
-	$p->code .= ". pipeline('insert_head','<!-- insert_head -->')";
1897
-	$p->interdire_scripts = false;
1893
+    $p->code = "'<'.'"
1894
+        . '?php header("X-Spip-Filtre: insert_head_css_conditionnel"); ?'
1895
+        . "'.'>'";
1896
+    $p->code .= ". pipeline('insert_head','<!-- insert_head -->')";
1897
+    $p->interdire_scripts = false;
1898 1898
 
1899
-	return $p;
1899
+    return $p;
1900 1900
 }
1901 1901
 
1902 1902
 /**
@@ -1914,10 +1914,10 @@  discard block
 block discarded – undo
1914 1914
  *     Pile complétée par le code à générer
1915 1915
  */
1916 1916
 function balise_INSERT_HEAD_CSS_dist($p) {
1917
-	$p->code = "pipeline('insert_head_css','<!-- insert_head_css -->')";
1918
-	$p->interdire_scripts = false;
1917
+    $p->code = "pipeline('insert_head_css','<!-- insert_head_css -->')";
1918
+    $p->interdire_scripts = false;
1919 1919
 
1920
-	return $p;
1920
+    return $p;
1921 1921
 }
1922 1922
 
1923 1923
 /**
@@ -1932,11 +1932,11 @@  discard block
 block discarded – undo
1932 1932
  *     Pile complétée par le code à générer
1933 1933
  **/
1934 1934
 function balise_INCLUDE_dist($p) {
1935
-	if (function_exists('balise_INCLURE')) {
1936
-		return balise_INCLURE($p);
1937
-	} else {
1938
-		return balise_INCLURE_dist($p);
1939
-	}
1935
+    if (function_exists('balise_INCLURE')) {
1936
+        return balise_INCLURE($p);
1937
+    } else {
1938
+        return balise_INCLURE_dist($p);
1939
+    }
1940 1940
 }
1941 1941
 
1942 1942
 /**
@@ -1970,66 +1970,66 @@  discard block
 block discarded – undo
1970 1970
  *     Pile complétée par le code à générer
1971 1971
  **/
1972 1972
 function balise_INCLURE_dist($p) {
1973
-	$id_boucle = $p->id_boucle;
1974
-	// la lang n'est pas passe de facon automatique par argumenter
1975
-	// mais le sera pas recuperer_fond, sauf si etoile=>true est passe
1976
-	// en option
1977
-
1978
-	$_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $id_boucle, false, false);
1979
-
1980
-	// erreur de syntaxe = fond absent
1981
-	// (2 messages d'erreur SPIP pour le prix d'un, mais pas d'erreur PHP
1982
-	if (!$_contexte) {
1983
-		$_contexte = [];
1984
-	}
1985
-
1986
-	if (isset($_contexte['fond'])) {
1987
-		$f = $_contexte['fond'];
1988
-		// toujours vrai :
1989
-		if (preg_match('/^.fond.\s*=>(.*)$/s', $f, $r)) {
1990
-			$f = $r[1];
1991
-			unset($_contexte['fond']);
1992
-		} else {
1993
-			spip_log('compilation de #INCLURE a revoir');
1994
-		}
1995
-
1996
-		// #INCLURE{doublons}
1997
-		if (isset($_contexte['doublons'])) {
1998
-			$_contexte['doublons'] = "'doublons' => \$doublons";
1999
-		}
2000
-
2001
-		// Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
2002
-		$flag_env = false;
2003
-		if (isset($_contexte['env']) || isset($_contexte['self'])) {
2004
-			$flag_env = true;
2005
-			unset($_contexte['env']);
2006
-		}
2007
-
2008
-		$_options = [];
2009
-		if (isset($_contexte['ajax'])) {
2010
-			$_options[] = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
2011
-			unset($_contexte['ajax']);
2012
-		}
2013
-		if ($p->etoile) {
2014
-			$_options[] = "'etoile'=>true";
2015
-		}
2016
-		$_options[] = "'compil'=>array(" . memoriser_contexte_compil($p) . ')';
2017
-
2018
-		$_l = 'array(' . join(",\n\t", $_contexte) . ')';
2019
-		if ($flag_env) {
2020
-			$_l = "array_merge(\$Pile[0],$_l)";
2021
-		}
2022
-
2023
-		$p->code = sprintf(CODE_RECUPERER_FOND, $f, $_l, join(',', $_options), "_request('connect') ?? ''");
2024
-	} elseif (!isset($_contexte[1])) {
2025
-		$msg = ['zbug_balise_sans_argument', ['balise' => ' INCLURE']];
2026
-		erreur_squelette($msg, $p);
2027
-	} else {
2028
-		$p->code = 'charge_scripts(' . $_contexte[1] . ',false)';
2029
-	}
2030
-
2031
-	$p->interdire_scripts = false; // la securite est assuree par recuperer_fond
2032
-	return $p;
1973
+    $id_boucle = $p->id_boucle;
1974
+    // la lang n'est pas passe de facon automatique par argumenter
1975
+    // mais le sera pas recuperer_fond, sauf si etoile=>true est passe
1976
+    // en option
1977
+
1978
+    $_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $id_boucle, false, false);
1979
+
1980
+    // erreur de syntaxe = fond absent
1981
+    // (2 messages d'erreur SPIP pour le prix d'un, mais pas d'erreur PHP
1982
+    if (!$_contexte) {
1983
+        $_contexte = [];
1984
+    }
1985
+
1986
+    if (isset($_contexte['fond'])) {
1987
+        $f = $_contexte['fond'];
1988
+        // toujours vrai :
1989
+        if (preg_match('/^.fond.\s*=>(.*)$/s', $f, $r)) {
1990
+            $f = $r[1];
1991
+            unset($_contexte['fond']);
1992
+        } else {
1993
+            spip_log('compilation de #INCLURE a revoir');
1994
+        }
1995
+
1996
+        // #INCLURE{doublons}
1997
+        if (isset($_contexte['doublons'])) {
1998
+            $_contexte['doublons'] = "'doublons' => \$doublons";
1999
+        }
2000
+
2001
+        // Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
2002
+        $flag_env = false;
2003
+        if (isset($_contexte['env']) || isset($_contexte['self'])) {
2004
+            $flag_env = true;
2005
+            unset($_contexte['env']);
2006
+        }
2007
+
2008
+        $_options = [];
2009
+        if (isset($_contexte['ajax'])) {
2010
+            $_options[] = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
2011
+            unset($_contexte['ajax']);
2012
+        }
2013
+        if ($p->etoile) {
2014
+            $_options[] = "'etoile'=>true";
2015
+        }
2016
+        $_options[] = "'compil'=>array(" . memoriser_contexte_compil($p) . ')';
2017
+
2018
+        $_l = 'array(' . join(",\n\t", $_contexte) . ')';
2019
+        if ($flag_env) {
2020
+            $_l = "array_merge(\$Pile[0],$_l)";
2021
+        }
2022
+
2023
+        $p->code = sprintf(CODE_RECUPERER_FOND, $f, $_l, join(',', $_options), "_request('connect') ?? ''");
2024
+    } elseif (!isset($_contexte[1])) {
2025
+        $msg = ['zbug_balise_sans_argument', ['balise' => ' INCLURE']];
2026
+        erreur_squelette($msg, $p);
2027
+    } else {
2028
+        $p->code = 'charge_scripts(' . $_contexte[1] . ',false)';
2029
+    }
2030
+
2031
+    $p->interdire_scripts = false; // la securite est assuree par recuperer_fond
2032
+    return $p;
2033 2033
 }
2034 2034
 
2035 2035
 
@@ -2057,69 +2057,69 @@  discard block
 block discarded – undo
2057 2057
  **/
2058 2058
 function balise_MODELE_dist($p) {
2059 2059
 
2060
-	$_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $p->id_boucle, false);
2061
-
2062
-	// erreur de syntaxe = fond absent
2063
-	// (2 messages d'erreur SPIP pour le prix d'un, mais pas d'erreur PHP
2064
-	if (!$_contexte) {
2065
-		$_contexte = [];
2066
-	}
2067
-
2068
-	if (!isset($_contexte[1])) {
2069
-		$msg = ['zbug_balise_sans_argument', ['balise' => ' MODELE']];
2070
-		erreur_squelette($msg, $p);
2071
-	} else {
2072
-		$nom = $_contexte[1];
2073
-		unset($_contexte[1]);
2074
-
2075
-		if (preg_match("/^\s*'[^']*'/s", $nom)) {
2076
-			$nom = "'modeles/" . substr($nom, 1);
2077
-		} else {
2078
-			$nom = "'modeles/' . $nom";
2079
-		}
2080
-
2081
-		$flag_env = false;
2082
-		if (isset($_contexte['env'])) {
2083
-			$flag_env = true;
2084
-			unset($_contexte['env']);
2085
-		}
2086
-
2087
-		// Incoherence dans la syntaxe du contexte. A revoir.
2088
-		// Reserver la cle primaire de la boucle courante si elle existe
2089
-		if (isset($p->boucles[$p->id_boucle]->primary)) {
2090
-			$primary = $p->boucles[$p->id_boucle]->primary;
2091
-			if (!strpos($primary, ',')) {
2092
-				$id = champ_sql($primary, $p);
2093
-				$_contexte[] = "'$primary'=>" . $id;
2094
-				$_contexte[] = "'id'=>" . $id;
2095
-			}
2096
-		}
2097
-		$_contexte[] = "'recurs'=>(++\$recurs)";
2098
-		$connect = '';
2099
-		if (isset($p->boucles[$p->id_boucle])) {
2100
-			$connect = $p->boucles[$p->id_boucle]->sql_serveur;
2101
-		}
2102
-
2103
-		$_options = memoriser_contexte_compil($p);
2104
-		$_options = "'compil'=>array($_options), 'trim'=>true";
2105
-		if (isset($_contexte['ajax'])) {
2106
-			$_options .= ', ' . preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
2107
-			unset($_contexte['ajax']);
2108
-		}
2109
-
2110
-		$_l = 'array(' . join(",\n\t", $_contexte) . ')';
2111
-		if ($flag_env) {
2112
-			$_l = "array_merge(\$Pile[0],$_l)";
2113
-		}
2114
-
2115
-		$page = sprintf(CODE_RECUPERER_FOND, $nom, $_l, $_options, _q($connect));
2116
-
2117
-		$p->code = "\n\t(((\$recurs=(isset(\$Pile[0]['recurs'])?\$Pile[0]['recurs']:0))>=5)? '' :\n\t$page)\n";
2118
-
2119
-		$p->interdire_scripts = false; // securite assuree par le squelette
2120
-	}
2121
-
2122
-	return $p;
2060
+    $_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $p->id_boucle, false);
2061
+
2062
+    // erreur de syntaxe = fond absent
2063
+    // (2 messages d'erreur SPIP pour le prix d'un, mais pas d'erreur PHP
2064
+    if (!$_contexte) {
2065
+        $_contexte = [];
2066
+    }
2067
+
2068
+    if (!isset($_contexte[1])) {
2069
+        $msg = ['zbug_balise_sans_argument', ['balise' => ' MODELE']];
2070
+        erreur_squelette($msg, $p);
2071
+    } else {
2072
+        $nom = $_contexte[1];
2073
+        unset($_contexte[1]);
2074
+
2075
+        if (preg_match("/^\s*'[^']*'/s", $nom)) {
2076
+            $nom = "'modeles/" . substr($nom, 1);
2077
+        } else {
2078
+            $nom = "'modeles/' . $nom";
2079
+        }
2080
+
2081
+        $flag_env = false;
2082
+        if (isset($_contexte['env'])) {
2083
+            $flag_env = true;
2084
+            unset($_contexte['env']);
2085
+        }
2086
+
2087
+        // Incoherence dans la syntaxe du contexte. A revoir.
2088
+        // Reserver la cle primaire de la boucle courante si elle existe
2089
+        if (isset($p->boucles[$p->id_boucle]->primary)) {
2090
+            $primary = $p->boucles[$p->id_boucle]->primary;
2091
+            if (!strpos($primary, ',')) {
2092
+                $id = champ_sql($primary, $p);
2093
+                $_contexte[] = "'$primary'=>" . $id;
2094
+                $_contexte[] = "'id'=>" . $id;
2095
+            }
2096
+        }
2097
+        $_contexte[] = "'recurs'=>(++\$recurs)";
2098
+        $connect = '';
2099
+        if (isset($p->boucles[$p->id_boucle])) {
2100
+            $connect = $p->boucles[$p->id_boucle]->sql_serveur;
2101
+        }
2102
+
2103
+        $_options = memoriser_contexte_compil($p);
2104
+        $_options = "'compil'=>array($_options), 'trim'=>true";
2105
+        if (isset($_contexte['ajax'])) {
2106
+            $_options .= ', ' . preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
2107
+            unset($_contexte['ajax']);
2108
+        }
2109
+
2110
+        $_l = 'array(' . join(",\n\t", $_contexte) . ')';
2111
+        if ($flag_env) {
2112
+            $_l = "array_merge(\$Pile[0],$_l)";
2113
+        }
2114
+
2115
+        $page = sprintf(CODE_RECUPERER_FOND, $nom, $_l, $_options, _q($connect));
2116
+
2117
+        $p->code = "\n\t(((\$recurs=(isset(\$Pile[0]['recurs'])?\$Pile[0]['recurs']:0))>=5)? '' :\n\t$page)\n";
2118
+
2119
+        $p->interdire_scripts = false; // securite assuree par le squelette
2120
+    }
2121
+
2122
+    return $p;
2123 2123
 }
2124 2124
 
2125 2125
 
@@ -2143,21 +2143,21 @@  discard block
 block discarded – undo
2143 2143
  *     Pile complétée par le code à générer
2144 2144
  **/
2145 2145
 function balise_SET_dist($p) {
2146
-	$_nom = interprete_argument_balise(1, $p);
2147
-	$_val = interprete_argument_balise(2, $p);
2146
+    $_nom = interprete_argument_balise(1, $p);
2147
+    $_val = interprete_argument_balise(2, $p);
2148 2148
 
2149
-	if (!$_nom || !$_val) {
2150
-		$err_b_s_a = ['zbug_balise_sans_argument', ['balise' => 'SET']];
2151
-		erreur_squelette($err_b_s_a, $p);
2152
-	}
2153
-	// affectation $_zzz inutile, mais permet de contourner un bug OpCode cache sous PHP 5.5.4
2154
-	// cf https://bugs.php.net/bug.php?id=65845
2155
-	else {
2156
-		$p->code = "vide(\$Pile['vars'][\$_zzz=(string)$_nom] = $_val)";
2157
-	}
2149
+    if (!$_nom || !$_val) {
2150
+        $err_b_s_a = ['zbug_balise_sans_argument', ['balise' => 'SET']];
2151
+        erreur_squelette($err_b_s_a, $p);
2152
+    }
2153
+    // affectation $_zzz inutile, mais permet de contourner un bug OpCode cache sous PHP 5.5.4
2154
+    // cf https://bugs.php.net/bug.php?id=65845
2155
+    else {
2156
+        $p->code = "vide(\$Pile['vars'][\$_zzz=(string)$_nom] = $_val)";
2157
+    }
2158 2158
 
2159
-	$p->interdire_scripts = false; // la balise ne renvoie rien
2160
-	return $p;
2159
+    $p->interdire_scripts = false; // la balise ne renvoie rien
2160
+    return $p;
2161 2161
 }
2162 2162
 
2163 2163
 
@@ -2187,12 +2187,12 @@  discard block
 block discarded – undo
2187 2187
  *     Pile complétée par le code à générer
2188 2188
  **/
2189 2189
 function balise_GET_dist($p) {
2190
-	$p->interdire_scripts = false; // le contenu vient de #SET, donc il est de confiance
2191
-	if (function_exists('balise_ENV')) {
2192
-		return balise_ENV($p, '$Pile["vars"]??[]');
2193
-	} else {
2194
-		return balise_ENV_dist($p, '$Pile["vars"]??[]');
2195
-	}
2190
+    $p->interdire_scripts = false; // le contenu vient de #SET, donc il est de confiance
2191
+    if (function_exists('balise_ENV')) {
2192
+        return balise_ENV($p, '$Pile["vars"]??[]');
2193
+    } else {
2194
+        return balise_ENV_dist($p, '$Pile["vars"]??[]');
2195
+    }
2196 2196
 }
2197 2197
 
2198 2198
 
@@ -2215,22 +2215,22 @@  discard block
 block discarded – undo
2215 2215
  *     Pile complétée par le code à générer
2216 2216
  **/
2217 2217
 function balise_DOUBLONS_dist($p) {
2218
-	if ($type = interprete_argument_balise(1, $p)) {
2219
-		if ($famille = interprete_argument_balise(2, $p)) {
2220
-			$type .= '.' . $famille;
2221
-		}
2222
-		$p->code = '(isset($doublons[' . $type . ']) ? $doublons[' . $type . '] : "")';
2223
-		if (!$p->etoile) {
2224
-			$p->code = 'array_filter(array_map("intval",explode(",",'
2225
-				. $p->code . ')))';
2226
-		}
2227
-	} else {
2228
-		$p->code = '$doublons';
2229
-	}
2218
+    if ($type = interprete_argument_balise(1, $p)) {
2219
+        if ($famille = interprete_argument_balise(2, $p)) {
2220
+            $type .= '.' . $famille;
2221
+        }
2222
+        $p->code = '(isset($doublons[' . $type . ']) ? $doublons[' . $type . '] : "")';
2223
+        if (!$p->etoile) {
2224
+            $p->code = 'array_filter(array_map("intval",explode(",",'
2225
+                . $p->code . ')))';
2226
+        }
2227
+    } else {
2228
+        $p->code = '$doublons';
2229
+    }
2230 2230
 
2231
-	$p->interdire_scripts = false;
2231
+    $p->interdire_scripts = false;
2232 2232
 
2233
-	return $p;
2233
+    return $p;
2234 2234
 }
2235 2235
 
2236 2236
 
@@ -2253,18 +2253,18 @@  discard block
 block discarded – undo
2253 2253
  *     Pile complétée par le code à générer
2254 2254
  **/
2255 2255
 function balise_PIPELINE_dist($p) {
2256
-	$_pipe = interprete_argument_balise(1, $p);
2257
-	if (!$_pipe) {
2258
-		$err_b_s_a = ['zbug_balise_sans_argument', ['balise' => 'PIPELINE']];
2259
-		erreur_squelette($err_b_s_a, $p);
2260
-	} else {
2261
-		$_flux = interprete_argument_balise(2, $p);
2262
-		$_flux = $_flux ?: "''";
2263
-		$p->code = "pipeline( $_pipe , $_flux )";
2264
-		$p->interdire_scripts = false;
2265
-	}
2256
+    $_pipe = interprete_argument_balise(1, $p);
2257
+    if (!$_pipe) {
2258
+        $err_b_s_a = ['zbug_balise_sans_argument', ['balise' => 'PIPELINE']];
2259
+        erreur_squelette($err_b_s_a, $p);
2260
+    } else {
2261
+        $_flux = interprete_argument_balise(2, $p);
2262
+        $_flux = $_flux ?: "''";
2263
+        $p->code = "pipeline( $_pipe , $_flux )";
2264
+        $p->interdire_scripts = false;
2265
+    }
2266 2266
 
2267
-	return $p;
2267
+    return $p;
2268 2268
 }
2269 2269
 
2270 2270
 
@@ -2289,10 +2289,10 @@  discard block
 block discarded – undo
2289 2289
  *     Pile complétée par le code à générer
2290 2290
  **/
2291 2291
 function balise_EDIT_dist($p) {
2292
-	$p->code = "''";
2293
-	$p->interdire_scripts = false;
2292
+    $p->code = "''";
2293
+    $p->interdire_scripts = false;
2294 2294
 
2295
-	return $p;
2295
+    return $p;
2296 2296
 }
2297 2297
 
2298 2298
 
@@ -2315,11 +2315,11 @@  discard block
 block discarded – undo
2315 2315
  *     Pile complétée par le code à générer
2316 2316
  **/
2317 2317
 function balise_TOTAL_UNIQUE_dist($p) {
2318
-	$_famille = interprete_argument_balise(1, $p);
2319
-	$_famille = $_famille ?: "''";
2320
-	$p->code = "unique('', $_famille, true)";
2318
+    $_famille = interprete_argument_balise(1, $p);
2319
+    $_famille = $_famille ?: "''";
2320
+    $p->code = "unique('', $_famille, true)";
2321 2321
 
2322
-	return $p;
2322
+    return $p;
2323 2323
 }
2324 2324
 
2325 2325
 /**
@@ -2342,19 +2342,19 @@  discard block
 block discarded – undo
2342 2342
  *     Pile complétée par le code à générer
2343 2343
  **/
2344 2344
 function balise_ARRAY_dist($p) {
2345
-	$_code = [];
2346
-	$n = 1;
2347
-	do {
2348
-		$_key = interprete_argument_balise($n++, $p);
2349
-		$_val = interprete_argument_balise($n++, $p);
2350
-		if ($_key && $_val) {
2351
-			$_code[] = "$_key => $_val";
2352
-		}
2353
-	} while ($_key && $_val);
2354
-	$p->code = 'array(' . join(', ', $_code) . ')';
2355
-	$p->interdire_scripts = false;
2345
+    $_code = [];
2346
+    $n = 1;
2347
+    do {
2348
+        $_key = interprete_argument_balise($n++, $p);
2349
+        $_val = interprete_argument_balise($n++, $p);
2350
+        if ($_key && $_val) {
2351
+            $_code[] = "$_key => $_val";
2352
+        }
2353
+    } while ($_key && $_val);
2354
+    $p->code = 'array(' . join(', ', $_code) . ')';
2355
+    $p->interdire_scripts = false;
2356 2356
 
2357
-	return $p;
2357
+    return $p;
2358 2358
 }
2359 2359
 
2360 2360
 /**
@@ -2373,15 +2373,15 @@  discard block
 block discarded – undo
2373 2373
  *     Pile complétée par le code à générer
2374 2374
  */
2375 2375
 function balise_LISTE_dist($p) {
2376
-	$_code = [];
2377
-	$n = 1;
2378
-	while ($_val = interprete_argument_balise($n++, $p)) {
2379
-		$_code[] = $_val;
2380
-	}
2381
-	$p->code = 'array(' . join(', ', $_code) . ')';
2382
-	$p->interdire_scripts = false;
2376
+    $_code = [];
2377
+    $n = 1;
2378
+    while ($_val = interprete_argument_balise($n++, $p)) {
2379
+        $_code[] = $_val;
2380
+    }
2381
+    $p->code = 'array(' . join(', ', $_code) . ')';
2382
+    $p->interdire_scripts = false;
2383 2383
 
2384
-	return $p;
2384
+    return $p;
2385 2385
 }
2386 2386
 
2387 2387
 
@@ -2415,21 +2415,21 @@  discard block
 block discarded – undo
2415 2415
  *     Pile complétée par le code à générer
2416 2416
  **/
2417 2417
 function balise_AUTORISER_dist($p) {
2418
-	$_code = [];
2419
-	$p->descr['session'] = true; // faire un cache par session
2418
+    $_code = [];
2419
+    $p->descr['session'] = true; // faire un cache par session
2420 2420
 
2421
-	$n = 1;
2422
-	while ($_v = interprete_argument_balise($n++, $p)) {
2423
-		$_code[] = $_v;
2424
-	}
2421
+    $n = 1;
2422
+    while ($_v = interprete_argument_balise($n++, $p)) {
2423
+        $_code[] = $_v;
2424
+    }
2425 2425
 
2426
-	$p->code = '((function_exists("autoriser")||include_spip("inc/autoriser"))&&autoriser(' . join(
2427
-		', ',
2428
-		$_code
2429
-	) . ')?" ":"")';
2430
-	$p->interdire_scripts = false;
2426
+    $p->code = '((function_exists("autoriser")||include_spip("inc/autoriser"))&&autoriser(' . join(
2427
+        ', ',
2428
+        $_code
2429
+    ) . ')?" ":"")';
2430
+    $p->interdire_scripts = false;
2431 2431
 
2432
-	return $p;
2432
+    return $p;
2433 2433
 }
2434 2434
 
2435 2435
 
@@ -2453,15 +2453,15 @@  discard block
 block discarded – undo
2453 2453
  *     Pile complétée par le code à générer
2454 2454
  **/
2455 2455
 function balise_PLUGIN_dist($p) {
2456
-	$plugin = interprete_argument_balise(1, $p);
2457
-	$plugin = isset($plugin) ? str_replace('\'', '"', $plugin) : '""';
2458
-	$type_info = interprete_argument_balise(2, $p);
2459
-	$type_info = isset($type_info) ? str_replace('\'', '"', $type_info) : '"est_actif"';
2456
+    $plugin = interprete_argument_balise(1, $p);
2457
+    $plugin = isset($plugin) ? str_replace('\'', '"', $plugin) : '""';
2458
+    $type_info = interprete_argument_balise(2, $p);
2459
+    $type_info = isset($type_info) ? str_replace('\'', '"', $type_info) : '"est_actif"';
2460 2460
 
2461
-	$f = chercher_filtre('info_plugin');
2462
-	$p->code = $f . '(' . $plugin . ', ' . $type_info . ')';
2461
+    $f = chercher_filtre('info_plugin');
2462
+    $p->code = $f . '(' . $plugin . ', ' . $type_info . ')';
2463 2463
 
2464
-	return $p;
2464
+    return $p;
2465 2465
 }
2466 2466
 
2467 2467
 /**
@@ -2482,9 +2482,9 @@  discard block
 block discarded – undo
2482 2482
  *     Pile complétée par le code à générer
2483 2483
  **/
2484 2484
 function balise_AIDER_dist($p) {
2485
-	$_motif = interprete_argument_balise(1, $p);
2486
-	$p->code = "((\$aider=charger_fonction('aide','inc',true))?\$aider($_motif):'')";
2487
-	return $p;
2485
+    $_motif = interprete_argument_balise(1, $p);
2486
+    $p->code = "((\$aider=charger_fonction('aide','inc',true))?\$aider($_motif):'')";
2487
+    return $p;
2488 2488
 }
2489 2489
 
2490 2490
 /**
@@ -2510,16 +2510,16 @@  discard block
 block discarded – undo
2510 2510
  *     Pile complétée par le code à générer
2511 2511
  **/
2512 2512
 function balise_ACTION_FORMULAIRE($p) {
2513
-	if (!$_url = interprete_argument_balise(1, $p)) {
2514
-		$_url = "(\$Pile[0]['action'] ?? '')";
2515
-	}
2516
-	if (!$_form = interprete_argument_balise(2, $p)) {
2517
-		$_form = "(\$Pile[0]['form'] ?? '')";
2518
-	}
2519
-
2520
-	// envoyer le nom du formulaire que l'on traite
2521
-	// transmettre les eventuels args de la balise formulaire
2522
-	$p->code = "	'<span class=\"form-hidden\">' .
2513
+    if (!$_url = interprete_argument_balise(1, $p)) {
2514
+        $_url = "(\$Pile[0]['action'] ?? '')";
2515
+    }
2516
+    if (!$_form = interprete_argument_balise(2, $p)) {
2517
+        $_form = "(\$Pile[0]['form'] ?? '')";
2518
+    }
2519
+
2520
+    // envoyer le nom du formulaire que l'on traite
2521
+    // transmettre les eventuels args de la balise formulaire
2522
+    $p->code = "	'<span class=\"form-hidden\">' .
2523 2523
 	form_hidden($_url) .
2524 2524
 	'<input name=\'formulaire_action\' type=\'hidden\'
2525 2525
 		value=\'' . $_form . '\' />' .
@@ -2530,9 +2530,9 @@  discard block
 block discarded – undo
2530 2530
 	(\$Pile[0]['_hidden'] ?? '') .
2531 2531
 	'</span>'";
2532 2532
 
2533
-	$p->interdire_scripts = false;
2533
+    $p->interdire_scripts = false;
2534 2534
 
2535
-	return $p;
2535
+    return $p;
2536 2536
 }
2537 2537
 
2538 2538
 
@@ -2573,25 +2573,25 @@  discard block
 block discarded – undo
2573 2573
  */
2574 2574
 function balise_BOUTON_ACTION_dist($p) {
2575 2575
 
2576
-	$args = [];
2577
-	for ($k = 1; $k <= 6; $k++) {
2578
-		$_a = interprete_argument_balise($k, $p);
2579
-		if (!$_a) {
2580
-			$_a = "''";
2581
-		}
2582
-		$args[] = $_a;
2583
-	}
2584
-	// supprimer les args vides
2585
-	while (end($args) == "''" && count($args) > 2) {
2586
-		array_pop($args);
2587
-	}
2588
-	$args = implode(',', $args);
2576
+    $args = [];
2577
+    for ($k = 1; $k <= 6; $k++) {
2578
+        $_a = interprete_argument_balise($k, $p);
2579
+        if (!$_a) {
2580
+            $_a = "''";
2581
+        }
2582
+        $args[] = $_a;
2583
+    }
2584
+    // supprimer les args vides
2585
+    while (end($args) == "''" && count($args) > 2) {
2586
+        array_pop($args);
2587
+    }
2588
+    $args = implode(',', $args);
2589 2589
 
2590
-	$bouton_action = chercher_filtre('bouton_action');
2591
-	$p->code = "$bouton_action($args)";
2592
-	$p->interdire_scripts = false;
2590
+    $bouton_action = chercher_filtre('bouton_action');
2591
+    $p->code = "$bouton_action($args)";
2592
+    $p->interdire_scripts = false;
2593 2593
 
2594
-	return $p;
2594
+    return $p;
2595 2595
 }
2596 2596
 
2597 2597
 
@@ -2610,10 +2610,10 @@  discard block
 block discarded – undo
2610 2610
  *     Pile complétée par le code à générer
2611 2611
  */
2612 2612
 function balise_SLOGAN_SITE_SPIP_dist($p) {
2613
-	$p->code = "\$GLOBALS['meta']['slogan_site']";
2613
+    $p->code = "\$GLOBALS['meta']['slogan_site']";
2614 2614
 
2615
-	#$p->interdire_scripts = true;
2616
-	return $p;
2615
+    #$p->interdire_scripts = true;
2616
+    return $p;
2617 2617
 }
2618 2618
 
2619 2619
 
@@ -2637,10 +2637,10 @@  discard block
 block discarded – undo
2637 2637
  *     Pile complétée par le code à générer
2638 2638
  */
2639 2639
 function balise_HTML5_dist($p) {
2640
-	$p->code = html5_permis() ? "' '" : "''";
2641
-	$p->interdire_scripts = false;
2640
+    $p->code = html5_permis() ? "' '" : "''";
2641
+    $p->interdire_scripts = false;
2642 2642
 
2643
-	return $p;
2643
+    return $p;
2644 2644
 }
2645 2645
 
2646 2646
 
@@ -2666,60 +2666,60 @@  discard block
 block discarded – undo
2666 2666
  *     Pile complétée par le code à générer
2667 2667
  */
2668 2668
 function balise_TRI_dist($p, $liste = 'true') {
2669
-	$b = index_boucle_mere($p);
2670
-	// s'il n'y a pas de nom de boucle, on ne peut pas trier
2671
-	if ($b === '') {
2672
-		$msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
2673
-		erreur_squelette($msg, $p);
2674
-		$p->code = "''";
2669
+    $b = index_boucle_mere($p);
2670
+    // s'il n'y a pas de nom de boucle, on ne peut pas trier
2671
+    if ($b === '') {
2672
+        $msg = ['zbug_champ_hors_boucle', ['champ' => zbug_presenter_champ($p)]];
2673
+        erreur_squelette($msg, $p);
2674
+        $p->code = "''";
2675 2675
 
2676
-		return $p;
2677
-	}
2678
-	$boucle = $p->boucles[$b];
2676
+        return $p;
2677
+    }
2678
+    $boucle = $p->boucles[$b];
2679 2679
 
2680
-	// s'il n'y a pas de tri_champ, c'est qu'on se trouve
2681
-	// dans un boucle recursive ou qu'on a oublie le critere {tri}
2682
-	if (!isset($boucle->modificateur['tri_champ'])) {
2683
-		$msg = ['zbug_champ_hors_critere', [
2684
-			'champ' => zbug_presenter_champ($p),
2685
-			'critere' => 'tri'
2686
-		]];
2687
-		erreur_squelette($msg, $p);
2688
-		$p->code = "''";
2680
+    // s'il n'y a pas de tri_champ, c'est qu'on se trouve
2681
+    // dans un boucle recursive ou qu'on a oublie le critere {tri}
2682
+    if (!isset($boucle->modificateur['tri_champ'])) {
2683
+        $msg = ['zbug_champ_hors_critere', [
2684
+            'champ' => zbug_presenter_champ($p),
2685
+            'critere' => 'tri'
2686
+        ]];
2687
+        erreur_squelette($msg, $p);
2688
+        $p->code = "''";
2689 2689
 
2690
-		return $p;
2691
-	}
2690
+        return $p;
2691
+    }
2692 2692
 
2693
-	// Différentes infos relatives au tri présentes dans les modificateurs
2694
-	$_tri_nom = $boucle->modificateur['tri_nom'] ; // nom du paramètre définissant le tri
2695
-	$_tri_champ = $boucle->modificateur['tri_champ']; // champ actuel utilisé le tri
2696
-	$_tri_sens = $boucle->modificateur['tri_sens']; // sens de tri actuel
2697
-	$_tri_liste_sens_defaut = $boucle->modificateur['tri_liste_sens_defaut']; // sens par défaut pour chaque champ
2693
+    // Différentes infos relatives au tri présentes dans les modificateurs
2694
+    $_tri_nom = $boucle->modificateur['tri_nom'] ; // nom du paramètre définissant le tri
2695
+    $_tri_champ = $boucle->modificateur['tri_champ']; // champ actuel utilisé le tri
2696
+    $_tri_sens = $boucle->modificateur['tri_sens']; // sens de tri actuel
2697
+    $_tri_liste_sens_defaut = $boucle->modificateur['tri_liste_sens_defaut']; // sens par défaut pour chaque champ
2698 2698
 
2699
-	$_champ_ou_sens = interprete_argument_balise(1, $p);
2700
-	// si pas de champ, renvoyer le critère de tri actuel
2701
-	if (!$_champ_ou_sens) {
2702
-		$p->code = $_tri_champ;
2699
+    $_champ_ou_sens = interprete_argument_balise(1, $p);
2700
+    // si pas de champ, renvoyer le critère de tri actuel
2701
+    if (!$_champ_ou_sens) {
2702
+        $p->code = $_tri_champ;
2703 2703
 
2704
-		return $p;
2705
-	}
2706
-	// forcer la jointure si besoin, et si le champ est statique
2707
-	if (preg_match(",^'([\w.]+)'$,i", $_champ_ou_sens, $m)) {
2708
-		index_pile($b, $m[1], $p->boucles, '', null, true, false);
2709
-	}
2704
+        return $p;
2705
+    }
2706
+    // forcer la jointure si besoin, et si le champ est statique
2707
+    if (preg_match(",^'([\w.]+)'$,i", $_champ_ou_sens, $m)) {
2708
+        index_pile($b, $m[1], $p->boucles, '', null, true, false);
2709
+    }
2710 2710
 
2711
-	$_libelle = interprete_argument_balise(2, $p);
2712
-	$_libelle = $_libelle ?: $_champ_ou_sens;
2711
+    $_libelle = interprete_argument_balise(2, $p);
2712
+    $_libelle = $_libelle ?: $_champ_ou_sens;
2713 2713
 
2714
-	$_class = interprete_argument_balise(3, $p) ?? "''";
2714
+    $_class = interprete_argument_balise(3, $p) ?? "''";
2715 2715
 
2716
-	$nom_pagination = $boucle->modificateur['debut_nom'] ?? '';
2716
+    $nom_pagination = $boucle->modificateur['debut_nom'] ?? '';
2717 2717
 
2718
-	$p->code = "calculer_balise_tri($_champ_ou_sens, $_libelle, $_class, $_tri_nom, $_tri_champ, $_tri_sens, $_tri_liste_sens_defaut, $nom_pagination)";
2718
+    $p->code = "calculer_balise_tri($_champ_ou_sens, $_libelle, $_class, $_tri_nom, $_tri_champ, $_tri_sens, $_tri_liste_sens_defaut, $nom_pagination)";
2719 2719
 
2720
-	$p->interdire_scripts = false;
2720
+    $p->interdire_scripts = false;
2721 2721
 
2722
-	return $p;
2722
+    return $p;
2723 2723
 }
2724 2724
 
2725 2725
 
@@ -2740,21 +2740,21 @@  discard block
 block discarded – undo
2740 2740
  *     Pile complétée par le code à générer
2741 2741
  */
2742 2742
 function balise_SAUTER_dist($p) {
2743
-	$id_boucle = $p->id_boucle;
2743
+    $id_boucle = $p->id_boucle;
2744 2744
 
2745
-	if (empty($p->boucles[$id_boucle])) {
2746
-		$msg = ['zbug_champ_hors_boucle', ['champ' => '#SAUTER']];
2747
-		erreur_squelette($msg, $p);
2748
-	} else {
2749
-		$_saut = interprete_argument_balise(1, $p);
2750
-		$_compteur = "\$Numrows['$id_boucle']['compteur_boucle']";
2751
-		$_total = "(\$Numrows['$id_boucle']['total'] ?? null)";
2745
+    if (empty($p->boucles[$id_boucle])) {
2746
+        $msg = ['zbug_champ_hors_boucle', ['champ' => '#SAUTER']];
2747
+        erreur_squelette($msg, $p);
2748
+    } else {
2749
+        $_saut = interprete_argument_balise(1, $p);
2750
+        $_compteur = "\$Numrows['$id_boucle']['compteur_boucle']";
2751
+        $_total = "(\$Numrows['$id_boucle']['total'] ?? null)";
2752 2752
 
2753
-		$p->code = "vide($_compteur=\$iter->skip($_saut,$_total))";
2754
-	}
2755
-	$p->interdire_scripts = false;
2753
+        $p->code = "vide($_compteur=\$iter->skip($_saut,$_total))";
2754
+    }
2755
+    $p->interdire_scripts = false;
2756 2756
 
2757
-	return $p;
2757
+    return $p;
2758 2758
 }
2759 2759
 
2760 2760
 
@@ -2776,22 +2776,22 @@  discard block
 block discarded – undo
2776 2776
  *     Pile complétée par le code à générer
2777 2777
  */
2778 2778
 function balise_PUBLIE_dist($p) {
2779
-	if (!$_type = interprete_argument_balise(1, $p)) {
2780
-		$_type = _q($p->type_requete);
2781
-		$_id = champ_sql($p->boucles[$p->id_boucle]->primary, $p);
2782
-	} else {
2783
-		$_id = interprete_argument_balise(2, $p);
2784
-	}
2779
+    if (!$_type = interprete_argument_balise(1, $p)) {
2780
+        $_type = _q($p->type_requete);
2781
+        $_id = champ_sql($p->boucles[$p->id_boucle]->primary, $p);
2782
+    } else {
2783
+        $_id = interprete_argument_balise(2, $p);
2784
+    }
2785 2785
 
2786
-	$connect = '';
2787
-	if (isset($p->boucles[$p->id_boucle])) {
2788
-		$connect = $p->boucles[$p->id_boucle]->sql_serveur;
2789
-	}
2786
+    $connect = '';
2787
+    if (isset($p->boucles[$p->id_boucle])) {
2788
+        $connect = $p->boucles[$p->id_boucle]->sql_serveur;
2789
+    }
2790 2790
 
2791
-	$p->code = '(objet_test_si_publie(' . $_type . ',intval(' . $_id . '),' . _q($connect) . ")?' ':'')";
2792
-	$p->interdire_scripts = false;
2791
+    $p->code = '(objet_test_si_publie(' . $_type . ',intval(' . $_id . '),' . _q($connect) . ")?' ':'')";
2792
+    $p->interdire_scripts = false;
2793 2793
 
2794
-	return $p;
2794
+    return $p;
2795 2795
 }
2796 2796
 
2797 2797
 /**
@@ -2820,12 +2820,12 @@  discard block
 block discarded – undo
2820 2820
  *     Pile complétée par le code à générer
2821 2821
  */
2822 2822
 function balise_PRODUIRE_dist($p) {
2823
-	$balise_inclure = charger_fonction('INCLURE', 'balise');
2824
-	$p = $balise_inclure($p);
2823
+    $balise_inclure = charger_fonction('INCLURE', 'balise');
2824
+    $p = $balise_inclure($p);
2825 2825
 
2826
-	$p->code = str_replace('recuperer_fond(', 'produire_fond_statique(', $p->code);
2826
+    $p->code = str_replace('recuperer_fond(', 'produire_fond_statique(', $p->code);
2827 2827
 
2828
-	return $p;
2828
+    return $p;
2829 2829
 }
2830 2830
 
2831 2831
 /**
@@ -2844,13 +2844,13 @@  discard block
 block discarded – undo
2844 2844
  *     Pile complétée par le code à générer
2845 2845
  */
2846 2846
 function balise_LARGEUR_ECRAN_dist($p) {
2847
-	$_class = interprete_argument_balise(1, $p);
2848
-	if (!$_class) {
2849
-		$_class = 'null';
2850
-	}
2851
-	$p->code = "(is_string($_class)?vide(\$GLOBALS['largeur_ecran']=$_class):(isset(\$GLOBALS['largeur_ecran'])?\$GLOBALS['largeur_ecran']:''))";
2847
+    $_class = interprete_argument_balise(1, $p);
2848
+    if (!$_class) {
2849
+        $_class = 'null';
2850
+    }
2851
+    $p->code = "(is_string($_class)?vide(\$GLOBALS['largeur_ecran']=$_class):(isset(\$GLOBALS['largeur_ecran'])?\$GLOBALS['largeur_ecran']:''))";
2852 2852
 
2853
-	return $p;
2853
+    return $p;
2854 2854
 }
2855 2855
 
2856 2856
 
@@ -2866,14 +2866,14 @@  discard block
 block discarded – undo
2866 2866
  *     Pile complétée par le code à générer
2867 2867
  **/
2868 2868
 function balise_CONST_dist($p) {
2869
-	$_const = interprete_argument_balise(1, $p);
2870
-	if (!strlen($_const ?? '')) {
2871
-		$p->code = "''";
2872
-	}
2873
-	else {
2874
-		$p->code = "(defined($_const)?constant($_const):'')";
2875
-	}
2876
-	$p->interdire_scripts = false;
2877
-
2878
-	return $p;
2869
+    $_const = interprete_argument_balise(1, $p);
2870
+    if (!strlen($_const ?? '')) {
2871
+        $p->code = "''";
2872
+    }
2873
+    else {
2874
+        $p->code = "(defined($_const)?constant($_const):'')";
2875
+    }
2876
+    $p->interdire_scripts = false;
2877
+
2878
+    return $p;
2879 2879
 }
Please login to merge, or discard this patch.
ecrire/public/styliser_par_z.php 1 patch
Indentation   +305 added lines, -305 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  * @package SPIP\Core\Public\Styliser
19 19
  **/
20 20
 if (!defined('_ECRIRE_INC_VERSION')) {
21
-	return;
21
+    return;
22 22
 }
23 23
 
24 24
 /**
@@ -28,190 +28,190 @@  discard block
 block discarded – undo
28 28
  * @return array Données modifiées du pipeline
29 29
  */
30 30
 function public_styliser_par_z_dist($flux) {
31
-	static $prefix_path = null;
32
-	static $prefix_length;
33
-	static $z_blocs;
34
-	static $apl_constant;
35
-	static $page;
36
-	static $disponible = [];
37
-	static $echafauder;
38
-	static $prepend = '';
39
-
40
-	if (!isset($prefix_path)) {
41
-		$z_blocs = z_blocs(test_espace_prive());
42
-		if (test_espace_prive()) {
43
-			$prefix_path = 'prive/squelettes/';
44
-			$prefix_length = strlen($prefix_path);
45
-			$apl_constant = '_ECRIRE_AJAX_PARALLEL_LOAD';
46
-			$page = 'exec';
47
-			$echafauder = charger_fonction('echafauder', 'prive', true);
48
-			define('_ZCORE_EXCLURE_PATH', '');
49
-		} else {
50
-			$prefix_path = '';
51
-			$prefix_length = 0;
52
-			$apl_constant = '_Z_AJAX_PARALLEL_LOAD';
53
-			$page = _SPIP_PAGE;
54
-			$echafauder = charger_fonction('echafauder', 'public', true);
55
-			define('_ZCORE_EXCLURE_PATH', '\bprive|\bsquelettes-dist' . (defined('_DIR_PLUGIN_DIST') ? '|\b' . rtrim(
56
-				(string) _DIR_PLUGIN_DIST,
57
-				'/'
58
-			) : ''));
59
-		}
60
-		$prepend = (defined('_Z_PREPEND_PATH') ? _Z_PREPEND_PATH : '');
61
-	}
62
-	$z_contenu = reset($z_blocs); // contenu par defaut
63
-
64
-	$fond = $flux['args']['fond'];
65
-
66
-	if ($prepend || strncmp((string) $fond, (string) $prefix_path, $prefix_length) == 0) {
67
-		$fond = substr((string) $fond, $prefix_length);
68
-		$squelette = $flux['data'];
69
-		$ext = $flux['args']['ext'];
70
-		// Ajax Parallel loading : ne pas calculer le bloc, mais renvoyer un js qui le loadera en ajax
71
-		if (
72
-			defined('_Z_AJAX_PARALLEL_LOAD_OK')
73
-			&& ($dir = explode('/', $fond))
74
-			&& count($dir) == 2 // pas un sous repertoire
75
-			&& ($dir = reset($dir))
76
-			&& in_array($dir, $z_blocs) // verifier deja qu'on est dans un bloc Z
77
-			&& defined($apl_constant)
78
-			&& in_array($dir, explode(',', (string) constant($apl_constant))) // et dans un demande en APL
79
-			&& ($pipe = z_trouver_bloc($prefix_path . $prepend, $dir, 'z_apl', $ext)) // et qui contient le squelette APL
80
-		) {
81
-			$flux['data'] = $pipe;
82
-
83
-			return $flux;
84
-		}
85
-
86
-		// surcharger aussi les squelettes venant de squelettes-dist/
87
-		if ($squelette && !z_fond_valide($squelette)) {
88
-			$squelette = '';
89
-			$echafauder = '';
90
-		}
91
-		if ($prepend) {
92
-			$squelette = substr((string) find_in_path($prefix_path . $prepend . "$fond.$ext"), 0, -strlen(".$ext"));
93
-			if ($squelette) {
94
-				$flux['data'] = $squelette;
95
-			}
96
-		}
97
-
98
-		// gerer les squelettes non trouves
99
-		// -> router vers les /dist.html
100
-		// ou scaffolding ou page automatique les contenus
101
-		if (!$squelette) {
102
-			// si on est sur un ?page=XX non trouve
103
-			if (
104
-				isset($flux['args']['contexte'][$page]) && $flux['args']['contexte'][$page] == $fond
105
-				|| isset($flux['args']['contexte']['type-page']) && $flux['args']['contexte']['type-page'] == $fond
106
-				|| $fond == 'sommaire' && (!isset($flux['args']['contexte'][$page]) || !$flux['args']['contexte'][$page])
107
-			) {
108
-				// si on est sur un ?page=XX non trouve
109
-				// se brancher sur contenu/xx si il existe
110
-				// ou si c'est un objet spip, associe a une table, utiliser le fond homonyme
111
-				if (!isset($disponible[$fond])) {
112
-					$disponible[$fond] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $fond, $ext, (bool) $echafauder);
113
-				}
114
-
115
-				if ($disponible[$fond]) {
116
-					$flux['data'] = substr((string) find_in_path($prefix_path . "page.$ext"), 0, -strlen(".$ext"));
117
-				}
118
-			}
119
-
120
-			// echafaudage :
121
-			// si c'est un fond de contenu d'un objet en base
122
-			// generer un fond automatique a la volee pour les webmestres
123
-			elseif (strncmp($fond, "$z_contenu/", strlen((string) $z_contenu) + 1) == 0) {
124
-				$type = substr($fond, strlen((string) $z_contenu) + 1);
125
-				if ($type == 'page' && isset($flux['args']['contexte'][$page])) {
126
-					$type = $flux['args']['contexte'][$page];
127
-				}
128
-				if (!isset($disponible[$type])) {
129
-					$disponible[$type] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $type, $ext, (bool) $echafauder);
130
-				}
131
-				if (is_string($disponible[$type])) {
132
-					$flux['data'] = $disponible[$type];
133
-				} elseif (
134
-					$echafauder
135
-					&& include_spip('inc/autoriser')
136
-					&& isset($GLOBALS['visiteur_session']['statut'])
137
-					&& autoriser('echafauder', $type)
138
-					&& ($is = $disponible[$type])
139
-					&& is_array($is)
140
-				) {
141
-					$flux['data'] = $echafauder($type, $is[0], $is[1], $is[2], $ext);
142
-				} else {
143
-					$flux['data'] = ($disponible['404'] = z_contenu_disponible(
144
-						$prefix_path . $prepend,
145
-						$z_contenu,
146
-						'404',
147
-						$ext,
148
-						(bool) $echafauder
149
-					));
150
-				}
151
-			}
152
-
153
-			// sinon, si on demande un fond non trouve dans un des autres blocs
154
-			// et si il y a bien un contenu correspondant ou echafaudable
155
-			// se rabbatre sur le dist.html du bloc concerne
156
-			else {
157
-				if (
158
-					($dir = explode('/', $fond))
159
-					&& ($dir = reset($dir))
160
-					&& $dir !== $z_contenu
161
-					&& in_array($dir, $z_blocs)
162
-				) {
163
-					$type = substr($fond, strlen("$dir/"));
164
-					if ($type == 'page' && isset($flux['args']['contexte'][$page])) {
165
-						$type = $flux['args']['contexte'][$page];
166
-					}
167
-					if ($type !== 'page' && !isset($disponible[$type])) {
168
-						$disponible[$type] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $type, $ext, (bool) $echafauder);
169
-					}
170
-					if ($type == 'page' || $disponible[$type]) {
171
-						$flux['data'] = z_trouver_bloc($prefix_path . $prepend, $dir, 'dist', $ext);
172
-					}
173
-				}
174
-			}
175
-			$squelette = $flux['data'];
176
-		}
177
-
178
-		// layout specifiques par type et compositions :
179
-		// body-article.html
180
-		// body-sommaire.html
181
-		// pour des raisons de perfo, les declinaisons doivent etre dans le
182
-		// meme dossier que body.html
183
-		$f = null;
184
-		if ($fond == 'body' && str_ends_with((string) $squelette, $fond)) {
185
-			if (
186
-				isset($flux['args']['contexte']['type-page'])
187
-				&& (
188
-					isset($flux['args']['contexte']['composition']) && file_exists(($f = $squelette . '-' . $flux['args']['contexte']['type-page'] . '-' . $flux['args']['contexte']['composition']) . ".$ext")
189
-					|| file_exists(($f = $squelette . '-' . $flux['args']['contexte']['type-page']) . ".$ext")
190
-				)
191
-			) {
192
-				$flux['data'] = $f;
193
-			}
194
-		} elseif (
195
-			$fond == 'structure'
196
-			&& z_sanitize_var_zajax()
197
-			&& ($f = find_in_path($prefix_path . $prepend . 'ajax' . ".$ext"))
198
-		) {
199
-			$flux['data'] = substr((string) $f, 0, -strlen(".$ext"));
200
-		} elseif (
201
-			// chercher le fond correspondant a la composition
202
-			isset($flux['args']['contexte']['composition'])
203
-			&& (basename($fond) == 'page' || $squelette && str_ends_with((string) $squelette, $fond))
204
-			&& ($dir = substr($fond, $prefix_length))
205
-			&& ($dir = explode('/', $dir))
206
-			&& ($dir = reset($dir))
207
-			&& in_array($dir, $z_blocs)
208
-			&& ($f = find_in_path($prefix_path . $prepend . $fond . '-' . $flux['args']['contexte']['composition'] . ".$ext"))
209
-		) {
210
-			$flux['data'] = substr((string) $f, 0, -strlen(".$ext"));
211
-		}
212
-	}
213
-
214
-	return $flux;
31
+    static $prefix_path = null;
32
+    static $prefix_length;
33
+    static $z_blocs;
34
+    static $apl_constant;
35
+    static $page;
36
+    static $disponible = [];
37
+    static $echafauder;
38
+    static $prepend = '';
39
+
40
+    if (!isset($prefix_path)) {
41
+        $z_blocs = z_blocs(test_espace_prive());
42
+        if (test_espace_prive()) {
43
+            $prefix_path = 'prive/squelettes/';
44
+            $prefix_length = strlen($prefix_path);
45
+            $apl_constant = '_ECRIRE_AJAX_PARALLEL_LOAD';
46
+            $page = 'exec';
47
+            $echafauder = charger_fonction('echafauder', 'prive', true);
48
+            define('_ZCORE_EXCLURE_PATH', '');
49
+        } else {
50
+            $prefix_path = '';
51
+            $prefix_length = 0;
52
+            $apl_constant = '_Z_AJAX_PARALLEL_LOAD';
53
+            $page = _SPIP_PAGE;
54
+            $echafauder = charger_fonction('echafauder', 'public', true);
55
+            define('_ZCORE_EXCLURE_PATH', '\bprive|\bsquelettes-dist' . (defined('_DIR_PLUGIN_DIST') ? '|\b' . rtrim(
56
+                (string) _DIR_PLUGIN_DIST,
57
+                '/'
58
+            ) : ''));
59
+        }
60
+        $prepend = (defined('_Z_PREPEND_PATH') ? _Z_PREPEND_PATH : '');
61
+    }
62
+    $z_contenu = reset($z_blocs); // contenu par defaut
63
+
64
+    $fond = $flux['args']['fond'];
65
+
66
+    if ($prepend || strncmp((string) $fond, (string) $prefix_path, $prefix_length) == 0) {
67
+        $fond = substr((string) $fond, $prefix_length);
68
+        $squelette = $flux['data'];
69
+        $ext = $flux['args']['ext'];
70
+        // Ajax Parallel loading : ne pas calculer le bloc, mais renvoyer un js qui le loadera en ajax
71
+        if (
72
+            defined('_Z_AJAX_PARALLEL_LOAD_OK')
73
+            && ($dir = explode('/', $fond))
74
+            && count($dir) == 2 // pas un sous repertoire
75
+            && ($dir = reset($dir))
76
+            && in_array($dir, $z_blocs) // verifier deja qu'on est dans un bloc Z
77
+            && defined($apl_constant)
78
+            && in_array($dir, explode(',', (string) constant($apl_constant))) // et dans un demande en APL
79
+            && ($pipe = z_trouver_bloc($prefix_path . $prepend, $dir, 'z_apl', $ext)) // et qui contient le squelette APL
80
+        ) {
81
+            $flux['data'] = $pipe;
82
+
83
+            return $flux;
84
+        }
85
+
86
+        // surcharger aussi les squelettes venant de squelettes-dist/
87
+        if ($squelette && !z_fond_valide($squelette)) {
88
+            $squelette = '';
89
+            $echafauder = '';
90
+        }
91
+        if ($prepend) {
92
+            $squelette = substr((string) find_in_path($prefix_path . $prepend . "$fond.$ext"), 0, -strlen(".$ext"));
93
+            if ($squelette) {
94
+                $flux['data'] = $squelette;
95
+            }
96
+        }
97
+
98
+        // gerer les squelettes non trouves
99
+        // -> router vers les /dist.html
100
+        // ou scaffolding ou page automatique les contenus
101
+        if (!$squelette) {
102
+            // si on est sur un ?page=XX non trouve
103
+            if (
104
+                isset($flux['args']['contexte'][$page]) && $flux['args']['contexte'][$page] == $fond
105
+                || isset($flux['args']['contexte']['type-page']) && $flux['args']['contexte']['type-page'] == $fond
106
+                || $fond == 'sommaire' && (!isset($flux['args']['contexte'][$page]) || !$flux['args']['contexte'][$page])
107
+            ) {
108
+                // si on est sur un ?page=XX non trouve
109
+                // se brancher sur contenu/xx si il existe
110
+                // ou si c'est un objet spip, associe a une table, utiliser le fond homonyme
111
+                if (!isset($disponible[$fond])) {
112
+                    $disponible[$fond] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $fond, $ext, (bool) $echafauder);
113
+                }
114
+
115
+                if ($disponible[$fond]) {
116
+                    $flux['data'] = substr((string) find_in_path($prefix_path . "page.$ext"), 0, -strlen(".$ext"));
117
+                }
118
+            }
119
+
120
+            // echafaudage :
121
+            // si c'est un fond de contenu d'un objet en base
122
+            // generer un fond automatique a la volee pour les webmestres
123
+            elseif (strncmp($fond, "$z_contenu/", strlen((string) $z_contenu) + 1) == 0) {
124
+                $type = substr($fond, strlen((string) $z_contenu) + 1);
125
+                if ($type == 'page' && isset($flux['args']['contexte'][$page])) {
126
+                    $type = $flux['args']['contexte'][$page];
127
+                }
128
+                if (!isset($disponible[$type])) {
129
+                    $disponible[$type] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $type, $ext, (bool) $echafauder);
130
+                }
131
+                if (is_string($disponible[$type])) {
132
+                    $flux['data'] = $disponible[$type];
133
+                } elseif (
134
+                    $echafauder
135
+                    && include_spip('inc/autoriser')
136
+                    && isset($GLOBALS['visiteur_session']['statut'])
137
+                    && autoriser('echafauder', $type)
138
+                    && ($is = $disponible[$type])
139
+                    && is_array($is)
140
+                ) {
141
+                    $flux['data'] = $echafauder($type, $is[0], $is[1], $is[2], $ext);
142
+                } else {
143
+                    $flux['data'] = ($disponible['404'] = z_contenu_disponible(
144
+                        $prefix_path . $prepend,
145
+                        $z_contenu,
146
+                        '404',
147
+                        $ext,
148
+                        (bool) $echafauder
149
+                    ));
150
+                }
151
+            }
152
+
153
+            // sinon, si on demande un fond non trouve dans un des autres blocs
154
+            // et si il y a bien un contenu correspondant ou echafaudable
155
+            // se rabbatre sur le dist.html du bloc concerne
156
+            else {
157
+                if (
158
+                    ($dir = explode('/', $fond))
159
+                    && ($dir = reset($dir))
160
+                    && $dir !== $z_contenu
161
+                    && in_array($dir, $z_blocs)
162
+                ) {
163
+                    $type = substr($fond, strlen("$dir/"));
164
+                    if ($type == 'page' && isset($flux['args']['contexte'][$page])) {
165
+                        $type = $flux['args']['contexte'][$page];
166
+                    }
167
+                    if ($type !== 'page' && !isset($disponible[$type])) {
168
+                        $disponible[$type] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $type, $ext, (bool) $echafauder);
169
+                    }
170
+                    if ($type == 'page' || $disponible[$type]) {
171
+                        $flux['data'] = z_trouver_bloc($prefix_path . $prepend, $dir, 'dist', $ext);
172
+                    }
173
+                }
174
+            }
175
+            $squelette = $flux['data'];
176
+        }
177
+
178
+        // layout specifiques par type et compositions :
179
+        // body-article.html
180
+        // body-sommaire.html
181
+        // pour des raisons de perfo, les declinaisons doivent etre dans le
182
+        // meme dossier que body.html
183
+        $f = null;
184
+        if ($fond == 'body' && str_ends_with((string) $squelette, $fond)) {
185
+            if (
186
+                isset($flux['args']['contexte']['type-page'])
187
+                && (
188
+                    isset($flux['args']['contexte']['composition']) && file_exists(($f = $squelette . '-' . $flux['args']['contexte']['type-page'] . '-' . $flux['args']['contexte']['composition']) . ".$ext")
189
+                    || file_exists(($f = $squelette . '-' . $flux['args']['contexte']['type-page']) . ".$ext")
190
+                )
191
+            ) {
192
+                $flux['data'] = $f;
193
+            }
194
+        } elseif (
195
+            $fond == 'structure'
196
+            && z_sanitize_var_zajax()
197
+            && ($f = find_in_path($prefix_path . $prepend . 'ajax' . ".$ext"))
198
+        ) {
199
+            $flux['data'] = substr((string) $f, 0, -strlen(".$ext"));
200
+        } elseif (
201
+            // chercher le fond correspondant a la composition
202
+            isset($flux['args']['contexte']['composition'])
203
+            && (basename($fond) == 'page' || $squelette && str_ends_with((string) $squelette, $fond))
204
+            && ($dir = substr($fond, $prefix_length))
205
+            && ($dir = explode('/', $dir))
206
+            && ($dir = reset($dir))
207
+            && in_array($dir, $z_blocs)
208
+            && ($f = find_in_path($prefix_path . $prepend . $fond . '-' . $flux['args']['contexte']['composition'] . ".$ext"))
209
+        ) {
210
+            $flux['data'] = substr((string) $f, 0, -strlen(".$ext"));
211
+        }
212
+    }
213
+
214
+    return $flux;
215 215
 }
216 216
 
217 217
 /**
@@ -221,18 +221,18 @@  discard block
 block discarded – undo
221 221
  * @return array
222 222
  */
223 223
 function z_blocs($espace_prive = false) {
224
-	if ($espace_prive) {
225
-		return ($GLOBALS['z_blocs_ecrire'] ?? [
226
-			'contenu',
227
-			'navigation',
228
-			'extra',
229
-			'head',
230
-			'hierarchie',
231
-			'top'
232
-		]);
233
-	}
234
-
235
-	return ($GLOBALS['z_blocs'] ?? ['contenu']);
224
+    if ($espace_prive) {
225
+        return ($GLOBALS['z_blocs_ecrire'] ?? [
226
+            'contenu',
227
+            'navigation',
228
+            'extra',
229
+            'head',
230
+            'hierarchie',
231
+            'top'
232
+        ]);
233
+    }
234
+
235
+    return ($GLOBALS['z_blocs'] ?? ['contenu']);
236 236
 }
237 237
 
238 238
 /**
@@ -247,11 +247,11 @@  discard block
 block discarded – undo
247 247
  * @return mixed
248 248
  */
249 249
 function z_contenu_disponible($prefix_path, $z_contenu, $type, $ext, $echafauder = true) {
250
-	if ($d = z_trouver_bloc($prefix_path, $z_contenu, $type, $ext)) {
251
-		return $d;
252
-	}
250
+    if ($d = z_trouver_bloc($prefix_path, $z_contenu, $type, $ext)) {
251
+        return $d;
252
+    }
253 253
 
254
-	return $echafauder ? z_echafaudable($type) : false;
254
+    return $echafauder ? z_echafaudable($type) : false;
255 255
 }
256 256
 
257 257
 /**
@@ -265,7 +265,7 @@  discard block
 block discarded – undo
265 265
  *   `true` si on peut l'utiliser, `false` sinon.
266 266
  **/
267 267
 function z_fond_valide($squelette) {
268
-	return !_ZCORE_EXCLURE_PATH || !preg_match(',(' . _ZCORE_EXCLURE_PATH . ')/,', $squelette);
268
+    return !_ZCORE_EXCLURE_PATH || !preg_match(',(' . _ZCORE_EXCLURE_PATH . ')/,', $squelette);
269 269
 }
270 270
 
271 271
 /**
@@ -283,14 +283,14 @@  discard block
 block discarded – undo
283 283
  * @return string
284 284
  */
285 285
 function z_trouver_bloc($prefix_path, $bloc, $fond, $ext) {
286
-	if (
287
-		defined('_ZCORE_BLOC_PREFIX_SKEL') && ($f = find_in_path("$prefix_path$bloc/$bloc.$fond.$ext")) && z_fond_valide($f)
288
-		|| ($f = find_in_path("$prefix_path$bloc/$fond.$ext")) && z_fond_valide($f)
289
-	) {
290
-		return substr((string) $f, 0, -strlen(".$ext"));
291
-	}
292
-
293
-	return '';
286
+    if (
287
+        defined('_ZCORE_BLOC_PREFIX_SKEL') && ($f = find_in_path("$prefix_path$bloc/$bloc.$fond.$ext")) && z_fond_valide($f)
288
+        || ($f = find_in_path("$prefix_path$bloc/$fond.$ext")) && z_fond_valide($f)
289
+    ) {
290
+        return substr((string) $f, 0, -strlen(".$ext"));
291
+    }
292
+
293
+    return '';
294 294
 }
295 295
 
296 296
 /**
@@ -302,52 +302,52 @@  discard block
 block discarded – undo
302 302
  * @return bool
303 303
  */
304 304
 function z_echafaudable($type) {
305
-	static $pages = null;
306
-	static $echafaudable = [];
307
-	if (isset($echafaudable[$type])) {
308
-		return $echafaudable[$type];
309
-	}
310
-	if (preg_match(',[^\w],', $type)) {
311
-		return $echafaudable[$type] = false;
312
-	}
313
-
314
-	if (test_espace_prive()) {
315
-		if (!function_exists('trouver_objet_exec')) {
316
-			include_spip('inc/pipelines_ecrire');
317
-		}
318
-		if ($e = trouver_objet_exec($type)) {
319
-			return $echafaudable[$type] = [$e['table'], $e['table_objet_sql'], $e];
320
-		} else {
321
-			// peut etre c'est un exec=types qui liste tous les objets "type"
322
-			if (
323
-				($t = objet_type($type, false)) !== $type
324
-				&& ($e = trouver_objet_exec($t))
325
-			) {
326
-				return $echafaudable[$type] = [$e['table'], $e['table_objet_sql'], $t];
327
-			}
328
-		}
329
-	} else {
330
-		if (is_null($pages)) {
331
-			$pages = [];
332
-			$liste = lister_tables_objets_sql();
333
-			foreach ($liste as $t => $d) {
334
-				if ($d['page']) {
335
-					$pages[$d['page']] = [$d['table_objet'], $t];
336
-				}
337
-			}
338
-		}
339
-		if (!isset($pages[$type])) {
340
-			return $echafaudable[$type] = false;
341
-		}
342
-		if ((is_countable($pages[$type]) ? count($pages[$type]) : 0) == 2) {
343
-			$trouver_table = charger_fonction('trouver_table', 'base');
344
-			$pages[$type][] = $trouver_table(reset($pages[$type]));
345
-		}
346
-
347
-		return $echafaudable[$type] = $pages[$type];
348
-	}
349
-
350
-	return $echafaudable[$type] = false;
305
+    static $pages = null;
306
+    static $echafaudable = [];
307
+    if (isset($echafaudable[$type])) {
308
+        return $echafaudable[$type];
309
+    }
310
+    if (preg_match(',[^\w],', $type)) {
311
+        return $echafaudable[$type] = false;
312
+    }
313
+
314
+    if (test_espace_prive()) {
315
+        if (!function_exists('trouver_objet_exec')) {
316
+            include_spip('inc/pipelines_ecrire');
317
+        }
318
+        if ($e = trouver_objet_exec($type)) {
319
+            return $echafaudable[$type] = [$e['table'], $e['table_objet_sql'], $e];
320
+        } else {
321
+            // peut etre c'est un exec=types qui liste tous les objets "type"
322
+            if (
323
+                ($t = objet_type($type, false)) !== $type
324
+                && ($e = trouver_objet_exec($t))
325
+            ) {
326
+                return $echafaudable[$type] = [$e['table'], $e['table_objet_sql'], $t];
327
+            }
328
+        }
329
+    } else {
330
+        if (is_null($pages)) {
331
+            $pages = [];
332
+            $liste = lister_tables_objets_sql();
333
+            foreach ($liste as $t => $d) {
334
+                if ($d['page']) {
335
+                    $pages[$d['page']] = [$d['table_objet'], $t];
336
+                }
337
+            }
338
+        }
339
+        if (!isset($pages[$type])) {
340
+            return $echafaudable[$type] = false;
341
+        }
342
+        if ((is_countable($pages[$type]) ? count($pages[$type]) : 0) == 2) {
343
+            $trouver_table = charger_fonction('trouver_table', 'base');
344
+            $pages[$type][] = $trouver_table(reset($pages[$type]));
345
+        }
346
+
347
+        return $echafaudable[$type] = $pages[$type];
348
+    }
349
+
350
+    return $echafaudable[$type] = false;
351 351
 }
352 352
 
353 353
 
@@ -364,42 +364,42 @@  discard block
 block discarded – undo
364 364
  * @return string
365 365
  */
366 366
 function prive_echafauder_dist($exec, $table, $table_sql, $desc_exec, $ext) {
367
-	$scaffold = '';
368
-
369
-	// page objet ou objet_edit
370
-	if (is_array($desc_exec)) {
371
-		$type = $desc_exec['type'];
372
-		$primary = $desc_exec['id_table_objet'];
373
-
374
-		if ($desc_exec['edition'] === false) {
375
-			$fond = 'objet';
376
-		} else {
377
-			$trouver_table = charger_fonction('trouver_table', 'base');
378
-			$desc = $trouver_table($table_sql);
379
-			$fond = isset($desc['field']['id_rubrique']) ? 'objet_edit' : 'objet_edit.sans_rubrique';
380
-		}
381
-		$dir = z_blocs(test_espace_prive());
382
-		$dir = reset($dir);
383
-		$scaffold = "<INCLURE{fond=prive/echafaudage/$dir/" . $fond . ',objet=' . $type . ',id_objet=#' . strtoupper((string) $primary) . ',env}>';
384
-	} // page objets
385
-	elseif (($type = $desc_exec) && !str_contains($type, '/')) {
386
-		$dir = z_blocs(test_espace_prive());
387
-		$dir = reset($dir);
388
-		$scaffold = "<INCLURE{fond=prive/echafaudage/$dir/objets,objet=" . $type . ',env} />';
389
-	}
390
-	// morceau d'objet : on fournit le fond de sibstitution dans $desc_exec
391
-	// et objet et tire de $table
392
-	elseif ($fond = $desc_exec) {
393
-		$dir = md5(dirname($fond));
394
-		$scaffold = "<INCLURE{fond=$fond,objet=" . objet_type($table) . ',env} />';
395
-	}
396
-
397
-	$base_dir = sous_repertoire(_DIR_CACHE, 'scaffold', false);
398
-	$base_dir = sous_repertoire($base_dir, $dir, false);
399
-	$f = $base_dir . "$exec";
400
-	ecrire_fichier("$f.$ext", $scaffold);
401
-
402
-	return $f;
367
+    $scaffold = '';
368
+
369
+    // page objet ou objet_edit
370
+    if (is_array($desc_exec)) {
371
+        $type = $desc_exec['type'];
372
+        $primary = $desc_exec['id_table_objet'];
373
+
374
+        if ($desc_exec['edition'] === false) {
375
+            $fond = 'objet';
376
+        } else {
377
+            $trouver_table = charger_fonction('trouver_table', 'base');
378
+            $desc = $trouver_table($table_sql);
379
+            $fond = isset($desc['field']['id_rubrique']) ? 'objet_edit' : 'objet_edit.sans_rubrique';
380
+        }
381
+        $dir = z_blocs(test_espace_prive());
382
+        $dir = reset($dir);
383
+        $scaffold = "<INCLURE{fond=prive/echafaudage/$dir/" . $fond . ',objet=' . $type . ',id_objet=#' . strtoupper((string) $primary) . ',env}>';
384
+    } // page objets
385
+    elseif (($type = $desc_exec) && !str_contains($type, '/')) {
386
+        $dir = z_blocs(test_espace_prive());
387
+        $dir = reset($dir);
388
+        $scaffold = "<INCLURE{fond=prive/echafaudage/$dir/objets,objet=" . $type . ',env} />';
389
+    }
390
+    // morceau d'objet : on fournit le fond de sibstitution dans $desc_exec
391
+    // et objet et tire de $table
392
+    elseif ($fond = $desc_exec) {
393
+        $dir = md5(dirname($fond));
394
+        $scaffold = "<INCLURE{fond=$fond,objet=" . objet_type($table) . ',env} />';
395
+    }
396
+
397
+    $base_dir = sous_repertoire(_DIR_CACHE, 'scaffold', false);
398
+    $base_dir = sous_repertoire($base_dir, $dir, false);
399
+    $f = $base_dir . "$exec";
400
+    ecrire_fichier("$f.$ext", $scaffold);
401
+
402
+    return $f;
403 403
 }
404 404
 
405 405
 /**
@@ -408,17 +408,17 @@  discard block
 block discarded – undo
408 408
  * @return bool|string
409 409
  */
410 410
 function z_sanitize_var_zajax() {
411
-	$z_ajax = _request('var_zajax');
412
-	if (!$z_ajax) {
413
-		return false;
414
-	}
415
-	if (
416
-		!($z_blocs = z_blocs(test_espace_prive()))
417
-		|| !in_array($z_ajax, $z_blocs)
418
-	) {
419
-		set_request('var_zajax'); // enlever cette demande incongrue
420
-		$z_ajax = false;
421
-	}
422
-
423
-	return $z_ajax;
411
+    $z_ajax = _request('var_zajax');
412
+    if (!$z_ajax) {
413
+        return false;
414
+    }
415
+    if (
416
+        !($z_blocs = z_blocs(test_espace_prive()))
417
+        || !in_array($z_ajax, $z_blocs)
418
+    ) {
419
+        set_request('var_zajax'); // enlever cette demande incongrue
420
+        $z_ajax = false;
421
+    }
422
+
423
+    return $z_ajax;
424 424
 }
Please login to merge, or discard this patch.
ecrire/public/criteres.php 1 patch
Indentation   +1711 added lines, -1711 removed lines patch added patch discarded remove patch
@@ -20,7 +20,7 @@  discard block
 block discarded – undo
20 20
  **/
21 21
 
22 22
 if (!defined('_ECRIRE_INC_VERSION')) {
23
-	return;
23
+    return;
24 24
 }
25 25
 
26 26
 /**
@@ -46,12 +46,12 @@  discard block
 block discarded – undo
46 46
  **/
47 47
 function critere_racine_dist($idb, &$boucles, $crit) {
48 48
 
49
-	$not = $crit->not;
50
-	$boucle = &$boucles[$idb];
51
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
49
+    $not = $crit->not;
50
+    $boucle = &$boucles[$idb];
51
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
52 52
 
53
-	$c = ["'='", "'$boucle->id_table." . "$id_parent'", 0];
54
-	$boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
53
+    $c = ["'='", "'$boucle->id_table." . "$id_parent'", 0];
54
+    $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
55 55
 }
56 56
 
57 57
 
@@ -68,15 +68,15 @@  discard block
 block discarded – undo
68 68
  * @return void|array
69 69
  **/
70 70
 function critere_exclus_dist($idb, &$boucles, $crit) {
71
-	$not = $crit->not;
72
-	$boucle = &$boucles[$idb];
73
-	$id = $boucle->primary;
74
-
75
-	if ($not || !$id) {
76
-		return ['zbug_critere_inconnu', ['critere' => $not . $crit->op]];
77
-	}
78
-	$arg = kwote(calculer_argument_precedent($idb, $id, $boucles));
79
-	$boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg];
71
+    $not = $crit->not;
72
+    $boucle = &$boucles[$idb];
73
+    $id = $boucle->primary;
74
+
75
+    if ($not || !$id) {
76
+        return ['zbug_critere_inconnu', ['critere' => $not . $crit->op]];
77
+    }
78
+    $arg = kwote(calculer_argument_precedent($idb, $id, $boucles));
79
+    $boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg];
80 80
 }
81 81
 
82 82
 
@@ -96,73 +96,73 @@  discard block
 block discarded – undo
96 96
  * @return void|array
97 97
  **/
98 98
 function critere_doublons_dist($idb, &$boucles, $crit) {
99
-	$boucle = &$boucles[$idb];
100
-	$primary = $boucle->primary;
101
-
102
-	// la table nécessite une clé primaire, non composée
103
-	if (!$primary || strpos((string) $primary, ',')) {
104
-		return ['zbug_doublon_sur_table_sans_cle_primaire'];
105
-	}
106
-
107
-	$not = ($crit->not ? '' : 'NOT');
108
-
109
-	// le doublon s'applique sur un type de boucle (article)
110
-	$nom = "'" . $boucle->type_requete . "'";
111
-
112
-	// compléter le nom avec un nom précisé {doublons nom}
113
-	// on obtient $nom = "'article' . 'nom'"
114
-	if (isset($crit->param[0])) {
115
-		$nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
116
-	}
117
-
118
-	// code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP)
119
-	$init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n";
120
-	$init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n";
121
-
122
-	// on crée un sql_in avec la clé primaire de la table
123
-	// et la collection des doublons déjà emmagasinés dans le tableau
124
-	// $doublons et son index, ici $nom
125
-
126
-	// debut du code "sql_in('articles.id_article', "
127
-	$debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', ";
128
-	// lecture des données du doublon "$doublons[$doublon_index[] = "
129
-	// Attention : boucle->doublons désigne une variable qu'on affecte
130
-	$debut_doub = '$doublons[' . ($not ? $boucle->doublons . '[]= ' : (''));
131
-
132
-	// le debut complet du code des doublons
133
-	$debut_doub = $debut_in . $debut_doub;
134
-
135
-	// nom du doublon "('article' . 'nom')]"
136
-	$fin_doub = "($nom)]";
137
-
138
-	// si on trouve un autre critère doublon,
139
-	// on fusionne pour avoir un seul IN, et on s'en va !
140
-	foreach ($boucle->where as $k => $w) {
141
-		if (str_starts_with((string) $w[0], $debut_doub)) {
142
-			// fusionner le sql_in (du where)
143
-			$boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr((string) $w[0], strlen($debut_in));
144
-			// fusionner l'initialisation (du hash) pour faire plus joli
145
-			$x = strpos((string) $boucle->hash, $init_comment);
146
-			$len = strlen($init_comment);
147
-			$boucle->hash =
148
-				substr((string) $boucle->hash, 0, $x + $len) . $init_code . substr((string) $boucle->hash, $x + $len);
149
-
150
-			return;
151
-		}
152
-	}
153
-
154
-	// mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante
155
-	$boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"];
156
-
157
-	// déclarer le doublon s'il n'existe pas encore
158
-	$boucle->hash .= $init_comment . $init_code;
159
-
160
-
161
-	# la ligne suivante avait l'intention d'eviter une collecte deja faite
162
-	# mais elle fait planter une boucle a 2 critere doublons:
163
-	# {!doublons A}{doublons B}
164
-	# (de http://article.gmane.org/gmane.comp.web.spip.devel/31034)
165
-	#	if ($crit->not) $boucle->doublons = "";
99
+    $boucle = &$boucles[$idb];
100
+    $primary = $boucle->primary;
101
+
102
+    // la table nécessite une clé primaire, non composée
103
+    if (!$primary || strpos((string) $primary, ',')) {
104
+        return ['zbug_doublon_sur_table_sans_cle_primaire'];
105
+    }
106
+
107
+    $not = ($crit->not ? '' : 'NOT');
108
+
109
+    // le doublon s'applique sur un type de boucle (article)
110
+    $nom = "'" . $boucle->type_requete . "'";
111
+
112
+    // compléter le nom avec un nom précisé {doublons nom}
113
+    // on obtient $nom = "'article' . 'nom'"
114
+    if (isset($crit->param[0])) {
115
+        $nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
116
+    }
117
+
118
+    // code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP)
119
+    $init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n";
120
+    $init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n";
121
+
122
+    // on crée un sql_in avec la clé primaire de la table
123
+    // et la collection des doublons déjà emmagasinés dans le tableau
124
+    // $doublons et son index, ici $nom
125
+
126
+    // debut du code "sql_in('articles.id_article', "
127
+    $debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', ";
128
+    // lecture des données du doublon "$doublons[$doublon_index[] = "
129
+    // Attention : boucle->doublons désigne une variable qu'on affecte
130
+    $debut_doub = '$doublons[' . ($not ? $boucle->doublons . '[]= ' : (''));
131
+
132
+    // le debut complet du code des doublons
133
+    $debut_doub = $debut_in . $debut_doub;
134
+
135
+    // nom du doublon "('article' . 'nom')]"
136
+    $fin_doub = "($nom)]";
137
+
138
+    // si on trouve un autre critère doublon,
139
+    // on fusionne pour avoir un seul IN, et on s'en va !
140
+    foreach ($boucle->where as $k => $w) {
141
+        if (str_starts_with((string) $w[0], $debut_doub)) {
142
+            // fusionner le sql_in (du where)
143
+            $boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr((string) $w[0], strlen($debut_in));
144
+            // fusionner l'initialisation (du hash) pour faire plus joli
145
+            $x = strpos((string) $boucle->hash, $init_comment);
146
+            $len = strlen($init_comment);
147
+            $boucle->hash =
148
+                substr((string) $boucle->hash, 0, $x + $len) . $init_code . substr((string) $boucle->hash, $x + $len);
149
+
150
+            return;
151
+        }
152
+    }
153
+
154
+    // mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante
155
+    $boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"];
156
+
157
+    // déclarer le doublon s'il n'existe pas encore
158
+    $boucle->hash .= $init_comment . $init_code;
159
+
160
+
161
+    # la ligne suivante avait l'intention d'eviter une collecte deja faite
162
+    # mais elle fait planter une boucle a 2 critere doublons:
163
+    # {!doublons A}{doublons B}
164
+    # (de http://article.gmane.org/gmane.comp.web.spip.devel/31034)
165
+    #	if ($crit->not) $boucle->doublons = "";
166 166
 }
167 167
 
168 168
 
@@ -183,14 +183,14 @@  discard block
 block discarded – undo
183 183
  * @return void
184 184
  **/
185 185
 function critere_lang_select_dist($idb, &$boucles, $crit) {
186
-	if (!isset($crit->param[1][0]) || !($param = $crit->param[1][0]->texte)) {
187
-		$param = 'oui';
188
-	}
189
-	if ($crit->not) {
190
-		$param = ($param == 'oui') ? 'non' : 'oui';
191
-	}
192
-	$boucle = &$boucles[$idb];
193
-	$boucle->lang_select = $param;
186
+    if (!isset($crit->param[1][0]) || !($param = $crit->param[1][0]->texte)) {
187
+        $param = 'oui';
188
+    }
189
+    if ($crit->not) {
190
+        $param = ($param == 'oui') ? 'non' : 'oui';
191
+    }
192
+    $boucle = &$boucles[$idb];
193
+    $boucle->lang_select = $param;
194 194
 }
195 195
 
196 196
 
@@ -212,15 +212,15 @@  discard block
 block discarded – undo
212 212
  * @return void
213 213
  **/
214 214
 function critere_debut_dist($idb, &$boucles, $crit) {
215
-	[$un, $deux] = $crit->param;
216
-	$un = $un[0]->texte;
217
-	$deux = $deux[0]->texte;
218
-	if ($deux) {
219
-		$boucles[$idb]->limit =
220
-			'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"';
221
-	} else {
222
-		calculer_critere_DEFAUT_dist($idb, $boucles, $crit);
223
-	}
215
+    [$un, $deux] = $crit->param;
216
+    $un = $un[0]->texte;
217
+    $deux = $deux[0]->texte;
218
+    if ($deux) {
219
+        $boucles[$idb]->limit =
220
+            'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"';
221
+    } else {
222
+        calculer_critere_DEFAUT_dist($idb, $boucles, $crit);
223
+    }
224 224
 }
225 225
 
226 226
 
@@ -254,59 +254,59 @@  discard block
 block discarded – undo
254 254
  **/
255 255
 function critere_pagination_dist($idb, &$boucles, $crit) {
256 256
 
257
-	$boucle = &$boucles[$idb];
258
-	// definition de la taille de la page
259
-	$pas = isset($crit->param[0][0])
260
-		? calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent)
261
-		: "''";
262
-
263
-	if (!preg_match(_CODE_QUOTE, (string) $pas, $r)) {
264
-		$pas = "((\$a = intval($pas)) ? \$a : 10)";
265
-	} else {
266
-		$r = (int) $r[2];
267
-		$pas = (string) ($r ?: 10);
268
-	}
269
-
270
-	// Calcul du nommage de la pagination si il existe.
271
-	// La nouvelle syntaxe {pagination 20, nom} est prise en compte et privilégiée mais on reste
272
-	// compatible avec l'ancienne car certains cas fonctionnent correctement
273
-	$type = "'$idb'";
274
-	// Calcul d'un nommage spécifique de la pagination si précisé.
275
-	// Syntaxe {pagination 20, nom}
276
-	if (isset($crit->param[0][1])) {
277
-		$type = calculer_liste([$crit->param[0][1]], $idb, $boucles, $boucle->id_parent);
278
-	} // Ancienne syntaxe {pagination 20 nom} pour compatibilité
279
-	elseif (isset($crit->param[1][0])) {
280
-		$type = calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
281
-	}
282
-
283
-	$debut = ($type[0] !== "'") ? "'debut'.$type" : ("'debut" . substr((string) $type, 1));
284
-	$boucle->modificateur['debut_nom'] = $type;
285
-	$partie =
286
-		// tester si le numero de page demande est de la forme '@yyy'
287
-		'isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : _request(' . $debut . ");\n"
288
-		. "\tif (\$debut_boucle && \$debut_boucle[0] === '@') {\n"
289
-		. "\t\t" . '$debut_boucle = $Pile[0][' . $debut . '] = quete_debut_pagination(\'' . $boucle->primary . '\',$Pile[0][\'@' . $boucle->primary . '\'] = substr($debut_boucle,1),' . $pas . ',$iter);' . "\n"
290
-		. "\t\t" . '$iter->seek(0);' . "\n"
291
-		. "\t}\n"
292
-		. "\t" . '$debut_boucle = intval($debut_boucle)';
293
-
294
-	$boucle->hash .= '
257
+    $boucle = &$boucles[$idb];
258
+    // definition de la taille de la page
259
+    $pas = isset($crit->param[0][0])
260
+        ? calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent)
261
+        : "''";
262
+
263
+    if (!preg_match(_CODE_QUOTE, (string) $pas, $r)) {
264
+        $pas = "((\$a = intval($pas)) ? \$a : 10)";
265
+    } else {
266
+        $r = (int) $r[2];
267
+        $pas = (string) ($r ?: 10);
268
+    }
269
+
270
+    // Calcul du nommage de la pagination si il existe.
271
+    // La nouvelle syntaxe {pagination 20, nom} est prise en compte et privilégiée mais on reste
272
+    // compatible avec l'ancienne car certains cas fonctionnent correctement
273
+    $type = "'$idb'";
274
+    // Calcul d'un nommage spécifique de la pagination si précisé.
275
+    // Syntaxe {pagination 20, nom}
276
+    if (isset($crit->param[0][1])) {
277
+        $type = calculer_liste([$crit->param[0][1]], $idb, $boucles, $boucle->id_parent);
278
+    } // Ancienne syntaxe {pagination 20 nom} pour compatibilité
279
+    elseif (isset($crit->param[1][0])) {
280
+        $type = calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
281
+    }
282
+
283
+    $debut = ($type[0] !== "'") ? "'debut'.$type" : ("'debut" . substr((string) $type, 1));
284
+    $boucle->modificateur['debut_nom'] = $type;
285
+    $partie =
286
+        // tester si le numero de page demande est de la forme '@yyy'
287
+        'isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : _request(' . $debut . ");\n"
288
+        . "\tif (\$debut_boucle && \$debut_boucle[0] === '@') {\n"
289
+        . "\t\t" . '$debut_boucle = $Pile[0][' . $debut . '] = quete_debut_pagination(\'' . $boucle->primary . '\',$Pile[0][\'@' . $boucle->primary . '\'] = substr($debut_boucle,1),' . $pas . ',$iter);' . "\n"
290
+        . "\t\t" . '$iter->seek(0);' . "\n"
291
+        . "\t}\n"
292
+        . "\t" . '$debut_boucle = intval($debut_boucle)';
293
+
294
+    $boucle->hash .= '
295 295
 	$command[\'pagination\'] = array((isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : null), ' . $pas . ');';
296 296
 
297
-	$boucle->total_parties = $pas;
298
-	calculer_parties($boucles, $idb, $partie, 'p+');
299
-	// ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id
300
-	// sauf si pas de primaire, ou si primaire composee
301
-	// dans ce cas, on ne sait pas gerer une pagination indirecte
302
-	$t = $boucle->id_table . '.' . $boucle->primary;
303
-	if (
304
-		$boucle->primary
305
-		&& !preg_match('/[,\s]/', (string) $boucle->primary)
306
-		&& !in_array($t, $boucle->select)
307
-	) {
308
-		$boucle->select[] = $t;
309
-	}
297
+    $boucle->total_parties = $pas;
298
+    calculer_parties($boucles, $idb, $partie, 'p+');
299
+    // ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id
300
+    // sauf si pas de primaire, ou si primaire composee
301
+    // dans ce cas, on ne sait pas gerer une pagination indirecte
302
+    $t = $boucle->id_table . '.' . $boucle->primary;
303
+    if (
304
+        $boucle->primary
305
+        && !preg_match('/[,\s]/', (string) $boucle->primary)
306
+        && !in_array($t, $boucle->select)
307
+    ) {
308
+        $boucle->select[] = $t;
309
+    }
310 310
 }
311 311
 
312 312
 
@@ -328,24 +328,24 @@  discard block
 block discarded – undo
328 328
  **/
329 329
 function critere_recherche_dist($idb, &$boucles, $crit) {
330 330
 
331
-	$boucle = &$boucles[$idb];
331
+    $boucle = &$boucles[$idb];
332 332
 
333
-	if (!$boucle->primary || strpos((string) $boucle->primary, ',')) {
334
-		erreur_squelette(_T('zbug_critere_sur_table_sans_cle_primaire', ['critere' => 'recherche']), $boucle);
333
+    if (!$boucle->primary || strpos((string) $boucle->primary, ',')) {
334
+        erreur_squelette(_T('zbug_critere_sur_table_sans_cle_primaire', ['critere' => 'recherche']), $boucle);
335 335
 
336
-		return;
337
-	}
336
+        return;
337
+    }
338 338
 
339
-	if (isset($crit->param[0])) {
340
-		$quoi = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
341
-	} else {
342
-		$quoi = '(isset($Pile[0]["recherche"])?$Pile[0]["recherche"]:(isset($GLOBALS["recherche"])?$GLOBALS["recherche"]:""))';
343
-	}
339
+    if (isset($crit->param[0])) {
340
+        $quoi = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
341
+    } else {
342
+        $quoi = '(isset($Pile[0]["recherche"])?$Pile[0]["recherche"]:(isset($GLOBALS["recherche"])?$GLOBALS["recherche"]:""))';
343
+    }
344 344
 
345
-	$_modificateur = var_export($boucle->modificateur, true);
346
-	$boucle->hash .= '
345
+    $_modificateur = var_export($boucle->modificateur, true);
346
+    $boucle->hash .= '
347 347
 	// RECHERCHE'
348
-		. ($crit->cond ? '
348
+        . ($crit->cond ? '
349 349
 	if (!strlen(' . $quoi . ')){
350 350
 		list($rech_select, $rech_where) = array("0 as points","");
351 351
 	} else' : '') . '
@@ -356,21 +356,21 @@  discard block
 block discarded – undo
356 356
 	';
357 357
 
358 358
 
359
-	$t = $boucle->id_table . '.' . $boucle->primary;
360
-	if (!in_array($t, $boucles[$idb]->select)) {
361
-		$boucle->select[] = $t;
362
-	} # pour postgres, neuneu ici
363
-	// jointure uniquement sur le serveur principal
364
-	// (on ne peut joindre une table d'un serveur distant avec la table des resultats du serveur principal)
365
-	if (!$boucle->sql_serveur) {
366
-		$boucle->join['resultats'] = ["'" . $boucle->id_table . "'", "'id'", "'" . $boucle->primary . "'"];
367
-		$boucle->from['resultats'] = 'spip_resultats';
368
-	}
369
-	$boucle->select[] = '$rech_select';
370
-	//$boucle->where[]= "\$rech_where?'resultats.id=".$boucle->id_table.".".$boucle->primary."':''";
371
-
372
-	// et la recherche trouve
373
-	$boucle->where[] = '$rech_where?$rech_where:\'\'';
359
+    $t = $boucle->id_table . '.' . $boucle->primary;
360
+    if (!in_array($t, $boucles[$idb]->select)) {
361
+        $boucle->select[] = $t;
362
+    } # pour postgres, neuneu ici
363
+    // jointure uniquement sur le serveur principal
364
+    // (on ne peut joindre une table d'un serveur distant avec la table des resultats du serveur principal)
365
+    if (!$boucle->sql_serveur) {
366
+        $boucle->join['resultats'] = ["'" . $boucle->id_table . "'", "'id'", "'" . $boucle->primary . "'"];
367
+        $boucle->from['resultats'] = 'spip_resultats';
368
+    }
369
+    $boucle->select[] = '$rech_select';
370
+    //$boucle->where[]= "\$rech_where?'resultats.id=".$boucle->id_table.".".$boucle->primary."':''";
371
+
372
+    // et la recherche trouve
373
+    $boucle->where[] = '$rech_where?$rech_where:\'\'';
374 374
 }
375 375
 
376 376
 /**
@@ -387,25 +387,25 @@  discard block
 block discarded – undo
387 387
  * @return void
388 388
  **/
389 389
 function critere_traduction_dist($idb, &$boucles, $crit) {
390
-	$boucle = &$boucles[$idb];
391
-	$prim = $boucle->primary;
392
-	$table = $boucle->id_table;
393
-	$arg = kwote(calculer_argument_precedent($idb, 'id_trad', $boucles));
394
-	$dprim = kwote(calculer_argument_precedent($idb, $prim, $boucles));
395
-	$boucle->where[] =
396
-		[
397
-			"'OR'",
398
-			[
399
-				"'AND'",
400
-				["'='", "'$table.id_trad'", 0],
401
-				["'='", "'$table.$prim'", $dprim]
402
-			],
403
-			[
404
-				"'AND'",
405
-				["'>'", "'$table.id_trad'", 0],
406
-				["'='", "'$table.id_trad'", $arg]
407
-			]
408
-		];
390
+    $boucle = &$boucles[$idb];
391
+    $prim = $boucle->primary;
392
+    $table = $boucle->id_table;
393
+    $arg = kwote(calculer_argument_precedent($idb, 'id_trad', $boucles));
394
+    $dprim = kwote(calculer_argument_precedent($idb, $prim, $boucles));
395
+    $boucle->where[] =
396
+        [
397
+            "'OR'",
398
+            [
399
+                "'AND'",
400
+                ["'='", "'$table.id_trad'", 0],
401
+                ["'='", "'$table.$prim'", $dprim]
402
+            ],
403
+            [
404
+                "'AND'",
405
+                ["'>'", "'$table.id_trad'", 0],
406
+                ["'='", "'$table.id_trad'", $arg]
407
+            ]
408
+        ];
409 409
 }
410 410
 
411 411
 
@@ -423,17 +423,17 @@  discard block
 block discarded – undo
423 423
  * @return void
424 424
  **/
425 425
 function critere_origine_traduction_dist($idb, &$boucles, $crit) {
426
-	$boucle = &$boucles[$idb];
427
-	$prim = $boucle->primary;
428
-	$table = $boucle->id_table;
429
-
430
-	$c =
431
-		[
432
-			"'OR'",
433
-			["'='", "'$table." . "id_trad'", "'$table.$prim'"],
434
-			["'='", "'$table.id_trad'", "'0'"]
435
-		];
436
-	$boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
426
+    $boucle = &$boucles[$idb];
427
+    $prim = $boucle->primary;
428
+    $table = $boucle->id_table;
429
+
430
+    $c =
431
+        [
432
+            "'OR'",
433
+            ["'='", "'$table." . "id_trad'", "'$table.$prim'"],
434
+            ["'='", "'$table.id_trad'", "'0'"]
435
+        ];
436
+    $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
437 437
 }
438 438
 
439 439
 
@@ -450,17 +450,17 @@  discard block
 block discarded – undo
450 450
  **/
451 451
 function critere_meme_parent_dist($idb, &$boucles, $crit) {
452 452
 
453
-	$boucle = &$boucles[$idb];
454
-	$arg = kwote(calculer_argument_precedent($idb, 'id_parent', $boucles));
455
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
456
-	$mparent = $boucle->id_table . '.' . $id_parent;
457
-
458
-	if ($boucle->type_requete == 'rubriques' || isset($GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'])) {
459
-		$boucle->where[] = ["'='", "'$mparent'", $arg];
460
-	} // le cas FORUMS est gere dans le plugin forum, dans la fonction critere_FORUMS_meme_parent_dist()
461
-	else {
462
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $boucle->type_requete]];
463
-	}
453
+    $boucle = &$boucles[$idb];
454
+    $arg = kwote(calculer_argument_precedent($idb, 'id_parent', $boucles));
455
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
456
+    $mparent = $boucle->id_table . '.' . $id_parent;
457
+
458
+    if ($boucle->type_requete == 'rubriques' || isset($GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'])) {
459
+        $boucle->where[] = ["'='", "'$mparent'", $arg];
460
+    } // le cas FORUMS est gere dans le plugin forum, dans la fonction critere_FORUMS_meme_parent_dist()
461
+    else {
462
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $boucle->type_requete]];
463
+    }
464 464
 }
465 465
 
466 466
 
@@ -491,38 +491,38 @@  discard block
 block discarded – undo
491 491
  **/
492 492
 function critere_branche_dist($idb, &$boucles, $crit) {
493 493
 
494
-	$not = $crit->not;
495
-	$boucle = &$boucles[$idb];
496
-	// prendre en priorite un identifiant en parametre {branche XX}
497
-	if (isset($crit->param[0])) {
498
-		$arg = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
499
-		// sinon on le prend chez une boucle parente
500
-	} else {
501
-		$arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles), $boucle->sql_serveur, 'int NOT NULL');
502
-	}
503
-
504
-	//Trouver une jointure
505
-	$champ = 'id_rubrique';
506
-	$desc = $boucle->show;
507
-	//Seulement si necessaire
508
-	if (!array_key_exists($champ, $desc['field'])) {
509
-		$cle = trouver_jointure_champ($champ, $boucle);
510
-		$trouver_table = charger_fonction('trouver_table', 'base');
511
-		$desc = $trouver_table($boucle->from[$cle]);
512
-		if (count(trouver_champs_decomposes($champ, $desc)) > 1) {
513
-			$decompose = decompose_champ_id_objet($champ);
514
-			$champ = array_shift($decompose);
515
-			$boucle->where[] = ["'='", _q($cle . '.' . reset($decompose)), '"' . sql_quote(end($decompose)) . '"'];
516
-		}
517
-	} else {
518
-		$cle = $boucle->id_table;
519
-	}
520
-
521
-	$c = "sql_in('$cle" . ".$champ', calcul_branche_in($arg)"
522
-		. ($not ? ", 'NOT'" : '') . ')';
523
-	$boucle->where[] = $crit->cond
524
-		? "($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')'
525
-		: $c;
494
+    $not = $crit->not;
495
+    $boucle = &$boucles[$idb];
496
+    // prendre en priorite un identifiant en parametre {branche XX}
497
+    if (isset($crit->param[0])) {
498
+        $arg = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
499
+        // sinon on le prend chez une boucle parente
500
+    } else {
501
+        $arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles), $boucle->sql_serveur, 'int NOT NULL');
502
+    }
503
+
504
+    //Trouver une jointure
505
+    $champ = 'id_rubrique';
506
+    $desc = $boucle->show;
507
+    //Seulement si necessaire
508
+    if (!array_key_exists($champ, $desc['field'])) {
509
+        $cle = trouver_jointure_champ($champ, $boucle);
510
+        $trouver_table = charger_fonction('trouver_table', 'base');
511
+        $desc = $trouver_table($boucle->from[$cle]);
512
+        if (count(trouver_champs_decomposes($champ, $desc)) > 1) {
513
+            $decompose = decompose_champ_id_objet($champ);
514
+            $champ = array_shift($decompose);
515
+            $boucle->where[] = ["'='", _q($cle . '.' . reset($decompose)), '"' . sql_quote(end($decompose)) . '"'];
516
+        }
517
+    } else {
518
+        $cle = $boucle->id_table;
519
+    }
520
+
521
+    $c = "sql_in('$cle" . ".$champ', calcul_branche_in($arg)"
522
+        . ($not ? ", 'NOT'" : '') . ')';
523
+    $boucle->where[] = $crit->cond
524
+        ? "($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')'
525
+        : $c;
526 526
 }
527 527
 
528 528
 /**
@@ -538,15 +538,15 @@  discard block
 block discarded – undo
538 538
  **/
539 539
 function critere_logo_dist($idb, &$boucles, $crit) {
540 540
 
541
-	$boucle = &$boucles[$idb];
542
-	$not = ($crit->not ? 'NOT' : '');
543
-	$serveur = $boucle->sql_serveur;
541
+    $boucle = &$boucles[$idb];
542
+    $not = ($crit->not ? 'NOT' : '');
543
+    $serveur = $boucle->sql_serveur;
544 544
 
545
-	$c = "sql_in('" .
546
-		$boucle->id_table . '.' . $boucle->primary
547
-		. "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')";
545
+    $c = "sql_in('" .
546
+        $boucle->id_table . '.' . $boucle->primary
547
+        . "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')";
548 548
 
549
-	$boucle->where[] = $c;
549
+    $boucle->where[] = $c;
550 550
 }
551 551
 
552 552
 /**
@@ -569,31 +569,31 @@  discard block
 block discarded – undo
569 569
  * @return void|array
570 570
  */
571 571
 function critere_groupby_dist($idb, &$boucles, $crit) {
572
-	if ($t = isset($crit->param[0])) {
573
-		$t = $crit->param[0];
574
-		if ($t[0]->type == 'texte') {
575
-			$t = $t[0]->texte;
576
-			if (preg_match('/^(.*)\.(.*)$/', (string) $t, $r)) {
577
-				$t = table_objet_sql($r[1]);
578
-				$t = array_search($t, $boucles[$idb]->from);
579
-				if ($t) {
580
-					$t .= '.' . $r[2];
581
-				}
582
-			}
583
-		} else {
584
-			$t = '".'
585
-				. calculer_critere_arg_dynamique($idb, $boucles, $t)
586
-				. '."';
587
-		}
588
-	}
589
-	if ($t) {
590
-		$boucles[$idb]->group[] = $t;
591
-		if (!in_array($t, $boucles[$idb]->select)) {
592
-			$boucles[$idb]->select[] = $t;
593
-		}
594
-	} else {
595
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
596
-	}
572
+    if ($t = isset($crit->param[0])) {
573
+        $t = $crit->param[0];
574
+        if ($t[0]->type == 'texte') {
575
+            $t = $t[0]->texte;
576
+            if (preg_match('/^(.*)\.(.*)$/', (string) $t, $r)) {
577
+                $t = table_objet_sql($r[1]);
578
+                $t = array_search($t, $boucles[$idb]->from);
579
+                if ($t) {
580
+                    $t .= '.' . $r[2];
581
+                }
582
+            }
583
+        } else {
584
+            $t = '".'
585
+                . calculer_critere_arg_dynamique($idb, $boucles, $t)
586
+                . '."';
587
+        }
588
+    }
589
+    if ($t) {
590
+        $boucles[$idb]->group[] = $t;
591
+        if (!in_array($t, $boucles[$idb]->select)) {
592
+            $boucles[$idb]->select[] = $t;
593
+        }
594
+    } else {
595
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
596
+    }
597 597
 }
598 598
 
599 599
 /**
@@ -616,7 +616,7 @@  discard block
 block discarded – undo
616 616
  * @return void
617 617
  */
618 618
 function critere_groupby_supprimer_dist($idb, &$boucles, $crit): void {
619
-	$boucles[$idb]->group = [];
619
+    $boucles[$idb]->group = [];
620 620
 }
621 621
 
622 622
 /**
@@ -630,8 +630,8 @@  discard block
 block discarded – undo
630 630
  * @return void|array
631 631
  */
632 632
 function critere_fusion_dist(...$args) {
633
-	trigger_deprecation('spip', '5.0', 'Using "%s" criteria is deprecated, use "%s" criteria instead', 'fusion', 'groupby');
634
-	return critere_groupby_dist(...$args);
633
+    trigger_deprecation('spip', '5.0', 'Using "%s" criteria is deprecated, use "%s" criteria instead', 'fusion', 'groupby');
634
+    return critere_groupby_dist(...$args);
635 635
 }
636 636
 
637 637
 /**
@@ -644,8 +644,8 @@  discard block
 block discarded – undo
644 644
  * @param Critere $crit Paramètres du critère dans cette boucle
645 645
  */
646 646
 function critere_fusion_supprimer_dist(...$args): void {
647
-	trigger_deprecation('spip', '5.0', 'Using "%s" criteria is deprecated, use "%s" criteria instead', 'fusion_supprimer', 'groupby_supprimer');
648
-	critere_groupby_supprimer_dist(...$args);
647
+    trigger_deprecation('spip', '5.0', 'Using "%s" criteria is deprecated, use "%s" criteria instead', 'fusion_supprimer', 'groupby_supprimer');
648
+    critere_groupby_supprimer_dist(...$args);
649 649
 }
650 650
 
651 651
 /**
@@ -683,26 +683,26 @@  discard block
 block discarded – undo
683 683
  * @return void|array
684 684
  */
685 685
 function critere_collate_dist($idb, &$boucles, $crit) {
686
-	if (isset($crit->param[0])) {
687
-		$_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
688
-		$boucle = $boucles[$idb];
689
-		$boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')";
690
-		$n = is_countable($boucle->order) ? count($boucle->order) : 0;
691
-		if ($n && (!str_contains((string) $boucle->order[$n - 1], 'COLLATE'))) {
692
-			// l'instruction COLLATE doit être placée avant ASC ou DESC
693
-			// notamment lors de l'utilisation `{!par xxx}{collate yyy}`
694
-			if (
695
-				(false !== $i = strpos((string) $boucle->order[$n - 1], 'ASC'))
696
-				|| (false !== $i = strpos((string) $boucle->order[$n - 1], 'DESC'))
697
-			) {
698
-				$boucle->order[$n - 1] = substr_replace((string) $boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0);
699
-			} else {
700
-				$boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate'];
701
-			}
702
-		}
703
-	} else {
704
-		return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]);
705
-	}
686
+    if (isset($crit->param[0])) {
687
+        $_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
688
+        $boucle = $boucles[$idb];
689
+        $boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')";
690
+        $n = is_countable($boucle->order) ? count($boucle->order) : 0;
691
+        if ($n && (!str_contains((string) $boucle->order[$n - 1], 'COLLATE'))) {
692
+            // l'instruction COLLATE doit être placée avant ASC ou DESC
693
+            // notamment lors de l'utilisation `{!par xxx}{collate yyy}`
694
+            if (
695
+                (false !== $i = strpos((string) $boucle->order[$n - 1], 'ASC'))
696
+                || (false !== $i = strpos((string) $boucle->order[$n - 1], 'DESC'))
697
+            ) {
698
+                $boucle->order[$n - 1] = substr_replace((string) $boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0);
699
+            } else {
700
+                $boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate'];
701
+            }
702
+        }
703
+    } else {
704
+        return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]);
705
+    }
706 706
 }
707 707
 
708 708
 /**
@@ -717,26 +717,26 @@  discard block
 block discarded – undo
717 717
  * @return void|array
718 718
  */
719 719
 function critere_collecte_dist(...$args) {
720
-	trigger_deprecation('spip', '5.0', 'Using "%s" criteria is deprecated, use "%s" criteria instead', 'collecte', 'collate');
721
-	return critere_collate_dist(...$args);
720
+    trigger_deprecation('spip', '5.0', 'Using "%s" criteria is deprecated, use "%s" criteria instead', 'collecte', 'collate');
721
+    return critere_collate_dist(...$args);
722 722
 }
723 723
 
724 724
 function calculer_critere_arg_dynamique($idb, &$boucles, $crit, $suffix = '') {
725
-	$boucle = $boucles[$idb];
726
-	$alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')';
727
-	$var = '$champs_' . $idb;
728
-	$desc = (str_contains((string) $boucle->in, (string) "static $var ="));
729
-	if (!$desc) {
730
-		$desc = $boucle->show['field'];
731
-		$desc = implode(',', array_map('_q', array_keys($desc)));
732
-		$boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');';
733
-	}
734
-	if ($desc) {
735
-		$alt = "(in_array(\$x, $var)  ? $alt :(\$x$suffix))";
736
-	}
737
-	$arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent);
738
-
739
-	return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')";
725
+    $boucle = $boucles[$idb];
726
+    $alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')';
727
+    $var = '$champs_' . $idb;
728
+    $desc = (str_contains((string) $boucle->in, (string) "static $var ="));
729
+    if (!$desc) {
730
+        $desc = $boucle->show['field'];
731
+        $desc = implode(',', array_map('_q', array_keys($desc)));
732
+        $boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');';
733
+    }
734
+    if ($desc) {
735
+        $alt = "(in_array(\$x, $var)  ? $alt :(\$x$suffix))";
736
+    }
737
+    $arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent);
738
+
739
+    return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')";
740 740
 }
741 741
 
742 742
 /**
@@ -775,7 +775,7 @@  discard block
 block discarded – undo
775 775
  * @param Critere $crit Paramètres du critère dans cette boucle
776 776
  */
777 777
 function critere_par_dist($idb, &$boucles, $crit) {
778
-	return critere_parinverse($idb, $boucles, $crit);
778
+    return critere_parinverse($idb, $boucles, $crit);
779 779
 }
780 780
 
781 781
 /**
@@ -797,91 +797,91 @@  discard block
 block discarded – undo
797 797
  * @param Critere $crit Paramètres du critère dans cette boucle
798 798
  */
799 799
 function critere_parinverse($idb, &$boucles, $crit) {
800
-	$boucle = &$boucles[$idb];
801
-
802
-	$sens = $collecte = '';
803
-	if ($crit->not) {
804
-		$sens = " . ' DESC'";
805
-	}
806
-	if (isset($boucle->modificateur['collate'])) {
807
-		$collecte = ' . ' . $boucle->modificateur['collate'];
808
-	}
809
-
810
-	// Pour chaque paramètre du critère
811
-	foreach ($crit->param as $tri) {
812
-		$order = $fct = '';
813
-		// tris specifiés dynamiquement {par #ENV{tri}}
814
-		if ($tri[0]->type != 'texte') {
815
-			// calculer le order dynamique qui verifie les champs
816
-			$order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens);
817
-			// ajouter 'hasard' comme possibilité de tri dynamique
818
-			calculer_critere_par_hasard($idb, $boucles, $crit);
819
-		}
820
-		// tris textuels {par titre}
821
-		else {
822
-			$par = array_shift($tri);
823
-			$par = $par->texte;
824
-
825
-			// tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre}
826
-			if (preg_match(',^(\w+)[\s]+(.*)$,', (string) $par, $m)) {
827
-				$expression = trim($m[1]);
828
-				$champ = trim($m[2]);
829
-				if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) {
830
-					$order = $f($idb, $boucles, $crit, $tri, $champ);
831
-				} else {
832
-					return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
833
-				}
834
-
835
-			// tris de la forme {par champ} ou {par FONCTION(champ)}
836
-			} elseif ($boucle->type_requete == 'DATA' || preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', (string) $par, $match)) {
837
-				// {par FONCTION(champ)}
838
-				if (isset($match) && count($match) > 2) {
839
-					$par = substr($match[2], 1, -1);
840
-					$fct = $match[1];
841
-				}
842
-				// quelques cas spécifiques {par hasard}, {par date}
843
-				if ($par == 'hasard') {
844
-					$order = calculer_critere_par_hasard($idb, $boucles, $crit);
845
-				} elseif ($par == 'date' && !empty($boucle->show['date'])) {
846
-					$order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'";
847
-				} else {
848
-					// cas général {par champ}, {par table.champ}, ...
849
-					$order = calculer_critere_par_champ($idb, $boucles, $crit, $par);
850
-				}
851
-			}
852
-
853
-			// on ne sait pas traiter…
854
-			else {
855
-				return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
856
-			}
857
-
858
-			// En cas d'erreur de squelette retournée par une fonction
859
-			if (is_array($order)) {
860
-				return $order;
861
-			}
862
-		}
863
-
864
-		if (preg_match('/^\'([^"]*)\'$/', (string) $order, $m)) {
865
-			$t = $m[1];
866
-			if (strpos($t, '.') && !in_array($t, $boucle->select)) {
867
-				$boucle->select[] = $t;
868
-			}
869
-		} else {
870
-			$sens = '';
871
-		}
872
-
873
-		if ($fct) {
874
-			$order = preg_match("/^\s*'(.*)'\s*$/", (string) $order, $r)
875
-				? "'$fct(" . $r[1] . ")'"
876
-				: "'$fct(' . $order . ')'";
877
-		}
878
-		$t = $order . $collecte . $sens;
879
-		if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
880
-			$t = $r[1] . $r[2];
881
-		}
882
-
883
-		$boucle->order[] = $t;
884
-	}
800
+    $boucle = &$boucles[$idb];
801
+
802
+    $sens = $collecte = '';
803
+    if ($crit->not) {
804
+        $sens = " . ' DESC'";
805
+    }
806
+    if (isset($boucle->modificateur['collate'])) {
807
+        $collecte = ' . ' . $boucle->modificateur['collate'];
808
+    }
809
+
810
+    // Pour chaque paramètre du critère
811
+    foreach ($crit->param as $tri) {
812
+        $order = $fct = '';
813
+        // tris specifiés dynamiquement {par #ENV{tri}}
814
+        if ($tri[0]->type != 'texte') {
815
+            // calculer le order dynamique qui verifie les champs
816
+            $order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens);
817
+            // ajouter 'hasard' comme possibilité de tri dynamique
818
+            calculer_critere_par_hasard($idb, $boucles, $crit);
819
+        }
820
+        // tris textuels {par titre}
821
+        else {
822
+            $par = array_shift($tri);
823
+            $par = $par->texte;
824
+
825
+            // tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre}
826
+            if (preg_match(',^(\w+)[\s]+(.*)$,', (string) $par, $m)) {
827
+                $expression = trim($m[1]);
828
+                $champ = trim($m[2]);
829
+                if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) {
830
+                    $order = $f($idb, $boucles, $crit, $tri, $champ);
831
+                } else {
832
+                    return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
833
+                }
834
+
835
+            // tris de la forme {par champ} ou {par FONCTION(champ)}
836
+            } elseif ($boucle->type_requete == 'DATA' || preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', (string) $par, $match)) {
837
+                // {par FONCTION(champ)}
838
+                if (isset($match) && count($match) > 2) {
839
+                    $par = substr($match[2], 1, -1);
840
+                    $fct = $match[1];
841
+                }
842
+                // quelques cas spécifiques {par hasard}, {par date}
843
+                if ($par == 'hasard') {
844
+                    $order = calculer_critere_par_hasard($idb, $boucles, $crit);
845
+                } elseif ($par == 'date' && !empty($boucle->show['date'])) {
846
+                    $order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'";
847
+                } else {
848
+                    // cas général {par champ}, {par table.champ}, ...
849
+                    $order = calculer_critere_par_champ($idb, $boucles, $crit, $par);
850
+                }
851
+            }
852
+
853
+            // on ne sait pas traiter…
854
+            else {
855
+                return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
856
+            }
857
+
858
+            // En cas d'erreur de squelette retournée par une fonction
859
+            if (is_array($order)) {
860
+                return $order;
861
+            }
862
+        }
863
+
864
+        if (preg_match('/^\'([^"]*)\'$/', (string) $order, $m)) {
865
+            $t = $m[1];
866
+            if (strpos($t, '.') && !in_array($t, $boucle->select)) {
867
+                $boucle->select[] = $t;
868
+            }
869
+        } else {
870
+            $sens = '';
871
+        }
872
+
873
+        if ($fct) {
874
+            $order = preg_match("/^\s*'(.*)'\s*$/", (string) $order, $r)
875
+                ? "'$fct(" . $r[1] . ")'"
876
+                : "'$fct(' . $order . ')'";
877
+        }
878
+        $t = $order . $collecte . $sens;
879
+        if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
880
+            $t = $r[1] . $r[2];
881
+        }
882
+
883
+        $boucle->order[] = $t;
884
+    }
885 885
 }
886 886
 
887 887
 /**
@@ -895,13 +895,13 @@  discard block
 block discarded – undo
895 895
  * @return string Clause pour le Order by
896 896
  */
897 897
 function calculer_critere_par_hasard($idb, &$boucles, $crit) {
898
-	$boucle = &$boucles[$idb];
899
-	// Si ce n'est fait, ajouter un champ 'hasard' dans le select
900
-	$parha = 'rand() AS hasard';
901
-	if (!in_array($parha, $boucle->select)) {
902
-		$boucle->select[] = $parha;
903
-	}
904
-	return "'hasard'";
898
+    $boucle = &$boucles[$idb];
899
+    // Si ce n'est fait, ajouter un champ 'hasard' dans le select
900
+    $parha = 'rand() AS hasard';
901
+    if (!in_array($parha, $boucle->select)) {
902
+        $boucle->select[] = $parha;
903
+    }
904
+    return "'hasard'";
905 905
 }
906 906
 
907 907
 /**
@@ -925,22 +925,22 @@  discard block
 block discarded – undo
925 925
  * @return string|array Clause pour le Order by (array si erreur)
926 926
  */
927 927
 function calculer_critere_par_expression_num($idb, &$boucles, $crit, $tri, $champ) {
928
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
929
-	if (is_array($_champ)) {
930
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]];
931
-	}
932
-	$boucle = &$boucles[$idb];
933
-	$texte = '0+' . $_champ;
934
-	$suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
935
-	if ($suite !== "''") {
936
-		$texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
937
-	}
938
-	$asnum = 'num' . ($boucle->order ? count($boucle->order) : '');
939
-	$boucle->select[] = $texte . " AS $asnum";
940
-
941
-	$orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ);
942
-	$orderassinum = trim($orderassinum, "'");
943
-	return "'$orderassinum, $asnum'";
928
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
929
+    if (is_array($_champ)) {
930
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]];
931
+    }
932
+    $boucle = &$boucles[$idb];
933
+    $texte = '0+' . $_champ;
934
+    $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
935
+    if ($suite !== "''") {
936
+        $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
937
+    }
938
+    $asnum = 'num' . ($boucle->order ? count($boucle->order) : '');
939
+    $boucle->select[] = $texte . " AS $asnum";
940
+
941
+    $orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ);
942
+    $orderassinum = trim($orderassinum, "'");
943
+    return "'$orderassinum, $asnum'";
944 944
 }
945 945
 
946 946
 /**
@@ -961,34 +961,34 @@  discard block
 block discarded – undo
961 961
  * @return string|array Clause pour le Order by (array si erreur)
962 962
  */
963 963
 function calculer_critere_par_expression_sinum($idb, &$boucles, $crit, $tri, $champ) {
964
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
965
-	if (is_array($_champ)) {
966
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]];
967
-	}
968
-	$boucle = &$boucles[$idb];
969
-	$texte = '0+' . $_champ;
970
-	$suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
971
-	if ($suite !== "''") {
972
-		$texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
973
-	}
974
-
975
-	$as = false;
976
-	$select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS ";
977
-	foreach ($boucle->select as $s) {
978
-		if (str_starts_with((string) $s, $select)) {
979
-			$as = trim(substr((string) $s, strlen($select)));
980
-			if (!preg_match(',\W,', $as)) {
981
-				break;
982
-			}
983
-			$as = false;
984
-		}
985
-	}
986
-
987
-	if (!$as) {
988
-		$as = 'sinum' . ($boucle->order ? count($boucle->order) : '');
989
-		$boucle->select[] = $select . $as;
990
-	}
991
-	return "'$as'";
964
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
965
+    if (is_array($_champ)) {
966
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]];
967
+    }
968
+    $boucle = &$boucles[$idb];
969
+    $texte = '0+' . $_champ;
970
+    $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
971
+    if ($suite !== "''") {
972
+        $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
973
+    }
974
+
975
+    $as = false;
976
+    $select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS ";
977
+    foreach ($boucle->select as $s) {
978
+        if (str_starts_with((string) $s, $select)) {
979
+            $as = trim(substr((string) $s, strlen($select)));
980
+            if (!preg_match(',\W,', $as)) {
981
+                break;
982
+            }
983
+            $as = false;
984
+        }
985
+    }
986
+
987
+    if (!$as) {
988
+        $as = 'sinum' . ($boucle->order ? count($boucle->order) : '');
989
+        $boucle->select[] = $select . $as;
990
+    }
991
+    return "'$as'";
992 992
 }
993 993
 
994 994
 
@@ -1008,13 +1008,13 @@  discard block
 block discarded – undo
1008 1008
  * @return string|array Clause pour le Order by (array si erreur)
1009 1009
  */
1010 1010
 function calculer_critere_par_expression_multi($idb, &$boucles, $crit, $tri, $champ) {
1011
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
1012
-	if (is_array($_champ)) {
1013
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]];
1014
-	}
1015
-	$boucle = &$boucles[$idb];
1016
-	$boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\"";
1017
-	return "'multi'";
1011
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
1012
+    if (is_array($_champ)) {
1013
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]];
1014
+    }
1015
+    $boucle = &$boucles[$idb];
1016
+    $boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\"";
1017
+    return "'multi'";
1018 1018
 }
1019 1019
 
1020 1020
 /**
@@ -1033,56 +1033,56 @@  discard block
 block discarded – undo
1033 1033
  * @return array|string
1034 1034
  */
1035 1035
 function calculer_critere_par_champ($idb, &$boucles, $crit, $par, $raw = false) {
1036
-	$boucle = &$boucles[$idb];
1037
-	$desc = $boucle->show;
1038
-
1039
-	// le champ existe dans la table, pas de souci (le plus commun)
1040
-	if (isset($desc['field'][$par])) {
1041
-		$par = $boucle->id_table . '.' . $par;
1042
-	}
1043
-	// le champ est peut être une jointure
1044
-	else {
1045
-		$table = $table_alias = false; // toutes les tables de jointure possibles
1046
-		$champ = $par;
1047
-
1048
-		// le champ demandé est une exception de jointure {par titre_mot}
1049
-		if (isset($GLOBALS['exceptions_des_jointures'][$par])) {
1050
-			[$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par];
1051
-		} // la table de jointure est explicitement indiquée {par truc.muche}
1052
-		elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) {
1053
-			[, $table, $champ] = $r;
1054
-			$table_alias = $table; // c'est peut-être un alias de table {par L1.titre}
1055
-			$table = table_objet_sql($table);
1056
-		}
1057
-
1058
-		// Si on connait la table d'arrivée, on la demande donc explicitement
1059
-		// Sinon on cherche le champ dans les tables possibles de jointures
1060
-		// Si la table est déjà dans le from, on la réutilise.
1061
-		if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) {
1062
-			$par = $infos['alias'] . '.' . $champ;
1063
-		} elseif (
1064
-			$boucle->jointures_explicites
1065
-			&& ($alias = trouver_jointure_champ($champ, $boucle, explode(' ', (string) $boucle->jointures_explicites), false, $table))
1066
-		) {
1067
-			$par = $alias . '.' . $champ;
1068
-		} elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) {
1069
-			$par = $alias . '.' . $champ;
1070
-		// en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même)
1071
-		} elseif (
1072
-			$table_alias
1073
-			&& isset($boucle->from[$table_alias])
1074
-			&& ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias]))
1075
-		) {
1076
-			$par = $infos['alias'] . '.' . $champ;
1077
-		} elseif ($table) {
1078
-			// On avait table + champ, mais on ne les a pas trouvés
1079
-			return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
1080
-		} else {
1081
-			// Sinon tant pis, ca doit etre un champ synthetise (cf points)
1082
-		}
1083
-	}
1084
-
1085
-	return $raw ? $par : "'$par'";
1036
+    $boucle = &$boucles[$idb];
1037
+    $desc = $boucle->show;
1038
+
1039
+    // le champ existe dans la table, pas de souci (le plus commun)
1040
+    if (isset($desc['field'][$par])) {
1041
+        $par = $boucle->id_table . '.' . $par;
1042
+    }
1043
+    // le champ est peut être une jointure
1044
+    else {
1045
+        $table = $table_alias = false; // toutes les tables de jointure possibles
1046
+        $champ = $par;
1047
+
1048
+        // le champ demandé est une exception de jointure {par titre_mot}
1049
+        if (isset($GLOBALS['exceptions_des_jointures'][$par])) {
1050
+            [$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par];
1051
+        } // la table de jointure est explicitement indiquée {par truc.muche}
1052
+        elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) {
1053
+            [, $table, $champ] = $r;
1054
+            $table_alias = $table; // c'est peut-être un alias de table {par L1.titre}
1055
+            $table = table_objet_sql($table);
1056
+        }
1057
+
1058
+        // Si on connait la table d'arrivée, on la demande donc explicitement
1059
+        // Sinon on cherche le champ dans les tables possibles de jointures
1060
+        // Si la table est déjà dans le from, on la réutilise.
1061
+        if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) {
1062
+            $par = $infos['alias'] . '.' . $champ;
1063
+        } elseif (
1064
+            $boucle->jointures_explicites
1065
+            && ($alias = trouver_jointure_champ($champ, $boucle, explode(' ', (string) $boucle->jointures_explicites), false, $table))
1066
+        ) {
1067
+            $par = $alias . '.' . $champ;
1068
+        } elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) {
1069
+            $par = $alias . '.' . $champ;
1070
+        // en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même)
1071
+        } elseif (
1072
+            $table_alias
1073
+            && isset($boucle->from[$table_alias])
1074
+            && ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias]))
1075
+        ) {
1076
+            $par = $infos['alias'] . '.' . $champ;
1077
+        } elseif ($table) {
1078
+            // On avait table + champ, mais on ne les a pas trouvés
1079
+            return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
1080
+        } else {
1081
+            // Sinon tant pis, ca doit etre un champ synthetise (cf points)
1082
+        }
1083
+    }
1084
+
1085
+    return $raw ? $par : "'$par'";
1086 1086
 }
1087 1087
 
1088 1088
 /**
@@ -1107,33 +1107,33 @@  discard block
 block discarded – undo
1107 1107
  */
1108 1108
 function critere_inverse_dist($idb, &$boucles, $crit) {
1109 1109
 
1110
-	$boucle = &$boucles[$idb];
1111
-	// Classement par ordre inverse
1112
-	if ($crit->not) {
1113
-		critere_parinverse($idb, $boucles, $crit);
1114
-	} else {
1115
-		$order = "' DESC'";
1116
-		// Classement par ordre inverse fonction eventuelle de #ENV{...}
1117
-		if (isset($crit->param[0])) {
1118
-			$critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
1119
-			$order = "(($critere)?' DESC':'')";
1120
-		}
1121
-
1122
-		$n = is_countable($boucle->order) ? count($boucle->order) : 0;
1123
-		if (!$n) {
1124
-			if (isset($boucle->default_order[0])) {
1125
-				$boucle->default_order[0] .= ' . " DESC"';
1126
-			} else {
1127
-				$boucle->default_order[] = ' DESC';
1128
-			}
1129
-		} else {
1130
-			$t = $boucle->order[$n - 1] . " . $order";
1131
-			if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
1132
-				$t = $r[1] . $r[2];
1133
-			}
1134
-			$boucle->order[$n - 1] = $t;
1135
-		}
1136
-	}
1110
+    $boucle = &$boucles[$idb];
1111
+    // Classement par ordre inverse
1112
+    if ($crit->not) {
1113
+        critere_parinverse($idb, $boucles, $crit);
1114
+    } else {
1115
+        $order = "' DESC'";
1116
+        // Classement par ordre inverse fonction eventuelle de #ENV{...}
1117
+        if (isset($crit->param[0])) {
1118
+            $critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
1119
+            $order = "(($critere)?' DESC':'')";
1120
+        }
1121
+
1122
+        $n = is_countable($boucle->order) ? count($boucle->order) : 0;
1123
+        if (!$n) {
1124
+            if (isset($boucle->default_order[0])) {
1125
+                $boucle->default_order[0] .= ' . " DESC"';
1126
+            } else {
1127
+                $boucle->default_order[] = ' DESC';
1128
+            }
1129
+        } else {
1130
+            $t = $boucle->order[$n - 1] . " . $order";
1131
+            if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
1132
+                $t = $r[1] . $r[2];
1133
+            }
1134
+            $boucle->order[$n - 1] = $t;
1135
+        }
1136
+    }
1137 1137
 }
1138 1138
 
1139 1139
 /**
@@ -1145,139 +1145,139 @@  discard block
 block discarded – undo
1145 1145
  * @return void|array
1146 1146
  */
1147 1147
 function critere_par_ordre_liste_dist($idb, &$boucles, $crit) {
1148
-	$boucle = &$boucles[$idb];
1148
+    $boucle = &$boucles[$idb];
1149 1149
 
1150
-	$sens = $collecte = '';
1151
-	if ($crit->not) {
1152
-		$sens = " . ' DESC'";
1153
-	}
1150
+    $sens = $collecte = '';
1151
+    if ($crit->not) {
1152
+        $sens = " . ' DESC'";
1153
+    }
1154 1154
 
1155
-	$crit2 = clone $crit;
1156
-	$crit2->not = false;
1157
-	$crit2->param = [reset($crit->param)];
1158
-	$res = critere_parinverse($idb, $boucles, $crit2);
1155
+    $crit2 = clone $crit;
1156
+    $crit2->not = false;
1157
+    $crit2->param = [reset($crit->param)];
1158
+    $res = critere_parinverse($idb, $boucles, $crit2);
1159 1159
 
1160
-	// erreur ?
1161
-	if (is_array($res)) {
1162
-		return $res;
1163
-	}
1160
+    // erreur ?
1161
+    if (is_array($res)) {
1162
+        return $res;
1163
+    }
1164 1164
 
1165
-	$_order = array_pop($boucle->order);
1165
+    $_order = array_pop($boucle->order);
1166 1166
 
1167
-	$_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent);
1167
+    $_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent);
1168 1168
 
1169
-	$order = "'-FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste(array_reverse($_liste),'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens";
1170
-	$boucle->order[] = $order;
1169
+    $order = "'-FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste(array_reverse($_liste),'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens";
1170
+    $boucle->order[] = $order;
1171 1171
 }
1172 1172
 
1173 1173
 
1174 1174
 function critere_agenda_dist($idb, &$boucles, $crit) {
1175
-	$params = $crit->param;
1176
-
1177
-	if ((is_countable($params) ? count($params) : 0) < 1) {
1178
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1179
-	}
1180
-
1181
-	$boucle = &$boucles[$idb];
1182
-	$parent = $boucle->id_parent;
1183
-	$fields = $boucle->show['field'];
1184
-
1185
-	$date = array_shift($params);
1186
-	$type = array_shift($params);
1187
-
1188
-	// la valeur $type doit etre connue a la compilation
1189
-	// donc etre forcement reduite a un litteral unique dans le source
1190
-	$type = is_object($type[0]) ? $type[0]->texte : null;
1191
-
1192
-	// La valeur date doit designer un champ de la table SQL.
1193
-	// Si c'est un litteral unique dans le source, verifier a la compil,
1194
-	// sinon synthetiser le test de verif pour execution ulterieure
1195
-	// On prendra arbitrairement le premier champ si test negatif.
1196
-	if ((is_countable($date) ? count($date) : 0) == 1 && $date[0]->type == 'texte') {
1197
-		$date = $date[0]->texte;
1198
-		if (!isset($fields[$date])) {
1199
-			return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]];
1200
-		}
1201
-	} else {
1202
-		$a = calculer_liste($date, $idb, $boucles, $parent);
1203
-		$noms = array_keys($fields);
1204
-		$defaut = $noms[0];
1205
-		$noms = implode(' ', $noms);
1206
-		# bien laisser 2 espaces avant $nom pour que strpos<>0
1207
-		$cond = "(\$a=strval($a))AND\nstrpos(\"  $noms \",\" \$a \")";
1208
-		$date = "'.(($cond)\n?\$a:\"$defaut\").'";
1209
-	}
1210
-	$annee = $params ? array_shift($params) : '';
1211
-	$annee = "\n" . 'sprintf("%04d", ($x = ' .
1212
-		calculer_liste($annee, $idb, $boucles, $parent) .
1213
-		') ? $x : date("Y"))';
1214
-
1215
-	$mois = $params ? array_shift($params) : '';
1216
-	$mois = "\n" . 'sprintf("%02d", ($x = ' .
1217
-		calculer_liste($mois, $idb, $boucles, $parent) .
1218
-		') ? $x : date("m"))';
1219
-
1220
-	$jour = $params ? array_shift($params) : '';
1221
-	$jour = "\n" . 'sprintf("%02d", ($x = ' .
1222
-		calculer_liste($jour, $idb, $boucles, $parent) .
1223
-		') ? $x : date("d"))';
1224
-
1225
-	$annee2 = $params ? array_shift($params) : '';
1226
-	$annee2 = "\n" . 'sprintf("%04d", ($x = ' .
1227
-		calculer_liste($annee2, $idb, $boucles, $parent) .
1228
-		') ? $x : date("Y"))';
1229
-
1230
-	$mois2 = $params ? array_shift($params) : '';
1231
-	$mois2 = "\n" . 'sprintf("%02d", ($x = ' .
1232
-		calculer_liste($mois2, $idb, $boucles, $parent) .
1233
-		') ? $x : date("m"))';
1234
-
1235
-	$jour2 = $params ? array_shift($params) : '';
1236
-	$jour2 = "\n" . 'sprintf("%02d", ($x = ' .
1237
-		calculer_liste($jour2, $idb, $boucles, $parent) .
1238
-		') ? $x : date("d"))';
1239
-
1240
-	$date = $boucle->id_table . ".$date";
1241
-
1242
-	$quote_end = ",'" . $boucle->sql_serveur . "','text'";
1243
-	if ($type == 'jour') {
1244
-		$boucle->where[] = [
1245
-			"'='",
1246
-			"'DATE_FORMAT($date, \'%Y%m%d\')'",
1247
-			("sql_quote($annee . $mois . $jour$quote_end)")
1248
-		];
1249
-	} elseif ($type == 'mois') {
1250
-		$boucle->where[] = [
1251
-			"'='",
1252
-			"'DATE_FORMAT($date, \'%Y%m\')'",
1253
-			("sql_quote($annee . $mois$quote_end)")
1254
-		];
1255
-	} elseif ($type == 'semaine') {
1256
-		$boucle->where[] = [
1257
-			"'AND'",
1258
-			[
1259
-				"'>='",
1260
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1261
-				("date_debut_semaine($annee, $mois, $jour)")
1262
-			],
1263
-			[
1264
-				"'<='",
1265
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1266
-				("date_fin_semaine($annee, $mois, $jour)")
1267
-			]
1268
-		];
1269
-	} elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) {
1270
-		$boucle->where[] = [
1271
-			"'AND'",
1272
-			[
1273
-				"'>='",
1274
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1275
-				("sql_quote($annee . $mois . $jour$quote_end)")
1276
-			],
1277
-			["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")]
1278
-		];
1279
-	}
1280
-	// sinon on prend tout
1175
+    $params = $crit->param;
1176
+
1177
+    if ((is_countable($params) ? count($params) : 0) < 1) {
1178
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1179
+    }
1180
+
1181
+    $boucle = &$boucles[$idb];
1182
+    $parent = $boucle->id_parent;
1183
+    $fields = $boucle->show['field'];
1184
+
1185
+    $date = array_shift($params);
1186
+    $type = array_shift($params);
1187
+
1188
+    // la valeur $type doit etre connue a la compilation
1189
+    // donc etre forcement reduite a un litteral unique dans le source
1190
+    $type = is_object($type[0]) ? $type[0]->texte : null;
1191
+
1192
+    // La valeur date doit designer un champ de la table SQL.
1193
+    // Si c'est un litteral unique dans le source, verifier a la compil,
1194
+    // sinon synthetiser le test de verif pour execution ulterieure
1195
+    // On prendra arbitrairement le premier champ si test negatif.
1196
+    if ((is_countable($date) ? count($date) : 0) == 1 && $date[0]->type == 'texte') {
1197
+        $date = $date[0]->texte;
1198
+        if (!isset($fields[$date])) {
1199
+            return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]];
1200
+        }
1201
+    } else {
1202
+        $a = calculer_liste($date, $idb, $boucles, $parent);
1203
+        $noms = array_keys($fields);
1204
+        $defaut = $noms[0];
1205
+        $noms = implode(' ', $noms);
1206
+        # bien laisser 2 espaces avant $nom pour que strpos<>0
1207
+        $cond = "(\$a=strval($a))AND\nstrpos(\"  $noms \",\" \$a \")";
1208
+        $date = "'.(($cond)\n?\$a:\"$defaut\").'";
1209
+    }
1210
+    $annee = $params ? array_shift($params) : '';
1211
+    $annee = "\n" . 'sprintf("%04d", ($x = ' .
1212
+        calculer_liste($annee, $idb, $boucles, $parent) .
1213
+        ') ? $x : date("Y"))';
1214
+
1215
+    $mois = $params ? array_shift($params) : '';
1216
+    $mois = "\n" . 'sprintf("%02d", ($x = ' .
1217
+        calculer_liste($mois, $idb, $boucles, $parent) .
1218
+        ') ? $x : date("m"))';
1219
+
1220
+    $jour = $params ? array_shift($params) : '';
1221
+    $jour = "\n" . 'sprintf("%02d", ($x = ' .
1222
+        calculer_liste($jour, $idb, $boucles, $parent) .
1223
+        ') ? $x : date("d"))';
1224
+
1225
+    $annee2 = $params ? array_shift($params) : '';
1226
+    $annee2 = "\n" . 'sprintf("%04d", ($x = ' .
1227
+        calculer_liste($annee2, $idb, $boucles, $parent) .
1228
+        ') ? $x : date("Y"))';
1229
+
1230
+    $mois2 = $params ? array_shift($params) : '';
1231
+    $mois2 = "\n" . 'sprintf("%02d", ($x = ' .
1232
+        calculer_liste($mois2, $idb, $boucles, $parent) .
1233
+        ') ? $x : date("m"))';
1234
+
1235
+    $jour2 = $params ? array_shift($params) : '';
1236
+    $jour2 = "\n" . 'sprintf("%02d", ($x = ' .
1237
+        calculer_liste($jour2, $idb, $boucles, $parent) .
1238
+        ') ? $x : date("d"))';
1239
+
1240
+    $date = $boucle->id_table . ".$date";
1241
+
1242
+    $quote_end = ",'" . $boucle->sql_serveur . "','text'";
1243
+    if ($type == 'jour') {
1244
+        $boucle->where[] = [
1245
+            "'='",
1246
+            "'DATE_FORMAT($date, \'%Y%m%d\')'",
1247
+            ("sql_quote($annee . $mois . $jour$quote_end)")
1248
+        ];
1249
+    } elseif ($type == 'mois') {
1250
+        $boucle->where[] = [
1251
+            "'='",
1252
+            "'DATE_FORMAT($date, \'%Y%m\')'",
1253
+            ("sql_quote($annee . $mois$quote_end)")
1254
+        ];
1255
+    } elseif ($type == 'semaine') {
1256
+        $boucle->where[] = [
1257
+            "'AND'",
1258
+            [
1259
+                "'>='",
1260
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1261
+                ("date_debut_semaine($annee, $mois, $jour)")
1262
+            ],
1263
+            [
1264
+                "'<='",
1265
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1266
+                ("date_fin_semaine($annee, $mois, $jour)")
1267
+            ]
1268
+        ];
1269
+    } elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) {
1270
+        $boucle->where[] = [
1271
+            "'AND'",
1272
+            [
1273
+                "'>='",
1274
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1275
+                ("sql_quote($annee . $mois . $jour$quote_end)")
1276
+            ],
1277
+            ["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")]
1278
+        ];
1279
+    }
1280
+    // sinon on prend tout
1281 1281
 }
1282 1282
 
1283 1283
 
@@ -1302,33 +1302,33 @@  discard block
 block discarded – undo
1302 1302
  * @return void
1303 1303
  **/
1304 1304
 function calculer_critere_parties($idb, &$boucles, $crit) {
1305
-	$boucle = &$boucles[$idb];
1306
-	$a1 = $crit->param[0];
1307
-	$a2 = $crit->param[1];
1308
-	$op = $crit->op;
1309
-
1310
-	[$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1);
1311
-	[$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2);
1312
-
1313
-	if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) {
1314
-		$boucle->limit = $a11 . ',' . $a21;
1315
-	} else {
1316
-		// 3 dans {1/3}, {2,3} ou {1,n-3}
1317
-		$boucle->total_parties = ($a21 != 'n') ? $a21 : $a22;
1318
-		// 2 dans {2/3}, {2,5}, {n-2,1}
1319
-		$partie = ($a11 != 'n') ? $a11 : $a12;
1320
-		$mode = (($op == '/') ? '/' :
1321
-			(($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+'));
1322
-		// cas simple {0,#ENV{truc}} compilons le en LIMIT :
1323
-		if ($a11 !== 'n' && $a21 !== 'n' && $mode == '++' && $op == ',') {
1324
-			$boucle->limit =
1325
-				(is_numeric($a11) ? "'$a11'" : $a11)
1326
-				. ".','."
1327
-				. (is_numeric($a21) ? "'$a21'" : $a21);
1328
-		} else {
1329
-			calculer_parties($boucles, $idb, $partie, $mode);
1330
-		}
1331
-	}
1305
+    $boucle = &$boucles[$idb];
1306
+    $a1 = $crit->param[0];
1307
+    $a2 = $crit->param[1];
1308
+    $op = $crit->op;
1309
+
1310
+    [$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1);
1311
+    [$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2);
1312
+
1313
+    if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) {
1314
+        $boucle->limit = $a11 . ',' . $a21;
1315
+    } else {
1316
+        // 3 dans {1/3}, {2,3} ou {1,n-3}
1317
+        $boucle->total_parties = ($a21 != 'n') ? $a21 : $a22;
1318
+        // 2 dans {2/3}, {2,5}, {n-2,1}
1319
+        $partie = ($a11 != 'n') ? $a11 : $a12;
1320
+        $mode = (($op == '/') ? '/' :
1321
+            (($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+'));
1322
+        // cas simple {0,#ENV{truc}} compilons le en LIMIT :
1323
+        if ($a11 !== 'n' && $a21 !== 'n' && $mode == '++' && $op == ',') {
1324
+            $boucle->limit =
1325
+                (is_numeric($a11) ? "'$a11'" : $a11)
1326
+                . ".','."
1327
+                . (is_numeric($a21) ? "'$a21'" : $a21);
1328
+        } else {
1329
+            calculer_parties($boucles, $idb, $partie, $mode);
1330
+        }
1331
+    }
1332 1332
 }
1333 1333
 
1334 1334
 /**
@@ -1356,63 +1356,63 @@  discard block
 block discarded – undo
1356 1356
  * @return void
1357 1357
  **/
1358 1358
 function calculer_parties(&$boucles, $id_boucle, $debut, $mode) {
1359
-	$total_parties = $boucles[$id_boucle]->total_parties;
1360
-
1361
-	preg_match(',([+-/p])([+-/])?,', $mode, $regs);
1362
-	[, $op1, $op2] = array_pad($regs, 3, null);
1363
-	$nombre_boucle = "\$Numrows['$id_boucle']['total']";
1364
-	// {1/3}
1365
-	if ($op1 == '/') {
1366
-		$pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)";
1367
-		$totpos = is_numeric($total_parties) ? ($total_parties) :
1368
-			"($total_parties ? $total_parties : 1)";
1369
-		$fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1";
1370
-		$debut = $pmoins1 ? "ceil(($nombre_boucle * $pmoins1)/$totpos);" : 0;
1371
-	} else {
1372
-		// cas {n-1,x}
1373
-		if ($op1 == '-') {
1374
-			$debut = "$nombre_boucle - $debut;";
1375
-		}
1376
-
1377
-		// cas {x,n-1}
1378
-		if ($op2 == '-') {
1379
-			$fin = '$debut_boucle + ' . $nombre_boucle . ' - '
1380
-				. (is_numeric($total_parties) ? ($total_parties + 1) :
1381
-					($total_parties . ' - 1'));
1382
-		} else {
1383
-			// {x,1} ou {pagination}
1384
-			$fin = '$debut_boucle'
1385
-				. (is_numeric($total_parties) ?
1386
-					(($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) :
1387
-					('+' . $total_parties . ' - 1'));
1388
-		}
1389
-
1390
-		// {pagination}, gerer le debut_xx=-1 pour tout voir
1391
-		if ($op1 == 'p') {
1392
-			$debut .= ";\n	\$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))";
1393
-			$debut .= ";\n	\$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))";
1394
-			$fin = "(\$tout ? $nombre_boucle : $fin)";
1395
-		}
1396
-	}
1397
-
1398
-	// Notes :
1399
-	// $debut_boucle et $fin_boucle sont les indices SQL du premier
1400
-	// et du dernier demandes dans la boucle : 0 pour le premier,
1401
-	// n-1 pour le dernier ; donc total_boucle = 1 + debut - fin
1402
-	// Utiliser min pour rabattre $fin_boucle sur total_boucle.
1403
-
1404
-	$boucles[$id_boucle]->mode_partie = "\n\t"
1405
-		. '$debut_boucle = ' . $debut . ";\n	"
1406
-		. "\$debut_boucle = intval(\$debut_boucle);\n	"
1407
-		. '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n	"
1408
-		. '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n	"
1409
-		. '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);'
1410
-		. "\n\tif (\$debut_boucle>0"
1411
-		. " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']"
1412
-		. " AND \$iter->seek(\$debut_boucle,'continue'))"
1413
-		. "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t";
1414
-
1415
-	$boucles[$id_boucle]->partie = "
1359
+    $total_parties = $boucles[$id_boucle]->total_parties;
1360
+
1361
+    preg_match(',([+-/p])([+-/])?,', $mode, $regs);
1362
+    [, $op1, $op2] = array_pad($regs, 3, null);
1363
+    $nombre_boucle = "\$Numrows['$id_boucle']['total']";
1364
+    // {1/3}
1365
+    if ($op1 == '/') {
1366
+        $pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)";
1367
+        $totpos = is_numeric($total_parties) ? ($total_parties) :
1368
+            "($total_parties ? $total_parties : 1)";
1369
+        $fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1";
1370
+        $debut = $pmoins1 ? "ceil(($nombre_boucle * $pmoins1)/$totpos);" : 0;
1371
+    } else {
1372
+        // cas {n-1,x}
1373
+        if ($op1 == '-') {
1374
+            $debut = "$nombre_boucle - $debut;";
1375
+        }
1376
+
1377
+        // cas {x,n-1}
1378
+        if ($op2 == '-') {
1379
+            $fin = '$debut_boucle + ' . $nombre_boucle . ' - '
1380
+                . (is_numeric($total_parties) ? ($total_parties + 1) :
1381
+                    ($total_parties . ' - 1'));
1382
+        } else {
1383
+            // {x,1} ou {pagination}
1384
+            $fin = '$debut_boucle'
1385
+                . (is_numeric($total_parties) ?
1386
+                    (($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) :
1387
+                    ('+' . $total_parties . ' - 1'));
1388
+        }
1389
+
1390
+        // {pagination}, gerer le debut_xx=-1 pour tout voir
1391
+        if ($op1 == 'p') {
1392
+            $debut .= ";\n	\$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))";
1393
+            $debut .= ";\n	\$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))";
1394
+            $fin = "(\$tout ? $nombre_boucle : $fin)";
1395
+        }
1396
+    }
1397
+
1398
+    // Notes :
1399
+    // $debut_boucle et $fin_boucle sont les indices SQL du premier
1400
+    // et du dernier demandes dans la boucle : 0 pour le premier,
1401
+    // n-1 pour le dernier ; donc total_boucle = 1 + debut - fin
1402
+    // Utiliser min pour rabattre $fin_boucle sur total_boucle.
1403
+
1404
+    $boucles[$id_boucle]->mode_partie = "\n\t"
1405
+        . '$debut_boucle = ' . $debut . ";\n	"
1406
+        . "\$debut_boucle = intval(\$debut_boucle);\n	"
1407
+        . '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n	"
1408
+        . '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n	"
1409
+        . '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);'
1410
+        . "\n\tif (\$debut_boucle>0"
1411
+        . " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']"
1412
+        . " AND \$iter->seek(\$debut_boucle,'continue'))"
1413
+        . "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t";
1414
+
1415
+    $boucles[$id_boucle]->partie = "
1416 1416
 		if (\$Numrows['$id_boucle']['compteur_boucle'] <= \$debut_boucle) continue;
1417 1417
 		if (\$Numrows['$id_boucle']['compteur_boucle']-1 > \$fin_boucle) break;";
1418 1418
 }
@@ -1429,26 +1429,26 @@  discard block
 block discarded – undo
1429 1429
  * @return array          Valeur de l'élément (peut être une expression PHP), Nombre soustrait
1430 1430
  **/
1431 1431
 function calculer_critere_parties_aux($idb, &$boucles, $param) {
1432
-	if ($param[0]->type != 'texte') {
1433
-		$a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent);
1434
-		if (isset($param[1]->texte)) {
1435
-			preg_match(',^\s*(-(\d+))?\s*$,', (string) $param[1]->texte, $m);
1436
-
1437
-			return ["intval($a1)", ((isset($m[2]) && $m[2]) ? $m[2] : 0)];
1438
-		} else {
1439
-			return ["intval($a1)", 0];
1440
-		}
1441
-	} else {
1442
-		preg_match(',^\s*((\d+)|n)\s*(-\s*(\d+)?\s*)?$,', (string) $param[0]->texte, $m);
1443
-		$a1 = $m[1];
1444
-		if (empty($m[3])) {
1445
-			return [$a1, 0];
1446
-		} elseif (!empty($m[4])) {
1447
-			return [$a1, $m[4]];
1448
-		} else {
1449
-			return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)];
1450
-		}
1451
-	}
1432
+    if ($param[0]->type != 'texte') {
1433
+        $a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent);
1434
+        if (isset($param[1]->texte)) {
1435
+            preg_match(',^\s*(-(\d+))?\s*$,', (string) $param[1]->texte, $m);
1436
+
1437
+            return ["intval($a1)", ((isset($m[2]) && $m[2]) ? $m[2] : 0)];
1438
+        } else {
1439
+            return ["intval($a1)", 0];
1440
+        }
1441
+    } else {
1442
+        preg_match(',^\s*((\d+)|n)\s*(-\s*(\d+)?\s*)?$,', (string) $param[0]->texte, $m);
1443
+        $a1 = $m[1];
1444
+        if (empty($m[3])) {
1445
+            return [$a1, 0];
1446
+        } elseif (!empty($m[4])) {
1447
+            return [$a1, $m[4]];
1448
+        } else {
1449
+            return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)];
1450
+        }
1451
+    }
1452 1452
 }
1453 1453
 
1454 1454
 
@@ -1475,46 +1475,46 @@  discard block
 block discarded – undo
1475 1475
  *     array : Erreur sur un des critères
1476 1476
  **/
1477 1477
 function calculer_criteres($idb, &$boucles) {
1478
-	$msg = '';
1479
-	$boucle = $boucles[$idb];
1480
-	$table = strtoupper((string) $boucle->type_requete);
1481
-	$serveur = strtolower((string) $boucle->sql_serveur);
1482
-
1483
-	$defaut = charger_fonction('DEFAUT', 'calculer_critere');
1484
-	// s'il y avait une erreur de syntaxe, propager cette info
1485
-	if (!is_array($boucle->criteres)) {
1486
-		return [];
1487
-	}
1488
-
1489
-	foreach ($boucle->criteres as $crit) {
1490
-		$critere = $crit->op;
1491
-		// critere personnalise ?
1492
-		if (
1493
-			(!$serveur
1494
-				|| !function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere)
1495
-				&& !function_exists($f .= '_dist')
1496
-				&& !function_exists($f = 'critere_' . $serveur . '_' . $critere)
1497
-				&& !function_exists($f .= '_dist')
1498
-			)
1499
-			&& !function_exists($f = 'critere_' . $table . '_' . $critere)
1500
-			&& !function_exists($f .= '_dist')
1501
-			&& !function_exists($f = 'critere_' . $critere)
1502
-			&& !function_exists($f .= '_dist')
1503
-		) {
1504
-			// fonction critere standard
1505
-			$f = $defaut;
1506
-		}
1507
-		// compile le critere
1508
-		$res = $f($idb, $boucles, $crit);
1509
-
1510
-		// Gestion centralisee des erreurs pour pouvoir propager
1511
-		if (is_array($res)) {
1512
-			$msg = $res;
1513
-			erreur_squelette($msg, $boucle);
1514
-		}
1515
-	}
1516
-
1517
-	return $msg;
1478
+    $msg = '';
1479
+    $boucle = $boucles[$idb];
1480
+    $table = strtoupper((string) $boucle->type_requete);
1481
+    $serveur = strtolower((string) $boucle->sql_serveur);
1482
+
1483
+    $defaut = charger_fonction('DEFAUT', 'calculer_critere');
1484
+    // s'il y avait une erreur de syntaxe, propager cette info
1485
+    if (!is_array($boucle->criteres)) {
1486
+        return [];
1487
+    }
1488
+
1489
+    foreach ($boucle->criteres as $crit) {
1490
+        $critere = $crit->op;
1491
+        // critere personnalise ?
1492
+        if (
1493
+            (!$serveur
1494
+                || !function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere)
1495
+                && !function_exists($f .= '_dist')
1496
+                && !function_exists($f = 'critere_' . $serveur . '_' . $critere)
1497
+                && !function_exists($f .= '_dist')
1498
+            )
1499
+            && !function_exists($f = 'critere_' . $table . '_' . $critere)
1500
+            && !function_exists($f .= '_dist')
1501
+            && !function_exists($f = 'critere_' . $critere)
1502
+            && !function_exists($f .= '_dist')
1503
+        ) {
1504
+            // fonction critere standard
1505
+            $f = $defaut;
1506
+        }
1507
+        // compile le critere
1508
+        $res = $f($idb, $boucles, $crit);
1509
+
1510
+        // Gestion centralisee des erreurs pour pouvoir propager
1511
+        if (is_array($res)) {
1512
+            $msg = $res;
1513
+            erreur_squelette($msg, $boucle);
1514
+        }
1515
+    }
1516
+
1517
+    return $msg;
1518 1518
 }
1519 1519
 
1520 1520
 /**
@@ -1529,11 +1529,11 @@  discard block
 block discarded – undo
1529 1529
  * @return string         Code compilé rééchappé
1530 1530
  */
1531 1531
 function kwote($lisp, $serveur = '', $type = '') {
1532
-	if (preg_match(_CODE_QUOTE, $lisp, $r)) {
1533
-		return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"';
1534
-	} else {
1535
-		return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')";
1536
-	}
1532
+    if (preg_match(_CODE_QUOTE, $lisp, $r)) {
1533
+        return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"';
1534
+    } else {
1535
+        return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')";
1536
+    }
1537 1537
 }
1538 1538
 
1539 1539
 
@@ -1552,81 +1552,81 @@  discard block
 block discarded – undo
1552 1552
  * @return void|array
1553 1553
  **/
1554 1554
 function critere_IN_dist($idb, &$boucles, $crit) {
1555
-	$r = calculer_critere_infixe($idb, $boucles, $crit);
1556
-	if (!$r) {
1557
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1558
-	}
1559
-	[$arg, $op, $val, $col, $where_complement] = $r;
1560
-
1561
-	$in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col);
1562
-
1563
-	//	inserer la condition; exemple: {id_mot ?IN (66, 62, 64)}
1564
-	$where = $in;
1565
-	if ($crit->cond) {
1566
-		$pred = calculer_argument_precedent($idb, $col, $boucles);
1567
-		$where = ["'?'", $pred, $where, "''"];
1568
-		if ($where_complement) { // condition annexe du type "AND (objet='article')"
1569
-		$where_complement = ["'?'", $pred, $where_complement, "''"];
1570
-		}
1571
-	}
1572
-	if ($crit->exclus) {
1573
-		if (!preg_match(',^L\d+[.],', (string) $arg)) {
1574
-			$where = ["'NOT'", $where];
1575
-		} else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1576
-			// c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1577
-		{
1578
-			$where = [
1579
-				"'NOT'",
1580
-				[
1581
-					"'IN'",
1582
-					"'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1583
-					["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1584
-				]
1585
-			];
1586
-		}
1587
-	}
1588
-
1589
-	$boucles[$idb]->where[] = $where;
1590
-	if ($where_complement) { // condition annexe du type "AND (objet='article')"
1591
-	$boucles[$idb]->where[] = $where_complement;
1592
-	}
1555
+    $r = calculer_critere_infixe($idb, $boucles, $crit);
1556
+    if (!$r) {
1557
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1558
+    }
1559
+    [$arg, $op, $val, $col, $where_complement] = $r;
1560
+
1561
+    $in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col);
1562
+
1563
+    //	inserer la condition; exemple: {id_mot ?IN (66, 62, 64)}
1564
+    $where = $in;
1565
+    if ($crit->cond) {
1566
+        $pred = calculer_argument_precedent($idb, $col, $boucles);
1567
+        $where = ["'?'", $pred, $where, "''"];
1568
+        if ($where_complement) { // condition annexe du type "AND (objet='article')"
1569
+        $where_complement = ["'?'", $pred, $where_complement, "''"];
1570
+        }
1571
+    }
1572
+    if ($crit->exclus) {
1573
+        if (!preg_match(',^L\d+[.],', (string) $arg)) {
1574
+            $where = ["'NOT'", $where];
1575
+        } else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1576
+            // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1577
+        {
1578
+            $where = [
1579
+                "'NOT'",
1580
+                [
1581
+                    "'IN'",
1582
+                    "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1583
+                    ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1584
+                ]
1585
+            ];
1586
+        }
1587
+    }
1588
+
1589
+    $boucles[$idb]->where[] = $where;
1590
+    if ($where_complement) { // condition annexe du type "AND (objet='article')"
1591
+    $boucles[$idb]->where[] = $where_complement;
1592
+    }
1593 1593
 }
1594 1594
 
1595 1595
 function critere_IN_cas($idb, &$boucles, $crit2, $arg, $op, $val, $col) {
1596
-	static $num = [];
1597
-	$descr = $boucles[$idb]->descr;
1598
-	$cpt = &$num[$descr['nom']][$descr['gram']][$idb];
1599
-
1600
-	$var = '$in' . $cpt++;
1601
-	$x = "\n\t$var = array();";
1602
-	foreach ($val as $k => $v) {
1603
-		if (preg_match(",^(\n//.*\n)?'(.*)'$,", (string) $v, $r)) {
1604
-			// optimiser le traitement des constantes
1605
-			if (is_numeric($r[2])) {
1606
-				$x .= "\n\t$var" . "[]= $r[2];";
1607
-			} else {
1608
-				$x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';';
1609
-			}
1610
-		} else {
1611
-			// Pour permettre de passer des tableaux de valeurs
1612
-			// on repere l'utilisation brute de #ENV**{X},
1613
-			// c'est-a-dire sa  traduction en ($PILE[0][X]).
1614
-			// et on deballe mais en rajoutant l'anti XSS
1615
-			$x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);";
1616
-		}
1617
-	}
1618
-
1619
-	$boucles[$idb]->in .= $x;
1620
-
1621
-	// inserer le tri par defaut selon les ordres du IN ...
1622
-	// avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp)
1623
-	// et que l'on limite donc strictement aux cas necessaires :
1624
-	// si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle
1625
-	if (!$crit2) {
1626
-		$boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))";
1627
-	}
1628
-
1629
-	return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')';
1596
+    static $num = [];
1597
+    $descr = $boucles[$idb]->descr;
1598
+    $cpt = &$num[$descr['nom']][$descr['gram']][$idb];
1599
+
1600
+    $var = '$in' . $cpt++;
1601
+    $x = "\n\t$var = array();";
1602
+    foreach ($val as $k => $v) {
1603
+        if (preg_match(",^(\n//.*\n)?'(.*)'$,", (string) $v, $r)) {
1604
+            // optimiser le traitement des constantes
1605
+            if (is_numeric($r[2])) {
1606
+                $x .= "\n\t$var" . "[]= $r[2];";
1607
+            } else {
1608
+                $x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';';
1609
+            }
1610
+        } else {
1611
+            // Pour permettre de passer des tableaux de valeurs
1612
+            // on repere l'utilisation brute de #ENV**{X},
1613
+            // c'est-a-dire sa  traduction en ($PILE[0][X]).
1614
+            // et on deballe mais en rajoutant l'anti XSS
1615
+            $x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);";
1616
+        }
1617
+    }
1618
+
1619
+    $boucles[$idb]->in .= $x;
1620
+
1621
+    // inserer le tri par defaut selon les ordres du IN ...
1622
+    // avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp)
1623
+    // et que l'on limite donc strictement aux cas necessaires :
1624
+    // si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle
1625
+    if (!$crit2) {
1626
+        $boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))";
1627
+    }
1628
+
1629
+    return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')';
1630 1630
 }
1631 1631
 
1632 1632
 /**
@@ -1642,22 +1642,22 @@  discard block
 block discarded – undo
1642 1642
  * @return void
1643 1643
  */
1644 1644
 function critere_where_dist($idb, &$boucles, $crit) {
1645
-	$boucle = &$boucles[$idb];
1646
-	if (isset($crit->param[0])) {
1647
-		$_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1648
-	} else {
1649
-		$_where = "spip_sanitize_from_request(\$Pile[0]['where'] ?? null, 'where', 'vide')";
1650
-	}
1651
-
1652
-	if ($crit->cond) {
1653
-		$_where = "$_where ?: ''";
1654
-	}
1655
-
1656
-	if ($crit->not) {
1657
-		$_where = "['NOT', $_where]";
1658
-	}
1659
-
1660
-	$boucle->where[] = $_where;
1645
+    $boucle = &$boucles[$idb];
1646
+    if (isset($crit->param[0])) {
1647
+        $_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1648
+    } else {
1649
+        $_where = "spip_sanitize_from_request(\$Pile[0]['where'] ?? null, 'where', 'vide')";
1650
+    }
1651
+
1652
+    if ($crit->cond) {
1653
+        $_where = "$_where ?: ''";
1654
+    }
1655
+
1656
+    if ($crit->not) {
1657
+        $_where = "['NOT', $_where]";
1658
+    }
1659
+
1660
+    $boucle->where[] = $_where;
1661 1661
 }
1662 1662
 
1663 1663
 /**
@@ -1673,22 +1673,22 @@  discard block
 block discarded – undo
1673 1673
  * @return void
1674 1674
  */
1675 1675
 function critere_having_dist($idb, &$boucles, $crit) {
1676
-	$boucle = &$boucles[$idb];
1677
-	if (isset($crit->param[0])) {
1678
-		$_having = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1679
-	} else {
1680
-		$_having = "spip_sanitize_from_request(\$Pile[0]['having'] ?? null, 'having', 'vide')";
1681
-	}
1682
-
1683
-	if ($crit->cond) {
1684
-		$_having = "$_having ?: ''";
1685
-	}
1686
-
1687
-	if ($crit->not) {
1688
-		$_having = "['NOT', $_having]";
1689
-	}
1690
-
1691
-	$boucle->having[] = $_having;
1676
+    $boucle = &$boucles[$idb];
1677
+    if (isset($crit->param[0])) {
1678
+        $_having = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1679
+    } else {
1680
+        $_having = "spip_sanitize_from_request(\$Pile[0]['having'] ?? null, 'having', 'vide')";
1681
+    }
1682
+
1683
+    if ($crit->cond) {
1684
+        $_having = "$_having ?: ''";
1685
+    }
1686
+
1687
+    if ($crit->not) {
1688
+        $_having = "['NOT', $_having]";
1689
+    }
1690
+
1691
+    $boucle->having[] = $_having;
1692 1692
 }
1693 1693
 
1694 1694
 /**
@@ -1716,31 +1716,31 @@  discard block
 block discarded – undo
1716 1716
  * @return void
1717 1717
  */
1718 1718
 function critere_id__dist($idb, &$boucles, $crit) {
1719
-	/** @var Boucle $boucle */
1720
-	$boucle = $boucles[$idb];
1721
-
1722
-	$champs = lister_champs_id_conditionnel(
1723
-		$boucle->show['table'],
1724
-		$boucle->show,
1725
-		$boucle->sql_serveur
1726
-	);
1727
-
1728
-	// ne pas tenir compte des critères identiques déjà présents.
1729
-	if (!empty($boucle->modificateur['criteres'])) {
1730
-		$champs = array_diff($champs, array_keys($boucle->modificateur['criteres']));
1731
-	}
1732
-	// nous aider en mode debug.
1733
-	$boucle->debug[] = 'id_ : ' . implode(', ', $champs);
1734
-	$boucle->modificateur['id_'] = $champs;
1735
-
1736
-	// créer un critère {id_xxx?} de chaque champ retenu
1737
-	foreach ($champs as $champ) {
1738
-		$critere_id_table = new Critere();
1739
-		$critere_id_table->op = $champ;
1740
-		$critere_id_table->cond = true;
1741
-		$critere_id_table->ligne = $crit->ligne;
1742
-		calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table);
1743
-	}
1719
+    /** @var Boucle $boucle */
1720
+    $boucle = $boucles[$idb];
1721
+
1722
+    $champs = lister_champs_id_conditionnel(
1723
+        $boucle->show['table'],
1724
+        $boucle->show,
1725
+        $boucle->sql_serveur
1726
+    );
1727
+
1728
+    // ne pas tenir compte des critères identiques déjà présents.
1729
+    if (!empty($boucle->modificateur['criteres'])) {
1730
+        $champs = array_diff($champs, array_keys($boucle->modificateur['criteres']));
1731
+    }
1732
+    // nous aider en mode debug.
1733
+    $boucle->debug[] = 'id_ : ' . implode(', ', $champs);
1734
+    $boucle->modificateur['id_'] = $champs;
1735
+
1736
+    // créer un critère {id_xxx?} de chaque champ retenu
1737
+    foreach ($champs as $champ) {
1738
+        $critere_id_table = new Critere();
1739
+        $critere_id_table->op = $champ;
1740
+        $critere_id_table->cond = true;
1741
+        $critere_id_table->ligne = $crit->ligne;
1742
+        calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table);
1743
+    }
1744 1744
 }
1745 1745
 
1746 1746
 /**
@@ -1760,74 +1760,74 @@  discard block
 block discarded – undo
1760 1760
  * @return array Liste de nom de champs (tel que id_article, id_mot, id_parent ...)
1761 1761
  */
1762 1762
 function lister_champs_id_conditionnel($table, $desc = null, $serveur = '') {
1763
-	// calculer la description de la table
1764
-	if (!is_array($desc)) {
1765
-		$desc = description_table($table, $serveur);
1766
-	}
1767
-	if (!$desc) {
1768
-		return [];
1769
-	}
1770
-
1771
-	// Les champs id_xx de la table demandée
1772
-	$champs = array_filter(
1773
-		array_keys($desc['field']),
1774
-		fn($champ) => str_starts_with($champ, 'id_') || $champ == 'objet'
1775
-	);
1776
-
1777
-	// Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute.
1778
-	if (
1779
-		in_array('id_rubrique', $champs)
1780
-		&& !in_array('id_secteur', $champs)
1781
-	) {
1782
-		$champs[] = 'id_secteur';
1783
-	}
1784
-
1785
-	// On ne fera pas mieux pour les tables d’un autre serveur
1786
-	if ($serveur) {
1787
-		return $champs;
1788
-	}
1789
-
1790
-	$primary = false;
1791
-	$associable = false;
1792
-	include_spip('action/editer_liens');
1793
-
1794
-	if (isset($desc['type'])) {
1795
-		$primary = id_table_objet($desc['type']);
1796
-		$associable = objet_associable($desc['type']);
1797
-	}
1798
-	if (isset($desc['field']['id_objet']) && isset($desc['field']['objet'])) {
1799
-		$associable = true;
1800
-	}
1801
-
1802
-	// liste de toutes les tables principales, sauf la notre
1803
-	$tables = lister_tables_objets_sql();
1804
-	unset($tables[$table]);
1805
-
1806
-	foreach ($tables as $_table => $_desc) {
1807
-		if (
1808
-			$associable
1809
-			|| $primary && array_key_exists($primary, $_desc['field'])
1810
-			|| objet_associable($_desc['type'])
1811
-		) {
1812
-			$champs[] = id_table_objet($_table);
1813
-		}
1814
-	}
1815
-	$champs = array_values(array_unique($champs));
1816
-
1817
-	// Exclusions de certains id
1818
-	$exclusions = pipeline(
1819
-		'exclure_id_conditionnel',
1820
-		[
1821
-			'args' => [
1822
-				'table' => $table,
1823
-				'id_table_objet' => $primary,
1824
-				'associable' => $associable,
1825
-			],
1826
-			'data' => [],
1827
-		]
1828
-	);
1829
-
1830
-	return array_diff($champs, $exclusions);
1763
+    // calculer la description de la table
1764
+    if (!is_array($desc)) {
1765
+        $desc = description_table($table, $serveur);
1766
+    }
1767
+    if (!$desc) {
1768
+        return [];
1769
+    }
1770
+
1771
+    // Les champs id_xx de la table demandée
1772
+    $champs = array_filter(
1773
+        array_keys($desc['field']),
1774
+        fn($champ) => str_starts_with($champ, 'id_') || $champ == 'objet'
1775
+    );
1776
+
1777
+    // Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute.
1778
+    if (
1779
+        in_array('id_rubrique', $champs)
1780
+        && !in_array('id_secteur', $champs)
1781
+    ) {
1782
+        $champs[] = 'id_secteur';
1783
+    }
1784
+
1785
+    // On ne fera pas mieux pour les tables d’un autre serveur
1786
+    if ($serveur) {
1787
+        return $champs;
1788
+    }
1789
+
1790
+    $primary = false;
1791
+    $associable = false;
1792
+    include_spip('action/editer_liens');
1793
+
1794
+    if (isset($desc['type'])) {
1795
+        $primary = id_table_objet($desc['type']);
1796
+        $associable = objet_associable($desc['type']);
1797
+    }
1798
+    if (isset($desc['field']['id_objet']) && isset($desc['field']['objet'])) {
1799
+        $associable = true;
1800
+    }
1801
+
1802
+    // liste de toutes les tables principales, sauf la notre
1803
+    $tables = lister_tables_objets_sql();
1804
+    unset($tables[$table]);
1805
+
1806
+    foreach ($tables as $_table => $_desc) {
1807
+        if (
1808
+            $associable
1809
+            || $primary && array_key_exists($primary, $_desc['field'])
1810
+            || objet_associable($_desc['type'])
1811
+        ) {
1812
+            $champs[] = id_table_objet($_table);
1813
+        }
1814
+    }
1815
+    $champs = array_values(array_unique($champs));
1816
+
1817
+    // Exclusions de certains id
1818
+    $exclusions = pipeline(
1819
+        'exclure_id_conditionnel',
1820
+        [
1821
+            'args' => [
1822
+                'table' => $table,
1823
+                'id_table_objet' => $primary,
1824
+                'associable' => $associable,
1825
+            ],
1826
+            'data' => [],
1827
+        ]
1828
+    );
1829
+
1830
+    return array_diff($champs, $exclusions);
1831 1831
 }
1832 1832
 
1833 1833
 /**
@@ -1882,31 +1882,31 @@  discard block
 block discarded – undo
1882 1882
  * @return void
1883 1883
  */
1884 1884
 function critere_tri_dist($idb, &$boucles, $crit) {
1885
-	$boucle = &$boucles[$idb];
1886
-
1887
-	// definition du champ par defaut
1888
-	$_champ_defaut = isset($crit->param[0][0])
1889
-		? calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent)
1890
-		: "''";
1891
-	$_liste_sens_defaut = isset($crit->param[1][0])
1892
-		? calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent)
1893
-		: '1';
1894
-	$_variable = isset($crit->param[2][0])
1895
-		? calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent)
1896
-		: "'$idb'";
1897
-
1898
-	$_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):'')";
1899
-
1900
-	$_sens_defaut = "(is_array(\$s=$_liste_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)";
1901
-	$_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)";
1902
-
1903
-	$boucle->modificateur['tri_champ'] = $_tri;
1904
-	$boucle->modificateur['tri_sens'] = $_sens;
1905
-	$boucle->modificateur['tri_liste_sens_defaut'] = $_liste_sens_defaut;
1906
-	$boucle->modificateur['tri_nom'] = $_variable;
1907
-	// faut il inserer un test sur l'existence de $tri parmi les champs de la table ?
1908
-	// evite des erreurs sql, mais peut empecher des tri sur jointure ...
1909
-	$boucle->hash .= "
1885
+    $boucle = &$boucles[$idb];
1886
+
1887
+    // definition du champ par defaut
1888
+    $_champ_defaut = isset($crit->param[0][0])
1889
+        ? calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent)
1890
+        : "''";
1891
+    $_liste_sens_defaut = isset($crit->param[1][0])
1892
+        ? calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent)
1893
+        : '1';
1894
+    $_variable = isset($crit->param[2][0])
1895
+        ? calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent)
1896
+        : "'$idb'";
1897
+
1898
+    $_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):'')";
1899
+
1900
+    $_sens_defaut = "(is_array(\$s=$_liste_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)";
1901
+    $_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)";
1902
+
1903
+    $boucle->modificateur['tri_champ'] = $_tri;
1904
+    $boucle->modificateur['tri_sens'] = $_sens;
1905
+    $boucle->modificateur['tri_liste_sens_defaut'] = $_liste_sens_defaut;
1906
+    $boucle->modificateur['tri_nom'] = $_variable;
1907
+    // faut il inserer un test sur l'existence de $tri parmi les champs de la table ?
1908
+    // evite des erreurs sql, mais peut empecher des tri sur jointure ...
1909
+    $boucle->hash .= "
1910 1910
 	\$senstri = '';
1911 1911
 	\$tri = $_tri;
1912 1912
 	if (\$tri){
@@ -1914,8 +1914,8 @@  discard block
 block discarded – undo
1914 1914
 		\$senstri = (\$senstri<0)?' DESC':'';
1915 1915
 	};
1916 1916
 	";
1917
-	$boucle->select[] = '".tri_champ_select($tri)."';
1918
-	$boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)";
1917
+    $boucle->select[] = '".tri_champ_select($tri)."';
1918
+    $boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)";
1919 1919
 }
1920 1920
 
1921 1921
 # criteres de comparaison
@@ -1932,21 +1932,21 @@  discard block
 block discarded – undo
1932 1932
  * @return void|array
1933 1933
  **/
1934 1934
 function calculer_critere_DEFAUT_dist($idb, &$boucles, $crit) {
1935
-	// double cas particulier {0,1} et {1/2} repere a l'analyse lexicale
1936
-	if ($crit->op == ',' || $crit->op == '/') {
1937
-		calculer_critere_parties($idb, $boucles, $crit);
1938
-		return;
1939
-	}
1940
-
1941
-	$r = calculer_critere_infixe($idb, $boucles, $crit);
1942
-	if (!$r) {
1943
-		#	// on produit une erreur seulement si le critere n'a pas de '?'
1944
-		#	if (!$crit->cond) {
1945
-		return ['zbug_critere_inconnu', ['critere' => $crit->op]];
1946
-		#	}
1947
-	} else {
1948
-		calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r);
1949
-	}
1935
+    // double cas particulier {0,1} et {1/2} repere a l'analyse lexicale
1936
+    if ($crit->op == ',' || $crit->op == '/') {
1937
+        calculer_critere_parties($idb, $boucles, $crit);
1938
+        return;
1939
+    }
1940
+
1941
+    $r = calculer_critere_infixe($idb, $boucles, $crit);
1942
+    if (!$r) {
1943
+        #	// on produit une erreur seulement si le critere n'a pas de '?'
1944
+        #	if (!$crit->cond) {
1945
+        return ['zbug_critere_inconnu', ['critere' => $crit->op]];
1946
+        #	}
1947
+    } else {
1948
+        calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r);
1949
+    }
1950 1950
 }
1951 1951
 
1952 1952
 
@@ -1966,60 +1966,60 @@  discard block
 block discarded – undo
1966 1966
  * @return void
1967 1967
  **/
1968 1968
 function calculer_critere_DEFAUT_args($idb, &$boucles, $crit, $args) {
1969
-	[$arg, $op, $val, $col, $where_complement] = $args;
1970
-
1971
-	$where = ["'$op'", "'$arg'", $val[0]];
1972
-
1973
-	// inserer la negation (cf !...)
1974
-
1975
-	if ($crit->not) {
1976
-		$where = ["'NOT'", $where];
1977
-	}
1978
-	if ($crit->exclus) {
1979
-		if (!preg_match(',^L\d+[.],', (string) $arg)) {
1980
-			$where = ["'NOT'", $where];
1981
-		} else {
1982
-			// un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1983
-			// c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1984
-			$where = [
1985
-				"'NOT'",
1986
-				[
1987
-					"'IN'",
1988
-					"'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1989
-					["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1990
-				]
1991
-			];
1992
-		}
1993
-	}
1994
-
1995
-	// inserer la condition (cf {lang?})
1996
-	// traiter a part la date, elle est mise d'office par SPIP,
1997
-	if ($crit->cond) {
1998
-		$pred = calculer_argument_precedent($idb, $col, $boucles);
1999
-		if (($col === 'date' || $col === 'date_redac') && $pred === "\$Pile[0]['" . $col . "']") {
2000
-			$pred = "(\$Pile[0]['{$col}_default']?'':$pred)";
2001
-		}
2002
-
2003
-		if ($op === '=' && !$crit->not) {
2004
-			$where = [
2005
-				"'?'",
2006
-				"(is_array($pred))",
2007
-				critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col),
2008
-				$where
2009
-			];
2010
-		}
2011
-		$where = ["'?'", "!is_whereable($pred)", "''", $where];
2012
-		if ($where_complement) {
2013
-			// condition annexe du type "AND (objet='article')"
2014
-			$where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement];
2015
-		}
2016
-	}
2017
-
2018
-	$boucles[$idb]->where[] = $where;
2019
-	if ($where_complement) {
2020
-		// condition annexe du type "AND (objet='article')"
2021
-		$boucles[$idb]->where[] = $where_complement;
2022
-	}
1969
+    [$arg, $op, $val, $col, $where_complement] = $args;
1970
+
1971
+    $where = ["'$op'", "'$arg'", $val[0]];
1972
+
1973
+    // inserer la negation (cf !...)
1974
+
1975
+    if ($crit->not) {
1976
+        $where = ["'NOT'", $where];
1977
+    }
1978
+    if ($crit->exclus) {
1979
+        if (!preg_match(',^L\d+[.],', (string) $arg)) {
1980
+            $where = ["'NOT'", $where];
1981
+        } else {
1982
+            // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1983
+            // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1984
+            $where = [
1985
+                "'NOT'",
1986
+                [
1987
+                    "'IN'",
1988
+                    "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1989
+                    ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1990
+                ]
1991
+            ];
1992
+        }
1993
+    }
1994
+
1995
+    // inserer la condition (cf {lang?})
1996
+    // traiter a part la date, elle est mise d'office par SPIP,
1997
+    if ($crit->cond) {
1998
+        $pred = calculer_argument_precedent($idb, $col, $boucles);
1999
+        if (($col === 'date' || $col === 'date_redac') && $pred === "\$Pile[0]['" . $col . "']") {
2000
+            $pred = "(\$Pile[0]['{$col}_default']?'':$pred)";
2001
+        }
2002
+
2003
+        if ($op === '=' && !$crit->not) {
2004
+            $where = [
2005
+                "'?'",
2006
+                "(is_array($pred))",
2007
+                critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col),
2008
+                $where
2009
+            ];
2010
+        }
2011
+        $where = ["'?'", "!is_whereable($pred)", "''", $where];
2012
+        if ($where_complement) {
2013
+            // condition annexe du type "AND (objet='article')"
2014
+            $where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement];
2015
+        }
2016
+    }
2017
+
2018
+    $boucles[$idb]->where[] = $where;
2019
+    if ($where_complement) {
2020
+        // condition annexe du type "AND (objet='article')"
2021
+        $boucles[$idb]->where[] = $where_complement;
2022
+    }
2023 2023
 }
2024 2024
 
2025 2025
 
@@ -2060,160 +2060,160 @@  discard block
 block discarded – undo
2060 2060
  **/
2061 2061
 function calculer_critere_infixe($idb, &$boucles, $crit) {
2062 2062
 
2063
-	$boucle = &$boucles[$idb];
2064
-	$type = $boucle->type_requete;
2065
-	$table = $boucle->id_table;
2066
-	$desc = $boucle->show;
2067
-	$col_vraie = null;
2068
-
2069
-	[$fct, $col, $op, $val, $args_sql] =
2070
-		calculer_critere_infixe_ops($idb, $boucles, $crit);
2071
-
2072
-	$col_alias = $col;
2073
-	$where_complement = false;
2074
-
2075
-	// Cas particulier : id_enfant => utiliser la colonne id_objet
2076
-	if ($col == 'id_enfant') {
2077
-		$col = $boucle->primary;
2078
-	}
2079
-
2080
-	// Cas particulier : id_parent => verifier les exceptions de tables
2081
-	if (
2082
-		in_array($col, ['id_parent', 'id_secteur'])
2083
-		&& isset($GLOBALS['exceptions_des_tables'][$table][$col]) || isset($GLOBALS['exceptions_des_tables'][$table][$col]) && is_string($GLOBALS['exceptions_des_tables'][$table][$col])
2084
-	) {
2085
-		$col = $GLOBALS['exceptions_des_tables'][$table][$col];
2086
-	} // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums)
2087
-	else {
2088
-		if ($col == 'id_secteur' && ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) {
2089
-			$table = $critere_secteur($idb, $boucles, $val, $crit);
2090
-		}
2091
-
2092
-		// cas id_article=xx qui se mappe en id_objet=xx AND objet=article
2093
-		// sauf si exception declaree : sauter cette etape
2094
-		else {
2095
-			if (
2096
-				!isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col])
2097
-				&& !isset($GLOBALS['exceptions_des_jointures'][$col])
2098
-				&& count(trouver_champs_decomposes($col, $desc)) > 1
2099
-			) {
2100
-				$e = decompose_champ_id_objet($col);
2101
-				$col = array_shift($e);
2102
-				$where_complement = primary_doublee($e, $table);
2103
-			} // Cas particulier : expressions de date
2104
-			else {
2105
-				if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) {
2106
-					[$col, $col_vraie] = $c;
2107
-					$table = '';
2108
-				} // table explicitée {mots.titre}
2109
-				else {
2110
-					if (preg_match('/^(.*)\.(.*)$/', (string) $col, $r)) {
2111
-						[, $table, $col] = $r;
2112
-						$col_alias = $col;
2113
-
2114
-						$trouver_table = charger_fonction('trouver_table', 'base');
2115
-						if (
2116
-							($desc = $trouver_table($table, $boucle->sql_serveur))
2117
-							&& isset($desc['field'][$col])
2118
-							&& ($cle = array_search($desc['table'], $boucle->from))
2119
-						) {
2120
-							$table = $cle;
2121
-						} else {
2122
-							$table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond || $op != '='));
2123
-						}
2124
-						#$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true);
2125
-						if (!$table) {
2126
-							return '';
2127
-						}
2128
-					}
2129
-					// si le champ n'est pas trouvé dans la table,
2130
-					// on cherche si une jointure peut l'obtenir
2131
-					elseif (@!array_key_exists($col, $desc['field'])) {
2132
-						// Champ joker * des iterateurs DATA qui accepte tout
2133
-						if (@array_key_exists('*', $desc['field'])) {
2134
-							$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
2135
-						}
2136
-						else {
2137
-							$r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table);
2138
-							if (!$r) {
2139
-								return '';
2140
-							}
2141
-							[$col, $col_alias, $table, $where_complement, $desc] = $r;
2142
-						}
2143
-					}
2144
-				}
2145
-			}
2146
-		}
2147
-	}
2148
-
2149
-	$col_vraie = ($col_vraie ?: $col);
2150
-	// Dans tous les cas,
2151
-	// virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL)
2152
-	// et passer dans sql_quote avec le type si connu
2153
-	// et int sinon si la valeur est numerique
2154
-	// sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon)
2155
-	// Ne pas utiliser intval, PHP tronquant les Bigint de SQL
2156
-	if ($op == '=' || in_array($op, $GLOBALS['table_criteres_infixes'])) {
2157
-		$type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL');
2158
-		// defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon
2159
-		// prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut
2160
-		if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", (string) $val[0], $r)) {
2161
-			$val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"';
2162
-		}
2163
-		// sinon expliciter les
2164
-		// sql_quote(truc) en sql_quote(truc,'',type)
2165
-		// sql_quote(truc,serveur) en sql_quote(truc,serveur,type)
2166
-		// sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type)
2167
-		// sans toucher aux
2168
-		// sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE')
2169
-		// sql_quote(truc,'','varchar')
2170
-		elseif (
2171
-			preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', (string) $val[0], $r)
2172
-			&& (!isset($r[3]) || !$r[3] || !trim($r[3], ", '"))
2173
-		) {
2174
-			$r = $r[1]
2175
-				. ((isset($r[2]) && $r[2]) ? $r[2] : ",''")
2176
-				. ",'" . addslashes((string) $type_cast_quote) . "'";
2177
-			$val[0] = "sql_quote($r)";
2178
-		}
2179
-		elseif (
2180
-			str_contains((string) $val[0], '@@defaultcast@@')
2181
-			&& preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", (string) $val[0], $r)
2182
-		) {
2183
-			$val[0] = substr((string) $val[0], 0, -strlen($r[0])) . "'" . addslashes((string) $type_cast_quote) . "')";
2184
-		}
2185
-	}
2186
-
2187
-	if (
2188
-		str_contains((string) $val[0], '@@defaultcast@@')
2189
-		&& preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", (string) $val[0], $r)
2190
-	) {
2191
-		$val[0] = substr((string) $val[0], 0, -strlen($r[0])) . "'char')";
2192
-	}
2193
-
2194
-	// Indicateur pour permettre aux fonctionx boucle_X de modifier
2195
-	// leurs requetes par defaut, notamment le champ statut
2196
-	// Ne pas confondre champs de la table principale et des jointures
2197
-	if ($table === $boucle->id_table) {
2198
-		$boucles[$idb]->modificateur['criteres'][$col_vraie] = true;
2199
-		if ($col_alias != $col_vraie) {
2200
-			$boucles[$idb]->modificateur['criteres'][$col_alias] = true;
2201
-		}
2202
-	}
2203
-
2204
-	// inserer le nom de la table SQL devant le nom du champ
2205
-	if ($table) {
2206
-		$arg = $col[0] == '`' ? "$table." . substr((string) $col, 1, -1) : "$table.$col";
2207
-	} else {
2208
-		$arg = $col;
2209
-	}
2210
-
2211
-	// inserer la fonction SQL
2212
-	if ($fct) {
2213
-		$arg = "$fct($arg$args_sql)";
2214
-	}
2215
-
2216
-	return [$arg, $op, $val, $col_alias, $where_complement];
2063
+    $boucle = &$boucles[$idb];
2064
+    $type = $boucle->type_requete;
2065
+    $table = $boucle->id_table;
2066
+    $desc = $boucle->show;
2067
+    $col_vraie = null;
2068
+
2069
+    [$fct, $col, $op, $val, $args_sql] =
2070
+        calculer_critere_infixe_ops($idb, $boucles, $crit);
2071
+
2072
+    $col_alias = $col;
2073
+    $where_complement = false;
2074
+
2075
+    // Cas particulier : id_enfant => utiliser la colonne id_objet
2076
+    if ($col == 'id_enfant') {
2077
+        $col = $boucle->primary;
2078
+    }
2079
+
2080
+    // Cas particulier : id_parent => verifier les exceptions de tables
2081
+    if (
2082
+        in_array($col, ['id_parent', 'id_secteur'])
2083
+        && isset($GLOBALS['exceptions_des_tables'][$table][$col]) || isset($GLOBALS['exceptions_des_tables'][$table][$col]) && is_string($GLOBALS['exceptions_des_tables'][$table][$col])
2084
+    ) {
2085
+        $col = $GLOBALS['exceptions_des_tables'][$table][$col];
2086
+    } // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums)
2087
+    else {
2088
+        if ($col == 'id_secteur' && ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) {
2089
+            $table = $critere_secteur($idb, $boucles, $val, $crit);
2090
+        }
2091
+
2092
+        // cas id_article=xx qui se mappe en id_objet=xx AND objet=article
2093
+        // sauf si exception declaree : sauter cette etape
2094
+        else {
2095
+            if (
2096
+                !isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col])
2097
+                && !isset($GLOBALS['exceptions_des_jointures'][$col])
2098
+                && count(trouver_champs_decomposes($col, $desc)) > 1
2099
+            ) {
2100
+                $e = decompose_champ_id_objet($col);
2101
+                $col = array_shift($e);
2102
+                $where_complement = primary_doublee($e, $table);
2103
+            } // Cas particulier : expressions de date
2104
+            else {
2105
+                if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) {
2106
+                    [$col, $col_vraie] = $c;
2107
+                    $table = '';
2108
+                } // table explicitée {mots.titre}
2109
+                else {
2110
+                    if (preg_match('/^(.*)\.(.*)$/', (string) $col, $r)) {
2111
+                        [, $table, $col] = $r;
2112
+                        $col_alias = $col;
2113
+
2114
+                        $trouver_table = charger_fonction('trouver_table', 'base');
2115
+                        if (
2116
+                            ($desc = $trouver_table($table, $boucle->sql_serveur))
2117
+                            && isset($desc['field'][$col])
2118
+                            && ($cle = array_search($desc['table'], $boucle->from))
2119
+                        ) {
2120
+                            $table = $cle;
2121
+                        } else {
2122
+                            $table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond || $op != '='));
2123
+                        }
2124
+                        #$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true);
2125
+                        if (!$table) {
2126
+                            return '';
2127
+                        }
2128
+                    }
2129
+                    // si le champ n'est pas trouvé dans la table,
2130
+                    // on cherche si une jointure peut l'obtenir
2131
+                    elseif (@!array_key_exists($col, $desc['field'])) {
2132
+                        // Champ joker * des iterateurs DATA qui accepte tout
2133
+                        if (@array_key_exists('*', $desc['field'])) {
2134
+                            $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
2135
+                        }
2136
+                        else {
2137
+                            $r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table);
2138
+                            if (!$r) {
2139
+                                return '';
2140
+                            }
2141
+                            [$col, $col_alias, $table, $where_complement, $desc] = $r;
2142
+                        }
2143
+                    }
2144
+                }
2145
+            }
2146
+        }
2147
+    }
2148
+
2149
+    $col_vraie = ($col_vraie ?: $col);
2150
+    // Dans tous les cas,
2151
+    // virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL)
2152
+    // et passer dans sql_quote avec le type si connu
2153
+    // et int sinon si la valeur est numerique
2154
+    // sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon)
2155
+    // Ne pas utiliser intval, PHP tronquant les Bigint de SQL
2156
+    if ($op == '=' || in_array($op, $GLOBALS['table_criteres_infixes'])) {
2157
+        $type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL');
2158
+        // defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon
2159
+        // prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut
2160
+        if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", (string) $val[0], $r)) {
2161
+            $val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"';
2162
+        }
2163
+        // sinon expliciter les
2164
+        // sql_quote(truc) en sql_quote(truc,'',type)
2165
+        // sql_quote(truc,serveur) en sql_quote(truc,serveur,type)
2166
+        // sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type)
2167
+        // sans toucher aux
2168
+        // sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE')
2169
+        // sql_quote(truc,'','varchar')
2170
+        elseif (
2171
+            preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', (string) $val[0], $r)
2172
+            && (!isset($r[3]) || !$r[3] || !trim($r[3], ", '"))
2173
+        ) {
2174
+            $r = $r[1]
2175
+                . ((isset($r[2]) && $r[2]) ? $r[2] : ",''")
2176
+                . ",'" . addslashes((string) $type_cast_quote) . "'";
2177
+            $val[0] = "sql_quote($r)";
2178
+        }
2179
+        elseif (
2180
+            str_contains((string) $val[0], '@@defaultcast@@')
2181
+            && preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", (string) $val[0], $r)
2182
+        ) {
2183
+            $val[0] = substr((string) $val[0], 0, -strlen($r[0])) . "'" . addslashes((string) $type_cast_quote) . "')";
2184
+        }
2185
+    }
2186
+
2187
+    if (
2188
+        str_contains((string) $val[0], '@@defaultcast@@')
2189
+        && preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", (string) $val[0], $r)
2190
+    ) {
2191
+        $val[0] = substr((string) $val[0], 0, -strlen($r[0])) . "'char')";
2192
+    }
2193
+
2194
+    // Indicateur pour permettre aux fonctionx boucle_X de modifier
2195
+    // leurs requetes par defaut, notamment le champ statut
2196
+    // Ne pas confondre champs de la table principale et des jointures
2197
+    if ($table === $boucle->id_table) {
2198
+        $boucles[$idb]->modificateur['criteres'][$col_vraie] = true;
2199
+        if ($col_alias != $col_vraie) {
2200
+            $boucles[$idb]->modificateur['criteres'][$col_alias] = true;
2201
+        }
2202
+    }
2203
+
2204
+    // inserer le nom de la table SQL devant le nom du champ
2205
+    if ($table) {
2206
+        $arg = $col[0] == '`' ? "$table." . substr((string) $col, 1, -1) : "$table.$col";
2207
+    } else {
2208
+        $arg = $col;
2209
+    }
2210
+
2211
+    // inserer la fonction SQL
2212
+    if ($fct) {
2213
+        $arg = "$fct($arg$args_sql)";
2214
+    }
2215
+
2216
+    return [$arg, $op, $val, $col_alias, $where_complement];
2217 2217
 }
2218 2218
 
2219 2219
 
@@ -2242,75 +2242,75 @@  discard block
 block discarded – undo
2242 2242
  **/
2243 2243
 function calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table) {
2244 2244
 
2245
-	$where = '';
2246
-
2247
-	$calculer_critere_externe = 'calculer_critere_externe_init';
2248
-	// gestion par les plugins des jointures tordues
2249
-	// pas automatiques mais necessaires
2250
-	$table_sql = table_objet_sql($table);
2251
-	if (
2252
-		isset($GLOBALS['exceptions_des_jointures'][$table_sql])
2253
-		&& is_array($GLOBALS['exceptions_des_jointures'][$table_sql])
2254
-		&& (
2255
-			isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col])
2256
-			|| isset($GLOBALS['exceptions_des_jointures'][$table_sql][''])
2257
-		)
2258
-	) {
2259
-		$t = $GLOBALS['exceptions_des_jointures'][$table_sql];
2260
-		$index = $t[$col] ?? $t[''] ?? [];
2261
-
2262
-		if ((is_countable($index) ? count($index) : 0) == 3) {
2263
-			[$t, $col, $calculer_critere_externe] = $index;
2264
-		} elseif ((is_countable($index) ? count($index) : 0) == 2) {
2265
-			[$t, $col] = $t[$col];
2266
-		} elseif ((is_countable($index) ? count($index) : 0) == 1) {
2267
-			[$calculer_critere_externe] = $index;
2268
-			$t = $table;
2269
-		} else {
2270
-			$t = '';
2271
-		} // jointure non declaree. La trouver.
2272
-	} elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) {
2273
-		[$t, $col] = $GLOBALS['exceptions_des_jointures'][$col];
2274
-	} else {
2275
-		$t = '';
2276
-	} // jointure non declaree. La trouver.
2277
-
2278
-	// ici on construit le from pour fournir $col en piochant dans les jointures
2279
-
2280
-	// si des jointures explicites sont fournies, on cherche d'abord dans celles ci
2281
-	// permet de forcer une table de lien quand il y a ambiguite
2282
-	// <BOUCLE_(DOCUMENTS documents_liens){id_mot}>
2283
-	// alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}>
2284
-	$table = '';
2285
-	if ($boucle->jointures_explicites) {
2286
-		$jointures_explicites = explode(' ', $boucle->jointures_explicites);
2287
-		$table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond || $op != '='), $t);
2288
-	}
2289
-
2290
-	// et sinon on cherche parmi toutes les jointures declarees
2291
-	if (!$table) {
2292
-		$table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond || $op != '='), $t);
2293
-	}
2294
-
2295
-	if (!$table) {
2296
-		return '';
2297
-	}
2298
-
2299
-	// il ne reste plus qu'a trouver le champ dans les from
2300
-	[$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle);
2301
-
2302
-	if ((is_countable($cle) ? count($cle) : 0) > 1 || reset($cle) !== $col) {
2303
-		$col_alias = $col; // id_article devient juste le nom d'origine
2304
-		if ((is_countable($cle) ? count($cle) : 0) > 1 && reset($cle) == 'id_objet') {
2305
-			$e = decompose_champ_id_objet($col);
2306
-			$col = array_shift($e);
2307
-			$where = primary_doublee($e, $table);
2308
-		} else {
2309
-			$col = reset($cle);
2310
-		}
2311
-	}
2312
-
2313
-	return [$col, $col_alias, $table, $where, $desc];
2245
+    $where = '';
2246
+
2247
+    $calculer_critere_externe = 'calculer_critere_externe_init';
2248
+    // gestion par les plugins des jointures tordues
2249
+    // pas automatiques mais necessaires
2250
+    $table_sql = table_objet_sql($table);
2251
+    if (
2252
+        isset($GLOBALS['exceptions_des_jointures'][$table_sql])
2253
+        && is_array($GLOBALS['exceptions_des_jointures'][$table_sql])
2254
+        && (
2255
+            isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col])
2256
+            || isset($GLOBALS['exceptions_des_jointures'][$table_sql][''])
2257
+        )
2258
+    ) {
2259
+        $t = $GLOBALS['exceptions_des_jointures'][$table_sql];
2260
+        $index = $t[$col] ?? $t[''] ?? [];
2261
+
2262
+        if ((is_countable($index) ? count($index) : 0) == 3) {
2263
+            [$t, $col, $calculer_critere_externe] = $index;
2264
+        } elseif ((is_countable($index) ? count($index) : 0) == 2) {
2265
+            [$t, $col] = $t[$col];
2266
+        } elseif ((is_countable($index) ? count($index) : 0) == 1) {
2267
+            [$calculer_critere_externe] = $index;
2268
+            $t = $table;
2269
+        } else {
2270
+            $t = '';
2271
+        } // jointure non declaree. La trouver.
2272
+    } elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) {
2273
+        [$t, $col] = $GLOBALS['exceptions_des_jointures'][$col];
2274
+    } else {
2275
+        $t = '';
2276
+    } // jointure non declaree. La trouver.
2277
+
2278
+    // ici on construit le from pour fournir $col en piochant dans les jointures
2279
+
2280
+    // si des jointures explicites sont fournies, on cherche d'abord dans celles ci
2281
+    // permet de forcer une table de lien quand il y a ambiguite
2282
+    // <BOUCLE_(DOCUMENTS documents_liens){id_mot}>
2283
+    // alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}>
2284
+    $table = '';
2285
+    if ($boucle->jointures_explicites) {
2286
+        $jointures_explicites = explode(' ', $boucle->jointures_explicites);
2287
+        $table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond || $op != '='), $t);
2288
+    }
2289
+
2290
+    // et sinon on cherche parmi toutes les jointures declarees
2291
+    if (!$table) {
2292
+        $table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond || $op != '='), $t);
2293
+    }
2294
+
2295
+    if (!$table) {
2296
+        return '';
2297
+    }
2298
+
2299
+    // il ne reste plus qu'a trouver le champ dans les from
2300
+    [$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle);
2301
+
2302
+    if ((is_countable($cle) ? count($cle) : 0) > 1 || reset($cle) !== $col) {
2303
+        $col_alias = $col; // id_article devient juste le nom d'origine
2304
+        if ((is_countable($cle) ? count($cle) : 0) > 1 && reset($cle) == 'id_objet') {
2305
+            $e = decompose_champ_id_objet($col);
2306
+            $col = array_shift($e);
2307
+            $where = primary_doublee($e, $table);
2308
+        } else {
2309
+            $col = reset($cle);
2310
+        }
2311
+    }
2312
+
2313
+    return [$col, $col_alias, $table, $where, $desc];
2314 2314
 }
2315 2315
 
2316 2316
 
@@ -2331,10 +2331,10 @@  discard block
 block discarded – undo
2331 2331
  *     - valeur
2332 2332
  **/
2333 2333
 function primary_doublee($decompose, $table) {
2334
-	$e1 = reset($decompose);
2335
-	$e2 = "sql_quote('" . end($decompose) . "')";
2334
+    $e1 = reset($decompose);
2335
+    $e2 = "sql_quote('" . end($decompose) . "')";
2336 2336
 
2337
-	return ["'='", "'$table." . $e1 . "'", $e2];
2337
+    return ["'='", "'$table." . $e1 . "'", $e2];
2338 2338
 }
2339 2339
 
2340 2340
 /**
@@ -2365,56 +2365,56 @@  discard block
 block discarded – undo
2365 2365
  *     Vide sinon.
2366 2366
  */
2367 2367
 function calculer_critere_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) {
2368
-	// si on demande un truc du genre spip_mots
2369
-	// avec aussi spip_mots_liens dans les jointures dispo
2370
-	// et qu'on est la
2371
-	// il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots
2372
-	if (
2373
-		$checkarrivee
2374
-		&& is_string($checkarrivee)
2375
-		&& ($a = table_objet($checkarrivee))
2376
-		&& in_array($a . '_liens', $joints)
2377
-		&& ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee))
2378
-	) {
2379
-		return $res;
2380
-	}
2381
-	foreach ($joints as $joint) {
2382
-		if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) {
2383
-			// alias de table dans le from
2384
-			$t = array_search($arrivee[0], $boucle->from);
2385
-			// recuperer la cle id_xx eventuellement decomposee en (id_objet,objet)
2386
-			$cols = $arrivee[2];
2387
-			// mais on ignore la 3eme cle si presente qui correspond alors au point de depart
2388
-			if ((is_countable($cols) ? count($cols) : 0) > 2) {
2389
-				array_pop($cols);
2390
-			}
2391
-			if ($t) {
2392
-				// la table est déjà dans le FROM, on vérifie si le champ est utilisé.
2393
-				$joindre = false;
2394
-				foreach ($cols as $col) {
2395
-					$c = '/\b' . $t . ".$col" . '\b/';
2396
-					if (trouver_champ($c, $boucle->where)) {
2397
-						$joindre = true;
2398
-					} else {
2399
-						// mais ca peut etre dans le FIELD pour le Having
2400
-						$c = "/FIELD.$t" . ".$col,/";
2401
-						if (trouver_champ($c, $boucle->select)) {
2402
-							$joindre = true;
2403
-						}
2404
-					}
2405
-				}
2406
-				if (!$joindre) {
2407
-					return $t;
2408
-				}
2409
-			}
2410
-			array_pop($arrivee);
2411
-			if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) {
2412
-				return $res;
2413
-			}
2414
-		}
2415
-	}
2416
-
2417
-	return '';
2368
+    // si on demande un truc du genre spip_mots
2369
+    // avec aussi spip_mots_liens dans les jointures dispo
2370
+    // et qu'on est la
2371
+    // il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots
2372
+    if (
2373
+        $checkarrivee
2374
+        && is_string($checkarrivee)
2375
+        && ($a = table_objet($checkarrivee))
2376
+        && in_array($a . '_liens', $joints)
2377
+        && ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee))
2378
+    ) {
2379
+        return $res;
2380
+    }
2381
+    foreach ($joints as $joint) {
2382
+        if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) {
2383
+            // alias de table dans le from
2384
+            $t = array_search($arrivee[0], $boucle->from);
2385
+            // recuperer la cle id_xx eventuellement decomposee en (id_objet,objet)
2386
+            $cols = $arrivee[2];
2387
+            // mais on ignore la 3eme cle si presente qui correspond alors au point de depart
2388
+            if ((is_countable($cols) ? count($cols) : 0) > 2) {
2389
+                array_pop($cols);
2390
+            }
2391
+            if ($t) {
2392
+                // la table est déjà dans le FROM, on vérifie si le champ est utilisé.
2393
+                $joindre = false;
2394
+                foreach ($cols as $col) {
2395
+                    $c = '/\b' . $t . ".$col" . '\b/';
2396
+                    if (trouver_champ($c, $boucle->where)) {
2397
+                        $joindre = true;
2398
+                    } else {
2399
+                        // mais ca peut etre dans le FIELD pour le Having
2400
+                        $c = "/FIELD.$t" . ".$col,/";
2401
+                        if (trouver_champ($c, $boucle->select)) {
2402
+                            $joindre = true;
2403
+                        }
2404
+                    }
2405
+                }
2406
+                if (!$joindre) {
2407
+                    return $t;
2408
+                }
2409
+            }
2410
+            array_pop($arrivee);
2411
+            if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) {
2412
+                return $res;
2413
+            }
2414
+        }
2415
+    }
2416
+
2417
+    return '';
2418 2418
 }
2419 2419
 
2420 2420
 /**
@@ -2440,35 +2440,35 @@  discard block
 block discarded – undo
2440 2440
  *     Alias de la table de jointure (Lx)
2441 2441
  */
2442 2442
 function calculer_lien_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) {
2443
-	$primary_arrivee = id_table_objet($checkarrivee);
2444
-
2445
-	// [FIXME] $checkarrivee peut-il arriver avec false ????
2446
-	$intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens');
2447
-	$arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee);
2448
-
2449
-	if (!$intermediaire || !$arrivee) {
2450
-		return '';
2451
-	}
2452
-	array_pop($intermediaire); // enlever la cle en 3eme argument
2453
-	array_pop($arrivee); // enlever la cle en 3eme argument
2454
-
2455
-	$res = fabrique_jointures(
2456
-		$boucle,
2457
-		[
2458
-			[
2459
-				$boucle->id_table,
2460
-				$intermediaire,
2461
-				[id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']]
2462
-			],
2463
-			[reset($intermediaire), $arrivee, $primary_arrivee]
2464
-		],
2465
-		$cond,
2466
-		$desc,
2467
-		$boucle->id_table,
2468
-		[$col]
2469
-	);
2470
-
2471
-	return $res;
2443
+    $primary_arrivee = id_table_objet($checkarrivee);
2444
+
2445
+    // [FIXME] $checkarrivee peut-il arriver avec false ????
2446
+    $intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens');
2447
+    $arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee);
2448
+
2449
+    if (!$intermediaire || !$arrivee) {
2450
+        return '';
2451
+    }
2452
+    array_pop($intermediaire); // enlever la cle en 3eme argument
2453
+    array_pop($arrivee); // enlever la cle en 3eme argument
2454
+
2455
+    $res = fabrique_jointures(
2456
+        $boucle,
2457
+        [
2458
+            [
2459
+                $boucle->id_table,
2460
+                $intermediaire,
2461
+                [id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']]
2462
+            ],
2463
+            [reset($intermediaire), $arrivee, $primary_arrivee]
2464
+        ],
2465
+        $cond,
2466
+        $desc,
2467
+        $boucle->id_table,
2468
+        [$col]
2469
+    );
2470
+
2471
+    return $res;
2472 2472
 }
2473 2473
 
2474 2474
 
@@ -2485,17 +2485,17 @@  discard block
 block discarded – undo
2485 2485
  *     false sinon.
2486 2486
  **/
2487 2487
 function trouver_champ($champ, $where) {
2488
-	if (!is_array($where)) {
2489
-		return preg_match($champ, $where);
2490
-	} else {
2491
-		foreach ($where as $clause) {
2492
-			if (trouver_champ($champ, $clause)) {
2493
-				return true;
2494
-			}
2495
-		}
2496
-
2497
-		return false;
2498
-	}
2488
+    if (!is_array($where)) {
2489
+        return preg_match($champ, $where);
2490
+    } else {
2491
+        foreach ($where as $clause) {
2492
+            if (trouver_champ($champ, $clause)) {
2493
+                return true;
2494
+            }
2495
+        }
2496
+
2497
+        return false;
2498
+    }
2499 2499
 }
2500 2500
 
2501 2501
 
@@ -2521,128 +2521,128 @@  discard block
 block discarded – undo
2521 2521
  *     - string $args_sql  Suite des arguments du critère. ?
2522 2522
  **/
2523 2523
 function calculer_critere_infixe_ops($idb, &$boucles, $crit) {
2524
-	// cas d'une valeur comparee a elle-meme ou son referent
2525
-	if ((is_countable($crit->param) ? count($crit->param) : 0) == 0) {
2526
-		$op = '=';
2527
-		$col = $val = $crit->op;
2528
-		if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2529
-			$val = $r[2];
2530
-		}
2531
-		// Cas special {lang} : aller chercher $GLOBALS['spip_lang']
2532
-		if ($val == 'lang') {
2533
-			$val = [kwote('$GLOBALS[\'spip_lang\']')];
2534
-		} else {
2535
-			$defaut = null;
2536
-			if ($val == 'id_parent') {
2537
-				// Si id_parent, comparer l'id_parent avec l'id_objet
2538
-				// de la boucle superieure.... faudrait verifier qu'il existe
2539
-				// pour eviter l'erreur SQL
2540
-				$val = $boucles[$idb]->primary;
2541
-				// mais si pas de boucle superieure, prendre id_parent dans l'env
2542
-				$defaut = "(\$Pile[0]['id_parent'] ?? null)";
2543
-			} elseif ($val == 'id_enfant') {
2544
-				// Si id_enfant, comparer l'id_objet avec l'id_parent
2545
-				// de la boucle superieure
2546
-				$val = 'id_parent';
2547
-			} elseif ($crit->cond && ($col == 'date' || $col == 'date_redac')) {
2548
-				// un critere conditionnel sur date est traite a part
2549
-				// car la date est mise d'office par SPIP,
2550
-				$defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])";
2551
-			}
2552
-
2553
-			$val = calculer_argument_precedent($idb, $val, $boucles, $defaut);
2554
-			$val = [kwote($val)];
2555
-		}
2556
-	} else {
2557
-		// comparaison explicite
2558
-		// le phraseur impose que le premier param soit du texte
2559
-		$params = $crit->param;
2560
-		$op = $crit->op;
2561
-		if ($op == '==') {
2562
-			$op = 'REGEXP';
2563
-		}
2564
-		$col = array_shift($params);
2565
-		$col = $col[0]->texte;
2566
-
2567
-		$val = [];
2568
-		$parent = $boucles[$idb]->id_parent;
2569
-
2570
-		// Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
2571
-		// celui ne sachant pas ce qu'est un critere infixe
2572
-		// et a fortiori son 2e operande qu'entoure " ou '
2573
-		if (
2574
-			(is_countable($params) ? count($params) : 0) == 1
2575
-			&& (is_countable($params[0]) ? count($params[0]) : 0) == 3
2576
-			&& $params[0][0]->type == 'texte'
2577
-			&& $params[0][2]->type == 'texte'
2578
-			&& ($p = $params[0][0]->texte) == $params[0][2]->texte
2579
-			&& ($p == "'" || $p == '"')
2580
-			&& $params[0][1]->type == 'champ'
2581
-		) {
2582
-			$val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p";
2583
-		} else {
2584
-			foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
2585
-				$a = calculer_liste($p, $idb, $boucles, $parent);
2586
-				$val[] = strcasecmp($op, 'IN') == 0
2587
-					? $a
2588
-					// toujours quoter en char ici
2589
-					: kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@');
2590
-			}
2591
-		}
2592
-	}
2593
-
2594
-	$fct = $args_sql = '';
2595
-	// fonction SQL ?
2596
-	// chercher FONCTION(champ) tel que CONCAT(titre,descriptif)
2597
-	if (preg_match('/^(.*)' . SQL_ARGS . '$/', (string) $col, $m)) {
2598
-		$fct = $m[1];
2599
-		preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a);
2600
-		$col = $a[1];
2601
-		if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) {
2602
-			$col = $m[1];
2603
-			$args_sql = $m[2];
2604
-		}
2605
-		$args_sql .= $a[2];
2606
-	}
2607
-
2608
-	return [$fct, $col, $op, $val, $args_sql];
2524
+    // cas d'une valeur comparee a elle-meme ou son referent
2525
+    if ((is_countable($crit->param) ? count($crit->param) : 0) == 0) {
2526
+        $op = '=';
2527
+        $col = $val = $crit->op;
2528
+        if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2529
+            $val = $r[2];
2530
+        }
2531
+        // Cas special {lang} : aller chercher $GLOBALS['spip_lang']
2532
+        if ($val == 'lang') {
2533
+            $val = [kwote('$GLOBALS[\'spip_lang\']')];
2534
+        } else {
2535
+            $defaut = null;
2536
+            if ($val == 'id_parent') {
2537
+                // Si id_parent, comparer l'id_parent avec l'id_objet
2538
+                // de la boucle superieure.... faudrait verifier qu'il existe
2539
+                // pour eviter l'erreur SQL
2540
+                $val = $boucles[$idb]->primary;
2541
+                // mais si pas de boucle superieure, prendre id_parent dans l'env
2542
+                $defaut = "(\$Pile[0]['id_parent'] ?? null)";
2543
+            } elseif ($val == 'id_enfant') {
2544
+                // Si id_enfant, comparer l'id_objet avec l'id_parent
2545
+                // de la boucle superieure
2546
+                $val = 'id_parent';
2547
+            } elseif ($crit->cond && ($col == 'date' || $col == 'date_redac')) {
2548
+                // un critere conditionnel sur date est traite a part
2549
+                // car la date est mise d'office par SPIP,
2550
+                $defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])";
2551
+            }
2552
+
2553
+            $val = calculer_argument_precedent($idb, $val, $boucles, $defaut);
2554
+            $val = [kwote($val)];
2555
+        }
2556
+    } else {
2557
+        // comparaison explicite
2558
+        // le phraseur impose que le premier param soit du texte
2559
+        $params = $crit->param;
2560
+        $op = $crit->op;
2561
+        if ($op == '==') {
2562
+            $op = 'REGEXP';
2563
+        }
2564
+        $col = array_shift($params);
2565
+        $col = $col[0]->texte;
2566
+
2567
+        $val = [];
2568
+        $parent = $boucles[$idb]->id_parent;
2569
+
2570
+        // Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
2571
+        // celui ne sachant pas ce qu'est un critere infixe
2572
+        // et a fortiori son 2e operande qu'entoure " ou '
2573
+        if (
2574
+            (is_countable($params) ? count($params) : 0) == 1
2575
+            && (is_countable($params[0]) ? count($params[0]) : 0) == 3
2576
+            && $params[0][0]->type == 'texte'
2577
+            && $params[0][2]->type == 'texte'
2578
+            && ($p = $params[0][0]->texte) == $params[0][2]->texte
2579
+            && ($p == "'" || $p == '"')
2580
+            && $params[0][1]->type == 'champ'
2581
+        ) {
2582
+            $val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p";
2583
+        } else {
2584
+            foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
2585
+                $a = calculer_liste($p, $idb, $boucles, $parent);
2586
+                $val[] = strcasecmp($op, 'IN') == 0
2587
+                    ? $a
2588
+                    // toujours quoter en char ici
2589
+                    : kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@');
2590
+            }
2591
+        }
2592
+    }
2593
+
2594
+    $fct = $args_sql = '';
2595
+    // fonction SQL ?
2596
+    // chercher FONCTION(champ) tel que CONCAT(titre,descriptif)
2597
+    if (preg_match('/^(.*)' . SQL_ARGS . '$/', (string) $col, $m)) {
2598
+        $fct = $m[1];
2599
+        preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a);
2600
+        $col = $a[1];
2601
+        if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) {
2602
+            $col = $m[1];
2603
+            $args_sql = $m[2];
2604
+        }
2605
+        $args_sql .= $a[2];
2606
+    }
2607
+
2608
+    return [$fct, $col, $op, $val, $args_sql];
2609 2609
 }
2610 2610
 
2611 2611
 // compatibilite ancienne version
2612 2612
 
2613 2613
 function calculer_vieux_in($params) {
2614
-	$deb = $params[0][0];
2615
-	$k = (is_countable($params) ? count($params) : 0) - 1;
2616
-	$last = $params[$k];
2617
-	$j = (is_countable($last) ? count($last) : 0) - 1;
2618
-	$last = $last[$j];
2619
-	$n = isset($last->texte) ? strlen((string) $last->texte) : 0;
2620
-
2621
-	if (
2622
-		!((isset($deb->texte[0]) && $deb->texte[0] == '(')
2623
-		&& (isset($last->texte[$n - 1]) && $last->texte[$n - 1] == ')'))
2624
-	) {
2625
-		return $params;
2626
-	}
2627
-	$params[0][0]->texte = substr((string) $deb->texte, 1);
2628
-	// attention, on peut avoir k=0,j=0 ==> recalculer
2629
-	$last = $params[$k][$j];
2630
-	$n = strlen((string) $last->texte);
2631
-	$params[$k][$j]->texte = substr((string) $last->texte, 0, $n - 1);
2632
-	$newp = [];
2633
-	foreach ($params as $v) {
2634
-		if ($v[0]->type != 'texte') {
2635
-			$newp[] = $v;
2636
-		} else {
2637
-			foreach (explode(',', (string) $v[0]->texte) as $x) {
2638
-				$t = new Texte();
2639
-				$t->texte = $x;
2640
-				$newp[] = [$t];
2641
-			}
2642
-		}
2643
-	}
2644
-
2645
-	return $newp;
2614
+    $deb = $params[0][0];
2615
+    $k = (is_countable($params) ? count($params) : 0) - 1;
2616
+    $last = $params[$k];
2617
+    $j = (is_countable($last) ? count($last) : 0) - 1;
2618
+    $last = $last[$j];
2619
+    $n = isset($last->texte) ? strlen((string) $last->texte) : 0;
2620
+
2621
+    if (
2622
+        !((isset($deb->texte[0]) && $deb->texte[0] == '(')
2623
+        && (isset($last->texte[$n - 1]) && $last->texte[$n - 1] == ')'))
2624
+    ) {
2625
+        return $params;
2626
+    }
2627
+    $params[0][0]->texte = substr((string) $deb->texte, 1);
2628
+    // attention, on peut avoir k=0,j=0 ==> recalculer
2629
+    $last = $params[$k][$j];
2630
+    $n = strlen((string) $last->texte);
2631
+    $params[$k][$j]->texte = substr((string) $last->texte, 0, $n - 1);
2632
+    $newp = [];
2633
+    foreach ($params as $v) {
2634
+        if ($v[0]->type != 'texte') {
2635
+            $newp[] = $v;
2636
+        } else {
2637
+            foreach (explode(',', (string) $v[0]->texte) as $x) {
2638
+                $t = new Texte();
2639
+                $t->texte = $x;
2640
+                $newp[] = [$t];
2641
+            }
2642
+        }
2643
+    }
2644
+
2645
+    return $newp;
2646 2646
 }
2647 2647
 
2648 2648
 /**
@@ -2661,91 +2661,91 @@  discard block
 block discarded – undo
2661 2661
  *     - nom de la colonne de date (si le calcul n'est pas relatif)
2662 2662
  **/
2663 2663
 function calculer_critere_infixe_date($idb, &$boucles, $col) {
2664
-	if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) {
2665
-		return '';
2666
-	}
2667
-
2668
-	$boucle = $boucles[$idb];
2669
-	$table = $boucle->show;
2670
-
2671
-	// si c'est une colonne de la table, ne rien faire
2672
-	if (isset($table['field'][$col])) {
2673
-		return '';
2674
-	}
2675
-
2676
-	// Le type de critère à prendre en compte
2677
-	$col = $regs[1];
2678
-
2679
-	// Si on trouve un nom de champ date précis, on l'utilise, pas besoin de déclaration dans l'API objet
2680
-	if (isset($regs[3]) && ($suite = $regs[3])) {
2681
-		# Recherche de l'existence du champ date_xxxx,
2682
-		# si oui choisir ce champ, sinon choisir xxxx
2683
-		$date_orig = isset($table['field']["date$suite"]) ? 'date' . $suite : substr($suite, 1);
2684
-
2685
-		$pred = $date_orig;
2686
-	} else { // Sinon il FAUT avoir déclaré le champ date officiel dans l'API objet
2687
-		// Si aucune déclaration trouvée, on quitte
2688
-		if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) {
2689
-			return '';
2690
-		}
2691
-		// Par défaut, on prend le champ date déclaré dans l'API
2692
-		$pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date'];
2693
-
2694
-		// Si c'est pour du relatif
2695
-		if (isset($regs[2]) && ($rel = $regs[2])) {
2696
-			$pred = 'date';
2697
-		}
2698
-	}
2699
-
2700
-	$date_compare = "\"' . normaliser_date(" .
2701
-		calculer_argument_precedent($idb, $pred, $boucles) .
2702
-		") . '\"";
2703
-
2704
-	$col_vraie = $date_orig;
2705
-	$date_orig = $boucle->id_table . '.' . $date_orig;
2706
-
2707
-	switch ($col) {
2708
-		case 'date':
2709
-			$col = $date_orig;
2710
-			break;
2711
-		case 'jour':
2712
-			$col = "DAYOFMONTH($date_orig)";
2713
-			break;
2714
-		case 'mois':
2715
-			$col = "MONTH($date_orig)";
2716
-			break;
2717
-		case 'annee':
2718
-			$col = "YEAR($date_orig)";
2719
-			break;
2720
-		case 'heure':
2721
-			$col = "DATE_FORMAT($date_orig, \\'%H:%i\\')";
2722
-			break;
2723
-		case 'age':
2724
-			$col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig);
2725
-			$col_vraie = '';// comparer a un int (par defaut)
2726
-			break;
2727
-		case 'age_relatif':
2728
-			$col = calculer_param_date($date_compare, $date_orig);
2729
-			$col_vraie = '';// comparer a un int (par defaut)
2730
-			break;
2731
-		case 'jour_relatif':
2732
-			$col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))';
2733
-			$col_vraie = '';// comparer a un int (par defaut)
2734
-			break;
2735
-		case 'mois_relatif':
2736
-			$col = 'MONTH(' . $date_compare . ')-MONTH(' .
2737
-				$date_orig . ')+12*(YEAR(' . $date_compare .
2738
-				')-YEAR(' . $date_orig . '))';
2739
-			$col_vraie = '';// comparer a un int (par defaut)
2740
-			break;
2741
-		case 'annee_relatif':
2742
-			$col = 'YEAR(' . $date_compare . ')-YEAR(' .
2743
-				$date_orig . ')';
2744
-			$col_vraie = '';// comparer a un int (par defaut)
2745
-			break;
2746
-	}
2747
-
2748
-	return [$col, $col_vraie];
2664
+    if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) {
2665
+        return '';
2666
+    }
2667
+
2668
+    $boucle = $boucles[$idb];
2669
+    $table = $boucle->show;
2670
+
2671
+    // si c'est une colonne de la table, ne rien faire
2672
+    if (isset($table['field'][$col])) {
2673
+        return '';
2674
+    }
2675
+
2676
+    // Le type de critère à prendre en compte
2677
+    $col = $regs[1];
2678
+
2679
+    // Si on trouve un nom de champ date précis, on l'utilise, pas besoin de déclaration dans l'API objet
2680
+    if (isset($regs[3]) && ($suite = $regs[3])) {
2681
+        # Recherche de l'existence du champ date_xxxx,
2682
+        # si oui choisir ce champ, sinon choisir xxxx
2683
+        $date_orig = isset($table['field']["date$suite"]) ? 'date' . $suite : substr($suite, 1);
2684
+
2685
+        $pred = $date_orig;
2686
+    } else { // Sinon il FAUT avoir déclaré le champ date officiel dans l'API objet
2687
+        // Si aucune déclaration trouvée, on quitte
2688
+        if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) {
2689
+            return '';
2690
+        }
2691
+        // Par défaut, on prend le champ date déclaré dans l'API
2692
+        $pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date'];
2693
+
2694
+        // Si c'est pour du relatif
2695
+        if (isset($regs[2]) && ($rel = $regs[2])) {
2696
+            $pred = 'date';
2697
+        }
2698
+    }
2699
+
2700
+    $date_compare = "\"' . normaliser_date(" .
2701
+        calculer_argument_precedent($idb, $pred, $boucles) .
2702
+        ") . '\"";
2703
+
2704
+    $col_vraie = $date_orig;
2705
+    $date_orig = $boucle->id_table . '.' . $date_orig;
2706
+
2707
+    switch ($col) {
2708
+        case 'date':
2709
+            $col = $date_orig;
2710
+            break;
2711
+        case 'jour':
2712
+            $col = "DAYOFMONTH($date_orig)";
2713
+            break;
2714
+        case 'mois':
2715
+            $col = "MONTH($date_orig)";
2716
+            break;
2717
+        case 'annee':
2718
+            $col = "YEAR($date_orig)";
2719
+            break;
2720
+        case 'heure':
2721
+            $col = "DATE_FORMAT($date_orig, \\'%H:%i\\')";
2722
+            break;
2723
+        case 'age':
2724
+            $col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig);
2725
+            $col_vraie = '';// comparer a un int (par defaut)
2726
+            break;
2727
+        case 'age_relatif':
2728
+            $col = calculer_param_date($date_compare, $date_orig);
2729
+            $col_vraie = '';// comparer a un int (par defaut)
2730
+            break;
2731
+        case 'jour_relatif':
2732
+            $col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))';
2733
+            $col_vraie = '';// comparer a un int (par defaut)
2734
+            break;
2735
+        case 'mois_relatif':
2736
+            $col = 'MONTH(' . $date_compare . ')-MONTH(' .
2737
+                $date_orig . ')+12*(YEAR(' . $date_compare .
2738
+                ')-YEAR(' . $date_orig . '))';
2739
+            $col_vraie = '';// comparer a un int (par defaut)
2740
+            break;
2741
+        case 'annee_relatif':
2742
+            $col = 'YEAR(' . $date_compare . ')-YEAR(' .
2743
+                $date_orig . ')';
2744
+            $col_vraie = '';// comparer a un int (par defaut)
2745
+            break;
2746
+    }
2747
+
2748
+    return [$col, $col_vraie];
2749 2749
 }
2750 2750
 
2751 2751
 /**
@@ -2764,16 +2764,16 @@  discard block
 block discarded – undo
2764 2764
  *     de colonne SQL et une date.
2765 2765
  **/
2766 2766
 function calculer_param_date($date_compare, $date_orig) {
2767
-	if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) {
2768
-		$init = "'\" . (\$x = $r[1]) . \"'";
2769
-		$date_compare = '\'$x\'';
2770
-	} else {
2771
-		$init = $date_compare;
2772
-	}
2773
-
2774
-	return
2775
-		// optimisation : mais prevoir le support SQLite avant
2776
-		"TIMESTAMPDIFF(HOUR,$date_orig,$init)/24";
2767
+    if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) {
2768
+        $init = "'\" . (\$x = $r[1]) . \"'";
2769
+        $date_compare = '\'$x\'';
2770
+    } else {
2771
+        $init = $date_compare;
2772
+    }
2773
+
2774
+    return
2775
+        // optimisation : mais prevoir le support SQLite avant
2776
+        "TIMESTAMPDIFF(HOUR,$date_orig,$init)/24";
2777 2777
 }
2778 2778
 
2779 2779
 /**
@@ -2791,17 +2791,17 @@  discard block
 block discarded – undo
2791 2791
  * @param Critere $crit Paramètres du critère dans cette boucle
2792 2792
  */
2793 2793
 function critere_DATA_source_dist($idb, &$boucles, $crit) {
2794
-	$boucle = &$boucles[$idb];
2794
+    $boucle = &$boucles[$idb];
2795 2795
 
2796
-	$args = [];
2797
-	foreach ($crit->param as &$param) {
2798
-		$args[] = calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent);
2799
-	}
2796
+    $args = [];
2797
+    foreach ($crit->param as &$param) {
2798
+        $args[] = calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent);
2799
+    }
2800 2800
 
2801
-	$boucle->hash .= '
2801
+    $boucle->hash .= '
2802 2802
 	$command[\'sourcemode\'] = ' . array_shift($args) . ";\n";
2803 2803
 
2804
-	$boucle->hash .= '
2804
+    $boucle->hash .= '
2805 2805
 	$command[\'source\'] = array(' . implode(', ', $args) . ");\n";
2806 2806
 }
2807 2807
 
@@ -2819,8 +2819,8 @@  discard block
 block discarded – undo
2819 2819
  * @param Critere $crit Paramètres du critère dans cette boucle
2820 2820
  */
2821 2821
 function critere_DATA_datacache_dist($idb, &$boucles, $crit) {
2822
-	$boucle = &$boucles[$idb];
2823
-	$boucle->hash .= '
2822
+    $boucle = &$boucles[$idb];
2823
+    $boucle->hash .= '
2824 2824
 	$command[\'datacache\'] = ' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2825 2825
 }
2826 2826
 
@@ -2836,12 +2836,12 @@  discard block
 block discarded – undo
2836 2836
  * @param Critere $crit Paramètres du critère dans cette boucle
2837 2837
  */
2838 2838
 function critere_php_args_dist($idb, &$boucles, $crit) {
2839
-	$boucle = &$boucles[$idb];
2840
-	$boucle->hash .= '$command[\'args\']=array();';
2841
-	foreach ($crit->param as $param) {
2842
-		$boucle->hash .= '
2839
+    $boucle = &$boucles[$idb];
2840
+    $boucle->hash .= '$command[\'args\']=array();';
2841
+    foreach ($crit->param as $param) {
2842
+        $boucle->hash .= '
2843 2843
 			$command[\'args\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2844
-	}
2844
+    }
2845 2845
 }
2846 2846
 
2847 2847
 /**
@@ -2858,16 +2858,16 @@  discard block
 block discarded – undo
2858 2858
  * @param Critere $crit Paramètres du critère dans cette boucle
2859 2859
  */
2860 2860
 function critere_DATA_liste_dist($idb, &$boucles, $crit) {
2861
-	$boucle = &$boucles[$idb];
2862
-	$boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n";
2863
-	foreach ($crit->param as $param) {
2864
-		$boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste(
2865
-			$param,
2866
-			$idb,
2867
-			$boucles,
2868
-			$boucles[$idb]->id_parent
2869
-		) . ";\n";
2870
-	}
2861
+    $boucle = &$boucles[$idb];
2862
+    $boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n";
2863
+    foreach ($crit->param as $param) {
2864
+        $boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste(
2865
+            $param,
2866
+            $idb,
2867
+            $boucles,
2868
+            $boucles[$idb]->id_parent
2869
+        ) . ";\n";
2870
+    }
2871 2871
 }
2872 2872
 
2873 2873
 /**
@@ -2892,16 +2892,16 @@  discard block
 block discarded – undo
2892 2892
  * @param Critere $crit Paramètres du critère dans cette boucle
2893 2893
  */
2894 2894
 function critere_DATA_enum_dist($idb, &$boucles, $crit) {
2895
-	$boucle = &$boucles[$idb];
2896
-	$boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n";
2897
-	foreach ($crit->param as $param) {
2898
-		$boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste(
2899
-			$param,
2900
-			$idb,
2901
-			$boucles,
2902
-			$boucles[$idb]->id_parent
2903
-		) . ";\n";
2904
-	}
2895
+    $boucle = &$boucles[$idb];
2896
+    $boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n";
2897
+    foreach ($crit->param as $param) {
2898
+        $boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste(
2899
+            $param,
2900
+            $idb,
2901
+            $boucles,
2902
+            $boucles[$idb]->id_parent
2903
+        ) . ";\n";
2904
+    }
2905 2905
 }
2906 2906
 
2907 2907
 /**
@@ -2916,11 +2916,11 @@  discard block
 block discarded – undo
2916 2916
  * @param Critere $crit Paramètres du critère dans cette boucle
2917 2917
  */
2918 2918
 function critere_DATA_datapath_dist($idb, &$boucles, $crit) {
2919
-	$boucle = &$boucles[$idb];
2920
-	foreach ($crit->param as $param) {
2921
-		$boucle->hash .= '
2919
+    $boucle = &$boucles[$idb];
2920
+    foreach ($crit->param as $param) {
2921
+        $boucle->hash .= '
2922 2922
 			$command[\'datapath\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2923
-	}
2923
+    }
2924 2924
 }
2925 2925
 
2926 2926
 
@@ -2952,20 +2952,20 @@  discard block
 block discarded – undo
2952 2952
  * @param Critere $crit Paramètres du critère dans cette boucle
2953 2953
  */
2954 2954
 function critere_si_dist($idb, &$boucles, $crit) {
2955
-	$boucle = &$boucles[$idb];
2956
-	// il faut initialiser 1 fois le tableau a chaque appel de la boucle
2957
-	// (par exemple lorsque notre boucle est appelee dans une autre boucle)
2958
-	// mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle !
2959
-	$boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
2960
-	if ($crit->param) {
2961
-		foreach ($crit->param as $param) {
2962
-			$boucle->hash .= "\t\$command['si'][] = "
2963
-				. calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n";
2964
-		}
2965
-		// interdire {si 0} aussi !
2966
-	} else {
2967
-		$boucle->hash .= '$command[\'si\'][] = 0;';
2968
-	}
2955
+    $boucle = &$boucles[$idb];
2956
+    // il faut initialiser 1 fois le tableau a chaque appel de la boucle
2957
+    // (par exemple lorsque notre boucle est appelee dans une autre boucle)
2958
+    // mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle !
2959
+    $boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
2960
+    if ($crit->param) {
2961
+        foreach ($crit->param as $param) {
2962
+            $boucle->hash .= "\t\$command['si'][] = "
2963
+                . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n";
2964
+        }
2965
+        // interdire {si 0} aussi !
2966
+    } else {
2967
+        $boucle->hash .= '$command[\'si\'][] = 0;';
2968
+    }
2969 2969
 }
2970 2970
 
2971 2971
 /**
@@ -2983,27 +2983,27 @@  discard block
 block discarded – undo
2983 2983
  */
2984 2984
 function critere_noeud_dist($idb, &$boucles, $crit) {
2985 2985
 
2986
-	$not = $crit->not;
2987
-	$boucle = &$boucles[$idb];
2988
-	$primary = $boucle->primary;
2986
+    $not = $crit->not;
2987
+    $boucle = &$boucles[$idb];
2988
+    $primary = $boucle->primary;
2989 2989
 
2990
-	if (!$primary || strpos((string) $primary, ',')) {
2991
-		erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle);
2990
+    if (!$primary || strpos((string) $primary, ',')) {
2991
+        erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle);
2992 2992
 
2993
-		return;
2994
-	}
2995
-	$table = $boucle->type_requete;
2996
-	$table_sql = table_objet_sql(objet_type($table));
2993
+        return;
2994
+    }
2995
+    $table = $boucle->type_requete;
2996
+    $table_sql = table_objet_sql(objet_type($table));
2997 2997
 
2998
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
2998
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
2999 2999
 
3000
-	$in = 'IN';
3001
-	$where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"];
3002
-	if ($not) {
3003
-		$where = ["'NOT'", $where];
3004
-	}
3000
+    $in = 'IN';
3001
+    $where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"];
3002
+    if ($not) {
3003
+        $where = ["'NOT'", $where];
3004
+    }
3005 3005
 
3006
-	$boucle->where[] = $where;
3006
+    $boucle->where[] = $where;
3007 3007
 }
3008 3008
 
3009 3009
 /**
@@ -3019,8 +3019,8 @@  discard block
 block discarded – undo
3019 3019
  * @param Critere $crit Paramètres du critère dans cette boucle
3020 3020
  */
3021 3021
 function critere_feuille_dist($idb, &$boucles, $crit) {
3022
-	$not = $crit->not;
3023
-	$crit->not = !$not;
3024
-	critere_noeud_dist($idb, $boucles, $crit);
3025
-	$crit->not = $not;
3022
+    $not = $crit->not;
3023
+    $crit->not = !$not;
3024
+    critere_noeud_dist($idb, $boucles, $crit);
3025
+    $crit->not = $not;
3026 3026
 }
Please login to merge, or discard this patch.
ecrire/public/normaliser.php 1 patch
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -13,15 +13,15 @@  discard block
 block discarded – undo
13 13
 \***************************************************************************/
14 14
 
15 15
 if (!defined('_ECRIRE_INC_VERSION')) {
16
-	return;
16
+    return;
17 17
 }
18 18
 
19 19
 function phraser_vieux_modele($p) {
20
- normaliser_args_inclumodel($p);
20
+    normaliser_args_inclumodel($p);
21 21
 }
22 22
 
23 23
 function phraser_vieux_inclu($p) {
24
- normaliser_args_inclumodel($p);
24
+    normaliser_args_inclumodel($p);
25 25
 }
26 26
 
27 27
 /**
@@ -32,24 +32,24 @@  discard block
 block discarded – undo
32 32
  * @return void
33 33
  */
34 34
 function normaliser_args_inclumodel($p) {
35
-	$params = $p->param;
36
-	if (!$params) {
37
-		return;
38
-	}
39
-	$args = $params[0];
40
-	if ($args[0]) {
41
-		return;
42
-	} // filtre immediat
43
-	array_shift($p->param);
44
-	foreach ($p->param as $l) {
45
-		if (!array_shift($l)) {
46
-			$args = array_merge($args, $l);
47
-			array_shift($p->param);
48
-		} else {
49
-			break;
50
-		} // filtre
51
-	}
52
-	array_unshift($p->param, $args);
35
+    $params = $p->param;
36
+    if (!$params) {
37
+        return;
38
+    }
39
+    $args = $params[0];
40
+    if ($args[0]) {
41
+        return;
42
+    } // filtre immediat
43
+    array_shift($p->param);
44
+    foreach ($p->param as $l) {
45
+        if (!array_shift($l)) {
46
+            $args = array_merge($args, $l);
47
+            array_shift($p->param);
48
+        } else {
49
+            break;
50
+        } // filtre
51
+    }
52
+    array_unshift($p->param, $args);
53 53
 }
54 54
 
55 55
 
@@ -59,35 +59,35 @@  discard block
 block discarded – undo
59 59
  * @return void
60 60
  */
61 61
 function normaliser_inclure($champ) {
62
-	normaliser_args_inclumodel($champ);
63
-	$l = $champ->param[0];
64
-	if (is_array($l) && !$l[0]) {
65
-		foreach ($l as $k => $p) {
66
-			if ($p && $p[0]->type == 'texte' && !strpos((string) $p[0]->texte, '=')) {
67
-				$p[0]->texte = trim((string) $p[0]->texte);
68
-			}
69
-		}
70
-		foreach ($l as $k => $p) {
71
-			if (
72
-				!$p || $p[0]->type != 'texte'
73
-				|| !preg_match('/^fond\s*=\s*(.*)$/', (string) $p[0]->texte, $r)
74
-			) {
75
-				continue;
76
-			}
62
+    normaliser_args_inclumodel($champ);
63
+    $l = $champ->param[0];
64
+    if (is_array($l) && !$l[0]) {
65
+        foreach ($l as $k => $p) {
66
+            if ($p && $p[0]->type == 'texte' && !strpos((string) $p[0]->texte, '=')) {
67
+                $p[0]->texte = trim((string) $p[0]->texte);
68
+            }
69
+        }
70
+        foreach ($l as $k => $p) {
71
+            if (
72
+                !$p || $p[0]->type != 'texte'
73
+                || !preg_match('/^fond\s*=\s*(.*)$/', (string) $p[0]->texte, $r)
74
+            ) {
75
+                continue;
76
+            }
77 77
 
78
-			if ($r[1]) {
79
-				$p[0]->texte = $r[1];
80
-			} else {
81
-				unset($p[0]);
82
-			}
83
-			$champ->texte = $p;
84
-			unset($champ->param[0][$k]);
85
-			if ((is_countable($champ->param[0]) ? count($champ->param[0]) : 0) == 1) {
86
-				array_shift($champ->param);
87
-			}
78
+            if ($r[1]) {
79
+                $p[0]->texte = $r[1];
80
+            } else {
81
+                unset($p[0]);
82
+            }
83
+            $champ->texte = $p;
84
+            unset($champ->param[0][$k]);
85
+            if ((is_countable($champ->param[0]) ? count($champ->param[0]) : 0) == 1) {
86
+                array_shift($champ->param);
87
+            }
88 88
 
89
-			return;
90
-		}
91
-	}
92
-	spip_log('inclure sans fond ni fichier', 'vieilles_def');
89
+            return;
90
+        }
91
+    }
92
+    spip_log('inclure sans fond ni fichier', 'vieilles_def');
93 93
 }
Please login to merge, or discard this patch.
ecrire/public/decompiler.php 1 patch
Indentation   +176 added lines, -176 removed lines patch added patch discarded remove patch
@@ -12,129 +12,129 @@  discard block
 block discarded – undo
12 12
 \***************************************************************************/
13 13
 
14 14
 if (!defined('_ECRIRE_INC_VERSION')) {
15
-	return;
15
+    return;
16 16
 }
17 17
 
18 18
 // Decompilation de l'arbre de syntaxe abstraite d'un squelette SPIP
19 19
 
20 20
 function decompiler_boucle($struct, $fmt = '', $prof = 0) {
21
-	$nom = $struct->id_boucle;
22
-	$preaff = decompiler_($struct->preaff, $fmt, $prof);
23
-	$avant = decompiler_($struct->avant, $fmt, $prof);
24
-	$apres = decompiler_($struct->apres, $fmt, $prof);
25
-	$altern = decompiler_($struct->altern, $fmt, $prof);
26
-	$milieu = decompiler_($struct->milieu, $fmt, $prof);
27
-	$postaff = decompiler_($struct->postaff, $fmt, $prof);
28
-
29
-	$type = $struct->sql_serveur ? "$struct->sql_serveur:" : '';
30
-	$type .= ($struct->type_requete ?: $struct->type_table_optionnelle);
31
-
32
-	if ($struct->jointures_explicites) {
33
-		$type .= ' ' . $struct->jointures_explicites;
34
-	}
35
-	if ($struct->table_optionnelle) {
36
-		$type .= '?';
37
-	}
38
-	// Revoir le cas de la boucle recursive
39
-
40
-	$crit = $struct->param;
41
-	if ($crit && !is_array($crit[0])) {
42
-		$type = strtolower($type) . array_shift($crit);
43
-	}
44
-	$crit = decompiler_criteres($struct, $fmt, $prof);
45
-
46
-	$f = 'format_boucle_' . $fmt;
47
-
48
-	return $f($preaff, $avant, $nom, $type, $crit, $milieu, $apres, $altern, $postaff, $prof);
21
+    $nom = $struct->id_boucle;
22
+    $preaff = decompiler_($struct->preaff, $fmt, $prof);
23
+    $avant = decompiler_($struct->avant, $fmt, $prof);
24
+    $apres = decompiler_($struct->apres, $fmt, $prof);
25
+    $altern = decompiler_($struct->altern, $fmt, $prof);
26
+    $milieu = decompiler_($struct->milieu, $fmt, $prof);
27
+    $postaff = decompiler_($struct->postaff, $fmt, $prof);
28
+
29
+    $type = $struct->sql_serveur ? "$struct->sql_serveur:" : '';
30
+    $type .= ($struct->type_requete ?: $struct->type_table_optionnelle);
31
+
32
+    if ($struct->jointures_explicites) {
33
+        $type .= ' ' . $struct->jointures_explicites;
34
+    }
35
+    if ($struct->table_optionnelle) {
36
+        $type .= '?';
37
+    }
38
+    // Revoir le cas de la boucle recursive
39
+
40
+    $crit = $struct->param;
41
+    if ($crit && !is_array($crit[0])) {
42
+        $type = strtolower($type) . array_shift($crit);
43
+    }
44
+    $crit = decompiler_criteres($struct, $fmt, $prof);
45
+
46
+    $f = 'format_boucle_' . $fmt;
47
+
48
+    return $f($preaff, $avant, $nom, $type, $crit, $milieu, $apres, $altern, $postaff, $prof);
49 49
 }
50 50
 
51 51
 function decompiler_include($struct, $fmt = '', $prof = 0) {
52
-	$res = [];
53
-	foreach ($struct->param ?: [] as $couple) {
54
-		array_shift($couple);
55
-		foreach ($couple as $v) {
56
-			$res[] = decompiler_($v, $fmt, $prof);
57
-		}
58
-	}
59
-	$file = is_string($struct->texte) ? $struct->texte :
60
-		decompiler_($struct->texte, $fmt, $prof);
61
-	$f = 'format_inclure_' . $fmt;
62
-
63
-	return $f($file, $res, $prof);
52
+    $res = [];
53
+    foreach ($struct->param ?: [] as $couple) {
54
+        array_shift($couple);
55
+        foreach ($couple as $v) {
56
+            $res[] = decompiler_($v, $fmt, $prof);
57
+        }
58
+    }
59
+    $file = is_string($struct->texte) ? $struct->texte :
60
+        decompiler_($struct->texte, $fmt, $prof);
61
+    $f = 'format_inclure_' . $fmt;
62
+
63
+    return $f($file, $res, $prof);
64 64
 }
65 65
 
66 66
 function decompiler_texte($struct, $fmt = '', $prof = 0) {
67
-	$f = 'format_texte_' . $fmt;
67
+    $f = 'format_texte_' . $fmt;
68 68
 
69
-	return strlen((string) $struct->texte) ? $f($struct->texte, $prof) : '';
69
+    return strlen((string) $struct->texte) ? $f($struct->texte, $prof) : '';
70 70
 }
71 71
 
72 72
 function decompiler_polyglotte($struct, $fmt = '', $prof = 0) {
73
-	$f = 'format_polyglotte_' . $fmt;
73
+    $f = 'format_polyglotte_' . $fmt;
74 74
 
75
-	return $f($struct->traductions, $prof);
75
+    return $f($struct->traductions, $prof);
76 76
 }
77 77
 
78 78
 function decompiler_idiome($struct, $fmt = '', $prof = 0) {
79
-	$args = [];
80
-	foreach ($struct->arg as $k => $v) {
81
-		$args[$k] = public_decompiler($v, $fmt, $prof);
82
-	}
79
+    $args = [];
80
+    foreach ($struct->arg as $k => $v) {
81
+        $args[$k] = public_decompiler($v, $fmt, $prof);
82
+    }
83 83
 
84
-	$filtres = decompiler_liste($struct->param, $fmt, $prof);
84
+    $filtres = decompiler_liste($struct->param, $fmt, $prof);
85 85
 
86
-	$f = 'format_idiome_' . $fmt;
86
+    $f = 'format_idiome_' . $fmt;
87 87
 
88
-	return $f($struct->nom_champ, $struct->module, $args, $filtres, $prof);
88
+    return $f($struct->nom_champ, $struct->module, $args, $filtres, $prof);
89 89
 }
90 90
 
91 91
 function decompiler_champ($struct, $fmt = '', $prof = 0) {
92
-	$avant = decompiler_($struct->avant, $fmt, $prof);
93
-	$apres = decompiler_($struct->apres, $fmt, $prof);
94
-	$args = $filtres = '';
95
-	if ($p = $struct->param) {
96
-		if ($p[0][0] === '') {
97
-			$args = decompiler_liste([array_shift($p)], $fmt, $prof);
98
-		}
99
-		$filtres = decompiler_liste($p, $fmt, $prof);
100
-	}
101
-	$f = 'format_champ_' . $fmt;
102
-
103
-	return $f($struct->nom_champ, $struct->nom_boucle, $struct->etoile, $avant, $apres, $args, $filtres, $prof);
92
+    $avant = decompiler_($struct->avant, $fmt, $prof);
93
+    $apres = decompiler_($struct->apres, $fmt, $prof);
94
+    $args = $filtres = '';
95
+    if ($p = $struct->param) {
96
+        if ($p[0][0] === '') {
97
+            $args = decompiler_liste([array_shift($p)], $fmt, $prof);
98
+        }
99
+        $filtres = decompiler_liste($p, $fmt, $prof);
100
+    }
101
+    $f = 'format_champ_' . $fmt;
102
+
103
+    return $f($struct->nom_champ, $struct->nom_boucle, $struct->etoile, $avant, $apres, $args, $filtres, $prof);
104 104
 }
105 105
 
106 106
 function decompiler_liste($sources, $fmt = '', $prof = 0) {
107
-	if (!is_array($sources)) {
108
-		return '';
109
-	}
110
-	$f = 'format_liste_' . $fmt;
111
-	$res = '';
112
-	foreach ($sources as $arg) {
113
-		if (!is_array($arg)) {
114
-			continue; // ne devrait pas arriver.
115
-		} else {
116
-			$r = array_shift($arg);
117
-		}
118
-		$args = [];
119
-		foreach ($arg as $v) {
120
-			// cas des arguments entoures de ' ou "
121
-			if (
122
-				(is_countable($v) ? count($v) : 0) == 1
123
-				&& $v[0]->type == 'texte'
124
-				&& strlen((string) $v[0]->apres) == 1
125
-				&& $v[0]->apres == $v[0]->avant
126
-			) {
127
-				$args[] = $v[0]->avant . $v[0]->texte . $v[0]->apres;
128
-			} else {
129
-				$args[] = decompiler_($v, $fmt, 0 - $prof);
130
-			}
131
-		}
132
-		if ($r !== '' || $args) {
133
-			$res .= $f($r, $args, $prof);
134
-		}
135
-	}
136
-
137
-	return $res;
107
+    if (!is_array($sources)) {
108
+        return '';
109
+    }
110
+    $f = 'format_liste_' . $fmt;
111
+    $res = '';
112
+    foreach ($sources as $arg) {
113
+        if (!is_array($arg)) {
114
+            continue; // ne devrait pas arriver.
115
+        } else {
116
+            $r = array_shift($arg);
117
+        }
118
+        $args = [];
119
+        foreach ($arg as $v) {
120
+            // cas des arguments entoures de ' ou "
121
+            if (
122
+                (is_countable($v) ? count($v) : 0) == 1
123
+                && $v[0]->type == 'texte'
124
+                && strlen((string) $v[0]->apres) == 1
125
+                && $v[0]->apres == $v[0]->avant
126
+            ) {
127
+                $args[] = $v[0]->avant . $v[0]->texte . $v[0]->apres;
128
+            } else {
129
+                $args[] = decompiler_($v, $fmt, 0 - $prof);
130
+            }
131
+        }
132
+        if ($r !== '' || $args) {
133
+            $res .= $f($r, $args, $prof);
134
+        }
135
+    }
136
+
137
+    return $res;
138 138
 }
139 139
 
140 140
 // Decompilation des criteres: on triche et on deroge:
@@ -142,93 +142,93 @@  discard block
 block discarded – undo
142 142
 // - le champ apres signale le critere {"separateur"} ou {'separateur'}
143 143
 // - les champs sont implicitement etendus (crochets implicites mais interdits)
144 144
 function decompiler_criteres($boucle, $fmt = '', $prof = 0) {
145
-	$sources = $boucle->param;
146
-	if (!is_array($sources)) {
147
-		return '';
148
-	}
149
-	$res = '';
150
-	$f = 'format_critere_' . $fmt;
151
-	foreach ($sources as $crit) {
152
-		if (!is_array($crit)) {
153
-			continue;
154
-		} // boucle recursive
155
-		array_shift($crit);
156
-		$args = [];
157
-		foreach ($crit as $i => $v) {
158
-			if (
159
-				(is_countable($v) ? count($v) : 0) == 1
160
-				&& $v[0]->type == 'texte'
161
-				&& $v[0]->apres
162
-			) {
163
-				$args[] = [['texte', ($v[0]->apres . $v[0]->texte . $v[0]->apres)]];
164
-			} else {
165
-				$res2 = [];
166
-				foreach ($v as $k => $p) {
167
-					if (
168
-						isset($p->type)
169
-						&& function_exists($d = 'decompiler_' . $p->type)
170
-					) {
171
-						$r = $d($p, $fmt, (0 - $prof));
172
-						$res2[] = [$p->type, $r];
173
-					} else {
174
-						spip_log("critere $i / $k mal forme");
175
-					}
176
-				}
177
-				$args[] = $res2;
178
-			}
179
-		}
180
-		$res .= $f($args);
181
-	}
182
-
183
-	return $res;
145
+    $sources = $boucle->param;
146
+    if (!is_array($sources)) {
147
+        return '';
148
+    }
149
+    $res = '';
150
+    $f = 'format_critere_' . $fmt;
151
+    foreach ($sources as $crit) {
152
+        if (!is_array($crit)) {
153
+            continue;
154
+        } // boucle recursive
155
+        array_shift($crit);
156
+        $args = [];
157
+        foreach ($crit as $i => $v) {
158
+            if (
159
+                (is_countable($v) ? count($v) : 0) == 1
160
+                && $v[0]->type == 'texte'
161
+                && $v[0]->apres
162
+            ) {
163
+                $args[] = [['texte', ($v[0]->apres . $v[0]->texte . $v[0]->apres)]];
164
+            } else {
165
+                $res2 = [];
166
+                foreach ($v as $k => $p) {
167
+                    if (
168
+                        isset($p->type)
169
+                        && function_exists($d = 'decompiler_' . $p->type)
170
+                    ) {
171
+                        $r = $d($p, $fmt, (0 - $prof));
172
+                        $res2[] = [$p->type, $r];
173
+                    } else {
174
+                        spip_log("critere $i / $k mal forme");
175
+                    }
176
+                }
177
+                $args[] = $res2;
178
+            }
179
+        }
180
+        $res .= $f($args);
181
+    }
182
+
183
+    return $res;
184 184
 }
185 185
 
186 186
 
187 187
 function decompiler_($liste, $fmt = '', $prof = 0) {
188
-	if (!is_array($liste)) {
189
-		return '';
190
-	}
191
-	$prof2 = ($prof < 0) ? ($prof - 1) : ($prof + 1);
192
-	$contenu = [];
193
-	foreach ($liste as $k => $p) {
194
-		if (!isset($p->type)) {
195
-			continue;
196
-		} #??????
197
-		$d = 'decompiler_' . $p->type;
198
-		$next = $liste[$k + 1] ?? false;
199
-		// Forcer le champ etendu si son source (pas les reecritures)
200
-		// contenait des args et s'il est suivi d'espaces,
201
-		// le champ simple les eliminant est un bug helas perenne.
202
-
203
-		if (
204
-			$next
205
-			&& $next->type == 'texte'
206
-			&& $p->type == 'champ'
207
-			&& !$p->apres
208
-			&& !$p->avant
209
-			&& $p->fonctions
210
-		) {
211
-			$n = strlen((string) $next->texte) - strlen(ltrim((string) $next->texte));
212
-			if ($n) {
213
-				$champ = new Texte();
214
-				$champ->texte = substr((string) $next->texte, 0, $n);
215
-				$champ->ligne = $p->ligne;
216
-				$p->apres = [$champ];
217
-				$next->texte = substr((string) $next->texte, $n);
218
-			}
219
-		}
220
-		$contenu[] = [$d($p, $fmt, $prof2), $p->type];
221
-	}
222
-	$f = 'format_suite_' . $fmt;
223
-
224
-	return $f($contenu);
188
+    if (!is_array($liste)) {
189
+        return '';
190
+    }
191
+    $prof2 = ($prof < 0) ? ($prof - 1) : ($prof + 1);
192
+    $contenu = [];
193
+    foreach ($liste as $k => $p) {
194
+        if (!isset($p->type)) {
195
+            continue;
196
+        } #??????
197
+        $d = 'decompiler_' . $p->type;
198
+        $next = $liste[$k + 1] ?? false;
199
+        // Forcer le champ etendu si son source (pas les reecritures)
200
+        // contenait des args et s'il est suivi d'espaces,
201
+        // le champ simple les eliminant est un bug helas perenne.
202
+
203
+        if (
204
+            $next
205
+            && $next->type == 'texte'
206
+            && $p->type == 'champ'
207
+            && !$p->apres
208
+            && !$p->avant
209
+            && $p->fonctions
210
+        ) {
211
+            $n = strlen((string) $next->texte) - strlen(ltrim((string) $next->texte));
212
+            if ($n) {
213
+                $champ = new Texte();
214
+                $champ->texte = substr((string) $next->texte, 0, $n);
215
+                $champ->ligne = $p->ligne;
216
+                $p->apres = [$champ];
217
+                $next->texte = substr((string) $next->texte, $n);
218
+            }
219
+        }
220
+        $contenu[] = [$d($p, $fmt, $prof2), $p->type];
221
+    }
222
+    $f = 'format_suite_' . $fmt;
223
+
224
+    return $f($contenu);
225 225
 }
226 226
 
227 227
 function public_decompiler($liste, $fmt = '', $prof = 0, $quoi = '') {
228
-	if (!include_spip('public/format_' . $fmt)) {
229
-		return "'$fmt'?";
230
-	}
231
-	$f = 'decompiler_' . $quoi;
228
+    if (!include_spip('public/format_' . $fmt)) {
229
+        return "'$fmt'?";
230
+    }
231
+    $f = 'decompiler_' . $quoi;
232 232
 
233
-	return $f($liste, $fmt, $prof);
233
+    return $f($liste, $fmt, $prof);
234 234
 }
Please login to merge, or discard this patch.
ecrire/public/parametrer.php 1 patch
Indentation   +247 added lines, -247 removed lines patch added patch discarded remove patch
@@ -10,7 +10,7 @@  discard block
 block discarded – undo
10 10
 \***************************************************************************/
11 11
 
12 12
 if (!defined('_ECRIRE_INC_VERSION')) {
13
-	return;
13
+    return;
14 14
 }
15 15
 
16 16
 include_fichiers_fonctions();
@@ -29,178 +29,178 @@  discard block
 block discarded – undo
29 29
 # En cas d'erreur process_ins est absent et texte est un tableau de 2 chaines
30 30
 
31 31
 function public_parametrer_dist($fond, $contexte = '', $cache = '', string $connect = '') {
32
-	static $composer, $styliser, $notes = null;
33
-	$courant = null;
34
-	$page = tester_redirection($fond, $contexte, $connect);
35
-	if ($page) {
36
-		return $page;
37
-	}
38
-
39
-	if (isset($contexte['lang'])) {
40
-		$lang = $contexte['lang'];
41
-	} elseif (!isset($lang)) {
42
-		$lang = $GLOBALS['meta']['langue_site'];
43
-	}
44
-
45
-	$select = ((!isset($GLOBALS['forcer_lang']) || !$GLOBALS['forcer_lang']) && $lang != $GLOBALS['spip_lang']);
46
-	if ($select) {
47
-		$select = lang_select($lang);
48
-	}
49
-
50
-	$debug = (defined('_VAR_MODE') && _VAR_MODE == 'debug');
51
-
52
-	if (!$styliser) {
53
-		$styliser = charger_fonction('styliser', 'public');
54
-	}
55
-	[$skel, $mime_type, $gram, $sourcefile] =
56
-		$styliser($fond, $contexte, $GLOBALS['spip_lang'], $connect);
57
-
58
-	if ($skel) {
59
-		// sauver le nom de l'eventuel squelette en cours d'execution
60
-		// (recursion possible a cause des modeles)
61
-		if ($debug) {
62
-			$courant = $GLOBALS['debug_objets']['courant'] ?? null;
63
-			$GLOBALS['debug_objets']['contexte'][$sourcefile] = $contexte;
64
-		}
65
-
66
-		// charger le squelette en specifiant les langages cibles et source
67
-		// au cas il faudrait le compiler (source posterieure au resultat)
68
-
69
-		if (!$composer) {
70
-			$composer = charger_fonction('composer', 'public');
71
-		}
72
-		$fonc = $composer($skel, $mime_type, $gram, $sourcefile, $connect);
73
-	} else {
74
-		$fonc = '';
75
-	}
76
-
77
-	if (!$fonc) { // squelette inconnu (==='') ou faux (===false)
78
-		$page = $fonc;
79
-	} else {
80
-		// Preparer l'appel de la fonction principale du squelette
81
-
82
-		spip_timer($a = 'calcul page ' . random_int(0, 1000));
83
-
84
-		// On cree un marqueur de notes unique lie a cette composition
85
-		// et on enregistre l'etat courant des globales de notes...
86
-		if (is_null($notes)) {
87
-			$notes = charger_fonction('notes', 'inc', true);
88
-		}
89
-		if ($notes) {
90
-			$notes('', 'empiler');
91
-		}
92
-
93
-		// Rajouter d'office ces deux parametres
94
-		// (mais vaudrait mieux que le compilateur sache le simuler
95
-		// car ca interdit l'usage de criteres conditionnels dessus).
96
-		if (!isset($contexte['date'])) {
97
-			$contexte['date'] = date('Y-m-d H:i:s');
98
-			$contexte['date_default'] = true;
99
-		} else {
100
-			$contexte['date'] = normaliser_date($contexte['date'], true);
101
-		}
102
-
103
-		if (!isset($contexte['date_redac'])) {
104
-			$contexte['date_redac'] = date('Y-m-d H:i:s');
105
-			$contexte['date_redac_default'] = true;
106
-		} else {
107
-			$contexte['date_redac'] = normaliser_date($contexte['date_redac'], true);
108
-		}
109
-
110
-		// Passer le nom du cache pour produire sa destruction automatique
111
-		try {
112
-			$page = $fonc(['cache' => $cache], [$contexte]);
113
-		} catch (Throwable $e) {
114
-			$msg = _T('zbug_erreur_execution_page') . " $sourcefile";
115
-			$full_msg = $msg . ' | File ' . $e->getFile() . ' Line ' . $e->getLine() . ' : ' . $e->getMessage();
116
-			$full_msg = str_replace(_ROOT_RACINE, '[…]/', $full_msg);
117
-			$corps = "<pre>$msg</pre>";
118
-			$page = analyse_resultat_skel($fond, ['cache' => $cache], $corps, $sourcefile);
119
-			erreur_squelette($full_msg);
120
-			unset($msg, $full_msg, $corps);
121
-		}
122
-
123
-		// Restituer les globales de notes telles qu'elles etaient avant l'appel
124
-		// Si l'inclus n'a pas affiche ses notes, tant pis (elles *doivent*
125
-		// etre dans son resultat, autrement elles ne seraient pas prises en
126
-		// compte a chaque calcul d'un texte contenant un modele, mais seulement
127
-		// quand le modele serait calcule, et on aurait des resultats incoherents)
128
-		if ($notes) {
129
-			$notes('', 'depiler');
130
-		}
131
-
132
-		// reinjecter en dynamique la pile des notes
133
-		// si il y a des inclure dynamiques
134
-		// si la pile n'est pas vide
135
-		// la generalisation de cette injection permettrait de corriger le point juste au dessus
136
-		// en faisant remonter les notes a l'incluant (A tester et valider avant application)
137
-		if ($notes) {
138
-			$page['notes'] = $notes('', 'sauver_etat');
139
-		}
140
-
141
-		// spip_log: un joli contexte
142
-		$infos = presenter_contexte(array_filter($contexte));
143
-
144
-		$profile = spip_timer($a);
145
-		spip_log("calcul ($profile) [$skel] $infos"
146
-			. ' (' . strlen((string) $page['texte']) . ' octets)');
147
-
148
-		if (defined('_CALCUL_PROFILER') && (int) $profile > _CALCUL_PROFILER) {
149
-			spip_log("calcul ($profile) [$skel] $infos"
150
-				. ' (' . strlen((string) $page['texte']) . ' octets) | ' . $_SERVER['REQUEST_URI'], 'profiler' . _LOG_AVERTISSEMENT);
151
-		}
152
-
153
-		if ($debug) {
154
-			// si c'est ce que demande le debusqueur, lui passer la main
155
-			$t = strlen((string) $page['texte']) ? $page['texte'] : ' ';
156
-			$GLOBALS['debug_objets']['resultat'][$fonc . 'tout'] = $t;
157
-			$GLOBALS['debug_objets']['courant'] = $courant;
158
-			$GLOBALS['debug_objets']['profile'][$sourcefile] = $profile;
159
-			if (
160
-				$GLOBALS['debug_objets']['sourcefile']
161
-				&& _request('var_mode_objet') == $fonc
162
-				&& _request('var_mode_affiche') == 'resultat'
163
-			) {
164
-				erreur_squelette();
165
-			}
166
-		}
167
-		// Si #CACHE{} n'etait pas la, le mettre a $delais
168
-		if (!isset($page['entetes']['X-Spip-Cache'])) {
169
-			// Dans l'espace prive ou dans un modeles/ on pose un cache 0 par defaut
170
-			// si aucun #CACHE{} spécifié
171
-			// le contexte implicite qui conditionne le cache assure qu'on retombe pas sur le meme
172
-			// entre public et prive
173
-			if (test_espace_prive() || str_starts_with((string) $fond, 'modeles/')) {
174
-				$page['entetes']['X-Spip-Cache'] = 0;
175
-			} else {
176
-				$page['entetes']['X-Spip-Cache'] = $GLOBALS['delais'] ?? 36000;
177
-			}
178
-		}
179
-
180
-		$page['contexte'] = $contexte;
181
-
182
-		// faire remonter le fichier source
183
-		static $js_inclus = false;
184
-		if (defined('_VAR_INCLURE') && _VAR_INCLURE) {
185
-			$page['sourcefile'] = $sourcefile;
186
-			$page['texte'] =
187
-				"<div class='inclure_blocs'><h6>" . $page['sourcefile'] . '</h6>' . $page['texte'] . '</div>'
188
-				. ($js_inclus ? '' : "<script type='text/javascript'>jQuery(function(){jQuery('.inclure_blocs > h6:first-child').hover(function(){jQuery(this).parent().addClass('hover')},function(){jQuery(this).parent().removeClass('hover')})});</script>");
189
-			$js_inclus = true;
190
-		}
191
-
192
-		// Si un modele contenait #SESSION, on note l'info dans $page
193
-		if (isset($GLOBALS['cache_utilise_session'])) {
194
-			$page['invalideurs']['session'] = $GLOBALS['cache_utilise_session'];
195
-			unset($GLOBALS['cache_utilise_session']);
196
-		}
197
-	}
198
-
199
-	if ($select) {
200
-		lang_select();
201
-	}
202
-
203
-	return $page;
32
+    static $composer, $styliser, $notes = null;
33
+    $courant = null;
34
+    $page = tester_redirection($fond, $contexte, $connect);
35
+    if ($page) {
36
+        return $page;
37
+    }
38
+
39
+    if (isset($contexte['lang'])) {
40
+        $lang = $contexte['lang'];
41
+    } elseif (!isset($lang)) {
42
+        $lang = $GLOBALS['meta']['langue_site'];
43
+    }
44
+
45
+    $select = ((!isset($GLOBALS['forcer_lang']) || !$GLOBALS['forcer_lang']) && $lang != $GLOBALS['spip_lang']);
46
+    if ($select) {
47
+        $select = lang_select($lang);
48
+    }
49
+
50
+    $debug = (defined('_VAR_MODE') && _VAR_MODE == 'debug');
51
+
52
+    if (!$styliser) {
53
+        $styliser = charger_fonction('styliser', 'public');
54
+    }
55
+    [$skel, $mime_type, $gram, $sourcefile] =
56
+        $styliser($fond, $contexte, $GLOBALS['spip_lang'], $connect);
57
+
58
+    if ($skel) {
59
+        // sauver le nom de l'eventuel squelette en cours d'execution
60
+        // (recursion possible a cause des modeles)
61
+        if ($debug) {
62
+            $courant = $GLOBALS['debug_objets']['courant'] ?? null;
63
+            $GLOBALS['debug_objets']['contexte'][$sourcefile] = $contexte;
64
+        }
65
+
66
+        // charger le squelette en specifiant les langages cibles et source
67
+        // au cas il faudrait le compiler (source posterieure au resultat)
68
+
69
+        if (!$composer) {
70
+            $composer = charger_fonction('composer', 'public');
71
+        }
72
+        $fonc = $composer($skel, $mime_type, $gram, $sourcefile, $connect);
73
+    } else {
74
+        $fonc = '';
75
+    }
76
+
77
+    if (!$fonc) { // squelette inconnu (==='') ou faux (===false)
78
+        $page = $fonc;
79
+    } else {
80
+        // Preparer l'appel de la fonction principale du squelette
81
+
82
+        spip_timer($a = 'calcul page ' . random_int(0, 1000));
83
+
84
+        // On cree un marqueur de notes unique lie a cette composition
85
+        // et on enregistre l'etat courant des globales de notes...
86
+        if (is_null($notes)) {
87
+            $notes = charger_fonction('notes', 'inc', true);
88
+        }
89
+        if ($notes) {
90
+            $notes('', 'empiler');
91
+        }
92
+
93
+        // Rajouter d'office ces deux parametres
94
+        // (mais vaudrait mieux que le compilateur sache le simuler
95
+        // car ca interdit l'usage de criteres conditionnels dessus).
96
+        if (!isset($contexte['date'])) {
97
+            $contexte['date'] = date('Y-m-d H:i:s');
98
+            $contexte['date_default'] = true;
99
+        } else {
100
+            $contexte['date'] = normaliser_date($contexte['date'], true);
101
+        }
102
+
103
+        if (!isset($contexte['date_redac'])) {
104
+            $contexte['date_redac'] = date('Y-m-d H:i:s');
105
+            $contexte['date_redac_default'] = true;
106
+        } else {
107
+            $contexte['date_redac'] = normaliser_date($contexte['date_redac'], true);
108
+        }
109
+
110
+        // Passer le nom du cache pour produire sa destruction automatique
111
+        try {
112
+            $page = $fonc(['cache' => $cache], [$contexte]);
113
+        } catch (Throwable $e) {
114
+            $msg = _T('zbug_erreur_execution_page') . " $sourcefile";
115
+            $full_msg = $msg . ' | File ' . $e->getFile() . ' Line ' . $e->getLine() . ' : ' . $e->getMessage();
116
+            $full_msg = str_replace(_ROOT_RACINE, '[…]/', $full_msg);
117
+            $corps = "<pre>$msg</pre>";
118
+            $page = analyse_resultat_skel($fond, ['cache' => $cache], $corps, $sourcefile);
119
+            erreur_squelette($full_msg);
120
+            unset($msg, $full_msg, $corps);
121
+        }
122
+
123
+        // Restituer les globales de notes telles qu'elles etaient avant l'appel
124
+        // Si l'inclus n'a pas affiche ses notes, tant pis (elles *doivent*
125
+        // etre dans son resultat, autrement elles ne seraient pas prises en
126
+        // compte a chaque calcul d'un texte contenant un modele, mais seulement
127
+        // quand le modele serait calcule, et on aurait des resultats incoherents)
128
+        if ($notes) {
129
+            $notes('', 'depiler');
130
+        }
131
+
132
+        // reinjecter en dynamique la pile des notes
133
+        // si il y a des inclure dynamiques
134
+        // si la pile n'est pas vide
135
+        // la generalisation de cette injection permettrait de corriger le point juste au dessus
136
+        // en faisant remonter les notes a l'incluant (A tester et valider avant application)
137
+        if ($notes) {
138
+            $page['notes'] = $notes('', 'sauver_etat');
139
+        }
140
+
141
+        // spip_log: un joli contexte
142
+        $infos = presenter_contexte(array_filter($contexte));
143
+
144
+        $profile = spip_timer($a);
145
+        spip_log("calcul ($profile) [$skel] $infos"
146
+            . ' (' . strlen((string) $page['texte']) . ' octets)');
147
+
148
+        if (defined('_CALCUL_PROFILER') && (int) $profile > _CALCUL_PROFILER) {
149
+            spip_log("calcul ($profile) [$skel] $infos"
150
+                . ' (' . strlen((string) $page['texte']) . ' octets) | ' . $_SERVER['REQUEST_URI'], 'profiler' . _LOG_AVERTISSEMENT);
151
+        }
152
+
153
+        if ($debug) {
154
+            // si c'est ce que demande le debusqueur, lui passer la main
155
+            $t = strlen((string) $page['texte']) ? $page['texte'] : ' ';
156
+            $GLOBALS['debug_objets']['resultat'][$fonc . 'tout'] = $t;
157
+            $GLOBALS['debug_objets']['courant'] = $courant;
158
+            $GLOBALS['debug_objets']['profile'][$sourcefile] = $profile;
159
+            if (
160
+                $GLOBALS['debug_objets']['sourcefile']
161
+                && _request('var_mode_objet') == $fonc
162
+                && _request('var_mode_affiche') == 'resultat'
163
+            ) {
164
+                erreur_squelette();
165
+            }
166
+        }
167
+        // Si #CACHE{} n'etait pas la, le mettre a $delais
168
+        if (!isset($page['entetes']['X-Spip-Cache'])) {
169
+            // Dans l'espace prive ou dans un modeles/ on pose un cache 0 par defaut
170
+            // si aucun #CACHE{} spécifié
171
+            // le contexte implicite qui conditionne le cache assure qu'on retombe pas sur le meme
172
+            // entre public et prive
173
+            if (test_espace_prive() || str_starts_with((string) $fond, 'modeles/')) {
174
+                $page['entetes']['X-Spip-Cache'] = 0;
175
+            } else {
176
+                $page['entetes']['X-Spip-Cache'] = $GLOBALS['delais'] ?? 36000;
177
+            }
178
+        }
179
+
180
+        $page['contexte'] = $contexte;
181
+
182
+        // faire remonter le fichier source
183
+        static $js_inclus = false;
184
+        if (defined('_VAR_INCLURE') && _VAR_INCLURE) {
185
+            $page['sourcefile'] = $sourcefile;
186
+            $page['texte'] =
187
+                "<div class='inclure_blocs'><h6>" . $page['sourcefile'] . '</h6>' . $page['texte'] . '</div>'
188
+                . ($js_inclus ? '' : "<script type='text/javascript'>jQuery(function(){jQuery('.inclure_blocs > h6:first-child').hover(function(){jQuery(this).parent().addClass('hover')},function(){jQuery(this).parent().removeClass('hover')})});</script>");
189
+            $js_inclus = true;
190
+        }
191
+
192
+        // Si un modele contenait #SESSION, on note l'info dans $page
193
+        if (isset($GLOBALS['cache_utilise_session'])) {
194
+            $page['invalideurs']['session'] = $GLOBALS['cache_utilise_session'];
195
+            unset($GLOBALS['cache_utilise_session']);
196
+        }
197
+    }
198
+
199
+    if ($select) {
200
+        lang_select();
201
+    }
202
+
203
+    return $page;
204 204
 }
205 205
 
206 206
 /**
@@ -209,37 +209,37 @@  discard block
 block discarded – undo
209 209
  * @return string
210 210
 */
211 211
 function presenter_contexte($contexte, $profondeur_max = 1, $max_lines = 0) {
212
-	$infos = [];
213
-	$line = 0;
214
-	foreach ($contexte as $var => $val) {
215
-		$line++;
216
-		if ($max_lines && $max_lines < $line) {
217
-			$infos[] = '…';
218
-			break;
219
-		}
220
-		if ($val === null) {
221
-			$val = '';
222
-		} elseif (is_array($val)) {
223
-			if ($profondeur_max > 0) {
224
-				$val = 'array:' . count($val) . '(' . presenter_contexte($val, $profondeur_max - 1, 3) . ')';
225
-			} else {
226
-				$val = 'array:' . count($val);
227
-			}
228
-		} elseif (is_object($val)) {
229
-			$val = $val::class;
230
-		} elseif (strlen("$val") > 30) {
231
-			$val = substr("$val", 0, 29) . '…';
232
-			if (strstr($val, ' ')) {
233
-				$val = "'$val'";
234
-			}
235
-		} elseif (strstr((string) $val, ' ')) {
236
-			$val = "'$val'";
237
-		} elseif (!strlen((string) $val)) {
238
-			$val = "''";
239
-		}
240
-		$infos[] = $var . '=' . $val;
241
-	}
242
-	return implode(', ', $infos);
212
+    $infos = [];
213
+    $line = 0;
214
+    foreach ($contexte as $var => $val) {
215
+        $line++;
216
+        if ($max_lines && $max_lines < $line) {
217
+            $infos[] = '…';
218
+            break;
219
+        }
220
+        if ($val === null) {
221
+            $val = '';
222
+        } elseif (is_array($val)) {
223
+            if ($profondeur_max > 0) {
224
+                $val = 'array:' . count($val) . '(' . presenter_contexte($val, $profondeur_max - 1, 3) . ')';
225
+            } else {
226
+                $val = 'array:' . count($val);
227
+            }
228
+        } elseif (is_object($val)) {
229
+            $val = $val::class;
230
+        } elseif (strlen("$val") > 30) {
231
+            $val = substr("$val", 0, 29) . '…';
232
+            if (strstr($val, ' ')) {
233
+                $val = "'$val'";
234
+            }
235
+        } elseif (strstr((string) $val, ' ')) {
236
+            $val = "'$val'";
237
+        } elseif (!strlen((string) $val)) {
238
+            $val = "''";
239
+        }
240
+        $infos[] = $var . '=' . $val;
241
+    }
242
+    return implode(', ', $infos);
243 243
 }
244 244
 
245 245
 
@@ -256,11 +256,11 @@  discard block
 block discarded – undo
256 256
  * @return array|bool
257 257
  */
258 258
 function tester_redirection($fond, $contexte, $connect) {
259
-	static $tester_redirection = null;
260
-	if (is_null($tester_redirection)) {
261
-		$tester_redirection = charger_fonction('tester_redirection', 'public');
262
-	}
263
-	return $tester_redirection($fond, $contexte, $connect);
259
+    static $tester_redirection = null;
260
+    if (is_null($tester_redirection)) {
261
+        $tester_redirection = charger_fonction('tester_redirection', 'public');
262
+    }
263
+    return $tester_redirection($fond, $contexte, $connect);
264 264
 }
265 265
 
266 266
 
@@ -276,42 +276,42 @@  discard block
 block discarded – undo
276 276
  * @return array|bool
277 277
  */
278 278
 function public_tester_redirection_dist($fond, $contexte, $connect) {
279
-	if (
280
-		$fond == 'article'
281
-		&& !empty($contexte['id_article'])
282
-		&& ($id_article = (int) $contexte['id_article'])
283
-	) {
284
-		include_spip('public/quete'); // pour quete_virtuel et ses dependances
285
-		$m = quete_virtuel($id_article, $connect) ?? '';
286
-		if (strlen($m)) {
287
-			include_spip('inc/texte');
288
-			// les navigateurs pataugent si l'URL est vide
289
-			if ($url = virtuel_redirige($m, true)) {
290
-				// passer en url absolue car cette redirection pourra
291
-				// etre utilisee dans un contexte d'url qui change
292
-				// y compris url arbo
293
-				$status = 302;
294
-				if (defined('_STATUS_REDIRECTION_VIRTUEL')) {
295
-					$status = _STATUS_REDIRECTION_VIRTUEL;
296
-				}
297
-				if (!preg_match(',^\w+:,', (string) $url)) {
298
-					include_spip('inc/filtres_mini');
299
-					$url = url_absolue($url);
300
-				}
301
-				$url = str_replace('&amp;', '&', (string) $url);
302
-
303
-				return [
304
-					'texte' => '<'
305
-						. "?php include_spip('inc/headers');redirige_par_entete('"
306
-						. texte_script($url)
307
-						. "','',$status);"
308
-						. '?' . '>',
309
-					'process_ins' => 'php',
310
-					'status' => $status
311
-				];
312
-			}
313
-		}
314
-	}
315
-
316
-	return false;
279
+    if (
280
+        $fond == 'article'
281
+        && !empty($contexte['id_article'])
282
+        && ($id_article = (int) $contexte['id_article'])
283
+    ) {
284
+        include_spip('public/quete'); // pour quete_virtuel et ses dependances
285
+        $m = quete_virtuel($id_article, $connect) ?? '';
286
+        if (strlen($m)) {
287
+            include_spip('inc/texte');
288
+            // les navigateurs pataugent si l'URL est vide
289
+            if ($url = virtuel_redirige($m, true)) {
290
+                // passer en url absolue car cette redirection pourra
291
+                // etre utilisee dans un contexte d'url qui change
292
+                // y compris url arbo
293
+                $status = 302;
294
+                if (defined('_STATUS_REDIRECTION_VIRTUEL')) {
295
+                    $status = _STATUS_REDIRECTION_VIRTUEL;
296
+                }
297
+                if (!preg_match(',^\w+:,', (string) $url)) {
298
+                    include_spip('inc/filtres_mini');
299
+                    $url = url_absolue($url);
300
+                }
301
+                $url = str_replace('&amp;', '&', (string) $url);
302
+
303
+                return [
304
+                    'texte' => '<'
305
+                        . "?php include_spip('inc/headers');redirige_par_entete('"
306
+                        . texte_script($url)
307
+                        . "','',$status);"
308
+                        . '?' . '>',
309
+                    'process_ins' => 'php',
310
+                    'status' => $status
311
+                ];
312
+            }
313
+        }
314
+    }
315
+
316
+    return false;
317 317
 }
Please login to merge, or discard this patch.
ecrire/public/compiler.php 1 patch
Indentation   +1213 added lines, -1213 removed lines patch added patch discarded remove patch
@@ -20,7 +20,7 @@  discard block
 block discarded – undo
20 20
  **/
21 21
 
22 22
 if (!defined('_ECRIRE_INC_VERSION')) {
23
-	return;
23
+    return;
24 24
 }
25 25
 
26 26
 /** Repérer un code ne calculant rien, meme avec commentaire */
@@ -61,92 +61,92 @@  discard block
 block discarded – undo
61 61
 
62 62
 
63 63
 function argumenter_inclure(
64
-	$params,
65
-	$rejet_filtres,
66
-	$p,
67
-	&$boucles,
68
-	$id_boucle,
69
-	$echap = true,
70
-	$lang = '',
71
-	$fond1 = false
64
+    $params,
65
+    $rejet_filtres,
66
+    $p,
67
+    &$boucles,
68
+    $id_boucle,
69
+    $echap = true,
70
+    $lang = '',
71
+    $fond1 = false
72 72
 ) {
73
-	$l = [];
74
-	$erreur_p_i_i = '';
75
-	if (!is_array($params)) {
76
-		return $l;
77
-	}
78
-	foreach ($params as $k => $couple) {
79
-		// la liste d'arguments d'inclusion peut se terminer par un filtre
80
-		$filtre = array_shift($couple);
81
-		if ($filtre) {
82
-			break;
83
-		}
84
-		foreach ($couple as $n => $val) {
85
-			$var = $val[0];
86
-			if ($var->type != 'texte') {
87
-				if ($n || $k || $fond1) {
88
-					$erreur_p_i_i = [
89
-						'zbug_parametres_inclus_incorrects',
90
-						['param' => $var->nom_champ]
91
-					];
92
-					erreur_squelette($erreur_p_i_i, $p);
93
-					break;
94
-				} else {
95
-					$l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle);
96
-				}
97
-			} else {
98
-				preg_match(',^([^=]*)(=?)(.*)$,m', $var->texte, $m);
99
-				$m = array_pad($m, 3, null);
100
-				$var = $m[1];
101
-				$auto = false;
102
-
103
-				if ($m[2]) {
104
-					$v = $m[3];
105
-					if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) {
106
-						$v = $m[1];
107
-					}
108
-					$val[0] = new Texte();
109
-					$val[0]->texte = $v;
110
-				} elseif ($k || $n || $fond1) {
111
-					$auto = true;
112
-				} else {
113
-					$var = 1;
114
-				}
115
-
116
-				if ($var == 'lang') {
117
-					$lang = !$auto
118
-						? calculer_liste($val, $p->descr, $boucles, $id_boucle)
119
-						: '$GLOBALS["spip_lang"]';
120
-				} else {
121
-					$val = $auto
122
-						? index_pile($id_boucle, $var, $boucles)
123
-						: calculer_liste($val, $p->descr, $boucles, $id_boucle);
124
-					if ($var !== 1) {
125
-						$val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
126
-							. $val . ($echap ? ") . '" : ' ');
127
-					} else {
128
-						$val = $echap ? "'.$val.'" : $val;
129
-					}
130
-					$l[$var] = $val;
131
-				}
132
-			}
133
-		}
134
-	}
135
-	if ($erreur_p_i_i) {
136
-		return false;
137
-	}
138
-	// Cas particulier de la langue : si {lang=xx} est definie, on
139
-	// la passe, sinon on passe la langue courante au moment du calcul
140
-	// sauf si on n'en veut pas
141
-	if ($lang === false) {
142
-		return $l;
143
-	}
144
-	if (!$lang) {
145
-		$lang = '$GLOBALS["spip_lang"]';
146
-	}
147
-	$l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : ' ');
148
-
149
-	return $l;
73
+    $l = [];
74
+    $erreur_p_i_i = '';
75
+    if (!is_array($params)) {
76
+        return $l;
77
+    }
78
+    foreach ($params as $k => $couple) {
79
+        // la liste d'arguments d'inclusion peut se terminer par un filtre
80
+        $filtre = array_shift($couple);
81
+        if ($filtre) {
82
+            break;
83
+        }
84
+        foreach ($couple as $n => $val) {
85
+            $var = $val[0];
86
+            if ($var->type != 'texte') {
87
+                if ($n || $k || $fond1) {
88
+                    $erreur_p_i_i = [
89
+                        'zbug_parametres_inclus_incorrects',
90
+                        ['param' => $var->nom_champ]
91
+                    ];
92
+                    erreur_squelette($erreur_p_i_i, $p);
93
+                    break;
94
+                } else {
95
+                    $l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle);
96
+                }
97
+            } else {
98
+                preg_match(',^([^=]*)(=?)(.*)$,m', $var->texte, $m);
99
+                $m = array_pad($m, 3, null);
100
+                $var = $m[1];
101
+                $auto = false;
102
+
103
+                if ($m[2]) {
104
+                    $v = $m[3];
105
+                    if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) {
106
+                        $v = $m[1];
107
+                    }
108
+                    $val[0] = new Texte();
109
+                    $val[0]->texte = $v;
110
+                } elseif ($k || $n || $fond1) {
111
+                    $auto = true;
112
+                } else {
113
+                    $var = 1;
114
+                }
115
+
116
+                if ($var == 'lang') {
117
+                    $lang = !$auto
118
+                        ? calculer_liste($val, $p->descr, $boucles, $id_boucle)
119
+                        : '$GLOBALS["spip_lang"]';
120
+                } else {
121
+                    $val = $auto
122
+                        ? index_pile($id_boucle, $var, $boucles)
123
+                        : calculer_liste($val, $p->descr, $boucles, $id_boucle);
124
+                    if ($var !== 1) {
125
+                        $val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
126
+                            . $val . ($echap ? ") . '" : ' ');
127
+                    } else {
128
+                        $val = $echap ? "'.$val.'" : $val;
129
+                    }
130
+                    $l[$var] = $val;
131
+                }
132
+            }
133
+        }
134
+    }
135
+    if ($erreur_p_i_i) {
136
+        return false;
137
+    }
138
+    // Cas particulier de la langue : si {lang=xx} est definie, on
139
+    // la passe, sinon on passe la langue courante au moment du calcul
140
+    // sauf si on n'en veut pas
141
+    if ($lang === false) {
142
+        return $l;
143
+    }
144
+    if (!$lang) {
145
+        $lang = '$GLOBALS["spip_lang"]';
146
+    }
147
+    $l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : ' ');
148
+
149
+    return $l;
150 150
 }
151 151
 
152 152
 /**
@@ -170,84 +170,84 @@  discard block
 block discarded – undo
170 170
  **/
171 171
 function calculer_inclure($p, &$boucles, $id_boucle) {
172 172
 
173
-	$_options = [];
174
-	$_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
175
-	if (is_string($p->texte)) {
176
-		$fichier = $p->texte;
177
-		$code = '"' . str_replace('"', '\"', $fichier) . '"';
178
-	} else {
179
-		$code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
180
-		if ($code && preg_match("/^'([^']*)'/s", $code, $r)) {
181
-			$fichier = $r[1];
182
-		} else {
183
-			$fichier = '';
184
-		}
185
-	}
186
-	if (!$code || $code === '""' || $code === "''") {
187
-		$trace = $p->fonctions;
188
-		while (
189
-			is_array($trace)
190
-			&& ($trace = array_filter($trace))
191
-			&& count($trace) == 1
192
-		) {
193
-			$trace = reset($trace);
194
-		}
195
-		$erreur_p_i_i = [
196
-			'zbug_parametres_inclus_incorrects',
197
-			['param' => print_r($trace, true)]
198
-		];
199
-		erreur_squelette($erreur_p_i_i, $p);
200
-
201
-		return "''";
202
-	}
203
-	$compil = texte_script(memoriser_contexte_compil($p));
204
-
205
-	if (is_array($_contexte)) {
206
-		// Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
207
-		if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) {
208
-			unset($_contexte['env']);
209
-		}
210
-
211
-		// noter les doublons dans l'appel a public.php
212
-		if (isset($_contexte['doublons'])) {
213
-			$_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'";
214
-		}
215
-
216
-		if ($ajax = isset($_contexte['ajax'])) {
217
-			$ajax = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
218
-			unset($_contexte['ajax']);
219
-		}
220
-
221
-		$_contexte = join(",\n\t", $_contexte);
222
-	} else {
223
-		return false;
224
-	} // j'aurais voulu toucher le fond ...
225
-
226
-	$contexte = 'array(' . $_contexte . ')';
227
-
228
-	if ($env) {
229
-		$contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
230
-	}
231
-
232
-	// s'il y a une extension .php, ce n'est pas un squelette
233
-	if ($fichier && preg_match('/^.+[.]php$/s', $fichier)) {
234
-		$code = sandbox_composer_inclure_php($fichier, $p, $contexte);
235
-	} else {
236
-		$_options[] = "\"compil\"=>array($compil)";
237
-		if ($ajax) {
238
-			$_options[] = $ajax;
239
-		}
240
-		$code = " ' . argumenter_squelette($code) . '";
241
-		$code = 'echo ' . sprintf(
242
-			CODE_RECUPERER_FOND,
243
-			$code,
244
-			$contexte,
245
-			implode(',', $_options),
246
-			"_request(\\'connect\\') ?? \\'\\'"
247
-		) . ';';
248
-	}
249
-
250
-	return "\n'<'.'" . '?php ' . $code . "\n?'." . "'>'";
173
+    $_options = [];
174
+    $_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
175
+    if (is_string($p->texte)) {
176
+        $fichier = $p->texte;
177
+        $code = '"' . str_replace('"', '\"', $fichier) . '"';
178
+    } else {
179
+        $code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
180
+        if ($code && preg_match("/^'([^']*)'/s", $code, $r)) {
181
+            $fichier = $r[1];
182
+        } else {
183
+            $fichier = '';
184
+        }
185
+    }
186
+    if (!$code || $code === '""' || $code === "''") {
187
+        $trace = $p->fonctions;
188
+        while (
189
+            is_array($trace)
190
+            && ($trace = array_filter($trace))
191
+            && count($trace) == 1
192
+        ) {
193
+            $trace = reset($trace);
194
+        }
195
+        $erreur_p_i_i = [
196
+            'zbug_parametres_inclus_incorrects',
197
+            ['param' => print_r($trace, true)]
198
+        ];
199
+        erreur_squelette($erreur_p_i_i, $p);
200
+
201
+        return "''";
202
+    }
203
+    $compil = texte_script(memoriser_contexte_compil($p));
204
+
205
+    if (is_array($_contexte)) {
206
+        // Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
207
+        if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) {
208
+            unset($_contexte['env']);
209
+        }
210
+
211
+        // noter les doublons dans l'appel a public.php
212
+        if (isset($_contexte['doublons'])) {
213
+            $_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'";
214
+        }
215
+
216
+        if ($ajax = isset($_contexte['ajax'])) {
217
+            $ajax = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
218
+            unset($_contexte['ajax']);
219
+        }
220
+
221
+        $_contexte = join(",\n\t", $_contexte);
222
+    } else {
223
+        return false;
224
+    } // j'aurais voulu toucher le fond ...
225
+
226
+    $contexte = 'array(' . $_contexte . ')';
227
+
228
+    if ($env) {
229
+        $contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
230
+    }
231
+
232
+    // s'il y a une extension .php, ce n'est pas un squelette
233
+    if ($fichier && preg_match('/^.+[.]php$/s', $fichier)) {
234
+        $code = sandbox_composer_inclure_php($fichier, $p, $contexte);
235
+    } else {
236
+        $_options[] = "\"compil\"=>array($compil)";
237
+        if ($ajax) {
238
+            $_options[] = $ajax;
239
+        }
240
+        $code = " ' . argumenter_squelette($code) . '";
241
+        $code = 'echo ' . sprintf(
242
+            CODE_RECUPERER_FOND,
243
+            $code,
244
+            $contexte,
245
+            implode(',', $_options),
246
+            "_request(\\'connect\\') ?? \\'\\'"
247
+        ) . ';';
248
+    }
249
+
250
+    return "\n'<'.'" . '?php ' . $code . "\n?'." . "'>'";
251 251
 }
252 252
 
253 253
 
@@ -265,7 +265,7 @@  discard block
 block discarded – undo
265 265
  *     true pour ne tester que le cas publie et ignorer l'eventuel var_mode=preview de la page
266 266
  */
267 267
 function instituer_boucle(&$boucle, $echapper = true, $ignore_previsu = false) {
268
-	/*
268
+    /*
269 269
 	$show['statut'][] = array(
270 270
 		'champ'=>'statut',  // champ de la table sur lequel porte le filtrage par le statut
271 271
 		'publie'=>'publie', // valeur ou liste de valeurs, qui definissent l'objet comme publie.
@@ -289,75 +289,75 @@  discard block
 block discarded – undo
289 289
 	champstatut est alors le champ statut sur la tablen
290 290
 	dans les jointures, clen peut etre un tableau pour une jointure complexe : array('id_objet','id_article','objet','article')
291 291
 	*/
292
-	$id_table = $boucle->id_table;
293
-	$show = $boucle->show;
294
-	if (isset($show['statut']) && $show['statut']) {
295
-		foreach ($show['statut'] as $k => $s) {
296
-			// Restreindre aux elements publies si pas de {statut} ou autre dans les criteres
297
-			$filtrer = true;
298
-			if (isset($s['exception'])) {
299
-				foreach (is_array($s['exception']) ? $s['exception'] : [$s['exception']] as $m) {
300
-					if (isset($boucle->modificateur[$m]) || isset($boucle->modificateur['criteres'][$m])) {
301
-						$filtrer = false;
302
-						break;
303
-					}
304
-				}
305
-			}
306
-
307
-			if ($filtrer) {
308
-				if (is_array($s['champ'])) {
309
-					$statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite
310
-					$jointures = [];
311
-					// indiquer la description de chaque table dans le tableau de jointures,
312
-					// ce qui permet d'eviter certains GROUP BY inutiles.
313
-					$trouver_table = charger_fonction('trouver_table', 'base');
314
-					foreach ($s['champ'] as $j) {
315
-						$id = reset($j);
316
-						$def = $trouver_table($id);
317
-						$jointures[] = ['', [$id, $def], end($j)];
318
-					}
319
-					$jointures[0][0] = $id_table;
320
-					if (!array_search($id, $boucle->from)) {
321
-						include_spip('public/jointures');
322
-						fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper);
323
-					}
324
-					// trouver l'alias de la table d'arrivee qui porte le statut
325
-					$id = array_search($id, $boucle->from);
326
-				} else {
327
-					$id = $id_table;
328
-					$statut = preg_replace(',\W,', '', $s['champ']); // securite
329
-				}
330
-				$mstatut = $id . '.' . $statut;
331
-
332
-				$arg_ignore_previsu = ($ignore_previsu ? ',true' : '');
333
-				include_spip('public/quete');
334
-				if (
335
-					isset($s['post_date'])
336
-					&& $s['post_date']
337
-					&& $GLOBALS['meta']['post_dates'] == 'non'
338
-				) {
339
-					$date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
340
-					array_unshift(
341
-						$boucle->where,
342
-						$echapper ?
343
-							"\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
344
-							:
345
-							quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
346
-					);
347
-				}
348
-				array_unshift(
349
-					$boucle->where,
350
-					$echapper ?
351
-						"\nquete_condition_statut('$mstatut',"
352
-						. _q($s['previsu']) . ','
353
-						. _q($s['publie']) . ','
354
-						. _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
355
-						:
356
-						quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
357
-				);
358
-			}
359
-		}
360
-	}
292
+    $id_table = $boucle->id_table;
293
+    $show = $boucle->show;
294
+    if (isset($show['statut']) && $show['statut']) {
295
+        foreach ($show['statut'] as $k => $s) {
296
+            // Restreindre aux elements publies si pas de {statut} ou autre dans les criteres
297
+            $filtrer = true;
298
+            if (isset($s['exception'])) {
299
+                foreach (is_array($s['exception']) ? $s['exception'] : [$s['exception']] as $m) {
300
+                    if (isset($boucle->modificateur[$m]) || isset($boucle->modificateur['criteres'][$m])) {
301
+                        $filtrer = false;
302
+                        break;
303
+                    }
304
+                }
305
+            }
306
+
307
+            if ($filtrer) {
308
+                if (is_array($s['champ'])) {
309
+                    $statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite
310
+                    $jointures = [];
311
+                    // indiquer la description de chaque table dans le tableau de jointures,
312
+                    // ce qui permet d'eviter certains GROUP BY inutiles.
313
+                    $trouver_table = charger_fonction('trouver_table', 'base');
314
+                    foreach ($s['champ'] as $j) {
315
+                        $id = reset($j);
316
+                        $def = $trouver_table($id);
317
+                        $jointures[] = ['', [$id, $def], end($j)];
318
+                    }
319
+                    $jointures[0][0] = $id_table;
320
+                    if (!array_search($id, $boucle->from)) {
321
+                        include_spip('public/jointures');
322
+                        fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper);
323
+                    }
324
+                    // trouver l'alias de la table d'arrivee qui porte le statut
325
+                    $id = array_search($id, $boucle->from);
326
+                } else {
327
+                    $id = $id_table;
328
+                    $statut = preg_replace(',\W,', '', $s['champ']); // securite
329
+                }
330
+                $mstatut = $id . '.' . $statut;
331
+
332
+                $arg_ignore_previsu = ($ignore_previsu ? ',true' : '');
333
+                include_spip('public/quete');
334
+                if (
335
+                    isset($s['post_date'])
336
+                    && $s['post_date']
337
+                    && $GLOBALS['meta']['post_dates'] == 'non'
338
+                ) {
339
+                    $date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
340
+                    array_unshift(
341
+                        $boucle->where,
342
+                        $echapper ?
343
+                            "\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
344
+                            :
345
+                            quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
346
+                    );
347
+                }
348
+                array_unshift(
349
+                    $boucle->where,
350
+                    $echapper ?
351
+                        "\nquete_condition_statut('$mstatut',"
352
+                        . _q($s['previsu']) . ','
353
+                        . _q($s['publie']) . ','
354
+                        . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
355
+                        :
356
+                        quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
357
+                );
358
+            }
359
+        }
360
+    }
361 361
 }
362 362
 
363 363
 /**
@@ -376,29 +376,29 @@  discard block
 block discarded – undo
376 376
  */
377 377
 function calculer_boucle($id_boucle, &$boucles) {
378 378
 
379
-	$boucle = &$boucles[$id_boucle];
380
-	instituer_boucle($boucle);
381
-	$boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]);
382
-
383
-	// en mode debug memoriser les premiers passages dans la boucle,
384
-	// mais pas tous, sinon ca pete.
385
-	if (_request('var_mode_affiche') != 'resultat') {
386
-		$trace = '';
387
-	} else {
388
-		$_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
389
-		$_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
390
-		$trace = "
379
+    $boucle = &$boucles[$id_boucle];
380
+    instituer_boucle($boucle);
381
+    $boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]);
382
+
383
+    // en mode debug memoriser les premiers passages dans la boucle,
384
+    // mais pas tous, sinon ca pete.
385
+    if (_request('var_mode_affiche') != 'resultat') {
386
+        $trace = '';
387
+    } else {
388
+        $_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
389
+        $_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
390
+        $trace = "
391 391
 		if (empty($_trace)) {
392 392
 			$_trace = [];
393 393
 		}
394 394
 		if (count($_trace) < 3) {
395 395
 			$_trace" . '[] = $t0;
396 396
 		}';
397
-	}
397
+    }
398 398
 
399
-	return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF)
400
-		? calculer_boucle_rec($id_boucle, $boucles, $trace)
401
-		: calculer_boucle_nonrec($id_boucle, $boucles, $trace);
399
+    return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF)
400
+        ? calculer_boucle_rec($id_boucle, $boucles, $trace)
401
+        : calculer_boucle_nonrec($id_boucle, $boucles, $trace);
402 402
 }
403 403
 
404 404
 
@@ -421,15 +421,15 @@  discard block
 block discarded – undo
421 421
  *    Code PHP compilé de la boucle récursive
422 422
  **/
423 423
 function calculer_boucle_rec($id_boucle, &$boucles, $trace) {
424
-	$nom = $boucles[$id_boucle]->param[0];
425
-
426
-	return
427
-		// Numrows[$nom] peut ne pas être encore defini
428
-		"\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
429
-		. "\n\t\$t0 = " . $boucles[$id_boucle]->return . ';'
430
-		. "\n\t\$Numrows['$nom'] = (\$save_numrows);"
431
-		. $trace
432
-		. "\n\treturn \$t0;";
424
+    $nom = $boucles[$id_boucle]->param[0];
425
+
426
+    return
427
+        // Numrows[$nom] peut ne pas être encore defini
428
+        "\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
429
+        . "\n\t\$t0 = " . $boucles[$id_boucle]->return . ';'
430
+        . "\n\t\$Numrows['$nom'] = (\$save_numrows);"
431
+        . $trace
432
+        . "\n\treturn \$t0;";
433 433
 }
434 434
 
435 435
 /**
@@ -482,173 +482,173 @@  discard block
 block discarded – undo
482 482
  **/
483 483
 function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) {
484 484
 
485
-	$code_sep = null;
486
-	$boucle = &$boucles[$id_boucle];
487
-	$return = $boucle->return;
488
-	$type_boucle = $boucle->type_requete;
489
-	$primary = $boucle->primary;
490
-	$constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return));
491
-	$flag_cpt = $boucle->mode_partie || $boucle->cptrows;
492
-	$corps = '';
493
-
494
-	// faudrait expanser le foreach a la compil, car y en a souvent qu'un
495
-	// et puis faire un [] plutot qu'un "','."
496
-	if ($boucle->doublons) {
497
-		$corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
498
-			index_pile($id_boucle, $primary, $boucles)
499
-			. "; // doublons\n";
500
-	}
501
-
502
-	// La boucle doit-elle selectionner la langue ?
503
-	// - par defaut, les boucles suivantes le font
504
-	//    (sauf si forcer_lang==true ou si le titre contient <multi>).
505
-	// - a moins d'une demande explicite via {!lang_select}
506
-	if (
507
-		!$constant && $boucle->lang_select != 'non' &&
508
-		(($boucle->lang_select == 'oui') ||
509
-			in_array($type_boucle, [
510
-				'articles',
511
-				'rubriques',
512
-				'hierarchie',
513
-				'breves'
514
-			]))
515
-	) {
516
-		// Memoriser la langue avant la boucle et la restituer apres
517
-		// afin que le corps de boucle affecte la globale directement
518
-		$init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t";
519
-		$fin_lang = "lang_select();\n\t";
520
-		$fin_lang_select_public = "\n\t\tlang_select();";
521
-
522
-		$corps .=
523
-			"\n\t\tlang_select_public("
524
-			. index_pile($id_boucle, 'lang', $boucles)
525
-			. ", '" . $boucle->lang_select . "'"
526
-			. (in_array($type_boucle, [
527
-				'articles',
528
-				'rubriques',
529
-				'hierarchie',
530
-				'breves'
531
-			]) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
532
-			. ');';
533
-	} else {
534
-		$init_lang = '';
535
-		$fin_lang = '';
536
-		$fin_lang_select_public = '';
537
-		// sortir les appels au traducteur (invariants de boucle)
538
-		if (
539
-			!str_contains($return, '?php')
540
-			&& preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r)
541
-		) {
542
-			$i = 1;
543
-			foreach ($r[1] as $t) {
544
-				$init_lang .= "\n\t\$l$i = $t;";
545
-				$return = str_replace($t, "\$l$i", $return);
546
-				$i++;
547
-			}
548
-		}
549
-	}
550
-
551
-	// gestion optimale des separateurs et des boucles constantes
552
-	if (is_countable($boucle->separateur) ? count($boucle->separateur) : 0) {
553
-		$code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
554
-	}
555
-
556
-	$corps .=
557
-		((!$boucle->separateur) ?
558
-			(($constant && !$corps && !$flag_cpt) ? $return :
559
-				(($return === "''") ? '' :
560
-					("\n\t\t" . '$t0 .= ' . $return . ';'))) :
561
-			("\n\t\t\$t1 " .
562
-				((str_starts_with($return, '$t1.')) ?
563
-					('.=' . substr($return, 4)) :
564
-					('= ' . $return)) .
565
-				";\n\t\t" .
566
-				'$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
567
-
568
-	// Calculer les invalideurs si c'est une boucle non constante et si on
569
-	// souhaite invalider ces elements
570
-	if (!$constant && $primary) {
571
-		include_spip('inc/invalideur');
572
-		$corps = calcul_invalideurs($corps, $primary, $boucles, $id_boucle);
573
-	}
574
-
575
-	// gerer le compteur de boucle
576
-	// avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}...
577
-
578
-	if ($boucle->partie || $boucle->cptrows) {
579
-		$corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;"
580
-			. $boucle->partie
581
-			. $corps;
582
-	}
583
-
584
-	// depiler la lang de la boucle si besoin
585
-	$corps .= $fin_lang_select_public;
586
-
587
-	// si le corps est une constante, ne pas appeler le serveur N fois!
588
-
589
-	if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) {
590
-		if (!isset($r[2]) || !$r[2]) {
591
-			if (!$boucle->numrows) {
592
-				return "\n\t\$t0 = '';";
593
-			} else {
594
-				$corps = '';
595
-			}
596
-		} else {
597
-			$boucle->numrows = true;
598
-			$corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);";
599
-		}
600
-	} else {
601
-		$corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n	}";
602
-	}
603
-
604
-	$count = '';
605
-	if (!$boucle->select) {
606
-		if (!$boucle->numrows || $boucle->limit || $boucle->mode_partie || $boucle->group) {
607
-			$count = '1';
608
-		} else {
609
-			$count = 'count(*)';
610
-		}
611
-		$boucles[$id_boucle]->select[] = $count;
612
-	}
613
-
614
-	if ($flag_cpt) {
615
-		$nums = "\n\t// COMPTEUR\n\t"
616
-			. "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t";
617
-	} else {
618
-		$nums = '';
619
-	}
620
-
621
-	if ($boucle->numrows || $boucle->mode_partie) {
622
-		$nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t"
623
-			. "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());"
624
-			. $boucle->mode_partie
625
-			. "\n\t";
626
-	}
627
-
628
-	// Ne calculer la requete que maintenant
629
-	// car ce qui precede appelle index_pile qui influe dessus
630
-
631
-	$init = (($init = $boucles[$id_boucle]->doublons)
632
-			? ("\n\t$init = array();") : '')
633
-		. calculer_requete_sql($boucles[$id_boucle]);
634
-
635
-	$contexte = memoriser_contexte_compil($boucle);
636
-
637
-	$a = sprintf(
638
-		CODE_CORPS_BOUCLE,
639
-		$init,
640
-		$boucle->iterateur,
641
-		'$command',
642
-		$contexte,
643
-		$nums,
644
-		$init_lang,
645
-		$corps,
646
-		$fin_lang,
647
-		$trace,
648
-		'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
649
-	);
650
-
651
-	return $a;
485
+    $code_sep = null;
486
+    $boucle = &$boucles[$id_boucle];
487
+    $return = $boucle->return;
488
+    $type_boucle = $boucle->type_requete;
489
+    $primary = $boucle->primary;
490
+    $constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return));
491
+    $flag_cpt = $boucle->mode_partie || $boucle->cptrows;
492
+    $corps = '';
493
+
494
+    // faudrait expanser le foreach a la compil, car y en a souvent qu'un
495
+    // et puis faire un [] plutot qu'un "','."
496
+    if ($boucle->doublons) {
497
+        $corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
498
+            index_pile($id_boucle, $primary, $boucles)
499
+            . "; // doublons\n";
500
+    }
501
+
502
+    // La boucle doit-elle selectionner la langue ?
503
+    // - par defaut, les boucles suivantes le font
504
+    //    (sauf si forcer_lang==true ou si le titre contient <multi>).
505
+    // - a moins d'une demande explicite via {!lang_select}
506
+    if (
507
+        !$constant && $boucle->lang_select != 'non' &&
508
+        (($boucle->lang_select == 'oui') ||
509
+            in_array($type_boucle, [
510
+                'articles',
511
+                'rubriques',
512
+                'hierarchie',
513
+                'breves'
514
+            ]))
515
+    ) {
516
+        // Memoriser la langue avant la boucle et la restituer apres
517
+        // afin que le corps de boucle affecte la globale directement
518
+        $init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t";
519
+        $fin_lang = "lang_select();\n\t";
520
+        $fin_lang_select_public = "\n\t\tlang_select();";
521
+
522
+        $corps .=
523
+            "\n\t\tlang_select_public("
524
+            . index_pile($id_boucle, 'lang', $boucles)
525
+            . ", '" . $boucle->lang_select . "'"
526
+            . (in_array($type_boucle, [
527
+                'articles',
528
+                'rubriques',
529
+                'hierarchie',
530
+                'breves'
531
+            ]) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
532
+            . ');';
533
+    } else {
534
+        $init_lang = '';
535
+        $fin_lang = '';
536
+        $fin_lang_select_public = '';
537
+        // sortir les appels au traducteur (invariants de boucle)
538
+        if (
539
+            !str_contains($return, '?php')
540
+            && preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r)
541
+        ) {
542
+            $i = 1;
543
+            foreach ($r[1] as $t) {
544
+                $init_lang .= "\n\t\$l$i = $t;";
545
+                $return = str_replace($t, "\$l$i", $return);
546
+                $i++;
547
+            }
548
+        }
549
+    }
550
+
551
+    // gestion optimale des separateurs et des boucles constantes
552
+    if (is_countable($boucle->separateur) ? count($boucle->separateur) : 0) {
553
+        $code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
554
+    }
555
+
556
+    $corps .=
557
+        ((!$boucle->separateur) ?
558
+            (($constant && !$corps && !$flag_cpt) ? $return :
559
+                (($return === "''") ? '' :
560
+                    ("\n\t\t" . '$t0 .= ' . $return . ';'))) :
561
+            ("\n\t\t\$t1 " .
562
+                ((str_starts_with($return, '$t1.')) ?
563
+                    ('.=' . substr($return, 4)) :
564
+                    ('= ' . $return)) .
565
+                ";\n\t\t" .
566
+                '$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
567
+
568
+    // Calculer les invalideurs si c'est une boucle non constante et si on
569
+    // souhaite invalider ces elements
570
+    if (!$constant && $primary) {
571
+        include_spip('inc/invalideur');
572
+        $corps = calcul_invalideurs($corps, $primary, $boucles, $id_boucle);
573
+    }
574
+
575
+    // gerer le compteur de boucle
576
+    // avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}...
577
+
578
+    if ($boucle->partie || $boucle->cptrows) {
579
+        $corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;"
580
+            . $boucle->partie
581
+            . $corps;
582
+    }
583
+
584
+    // depiler la lang de la boucle si besoin
585
+    $corps .= $fin_lang_select_public;
586
+
587
+    // si le corps est une constante, ne pas appeler le serveur N fois!
588
+
589
+    if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) {
590
+        if (!isset($r[2]) || !$r[2]) {
591
+            if (!$boucle->numrows) {
592
+                return "\n\t\$t0 = '';";
593
+            } else {
594
+                $corps = '';
595
+            }
596
+        } else {
597
+            $boucle->numrows = true;
598
+            $corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);";
599
+        }
600
+    } else {
601
+        $corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n	}";
602
+    }
603
+
604
+    $count = '';
605
+    if (!$boucle->select) {
606
+        if (!$boucle->numrows || $boucle->limit || $boucle->mode_partie || $boucle->group) {
607
+            $count = '1';
608
+        } else {
609
+            $count = 'count(*)';
610
+        }
611
+        $boucles[$id_boucle]->select[] = $count;
612
+    }
613
+
614
+    if ($flag_cpt) {
615
+        $nums = "\n\t// COMPTEUR\n\t"
616
+            . "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t";
617
+    } else {
618
+        $nums = '';
619
+    }
620
+
621
+    if ($boucle->numrows || $boucle->mode_partie) {
622
+        $nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t"
623
+            . "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());"
624
+            . $boucle->mode_partie
625
+            . "\n\t";
626
+    }
627
+
628
+    // Ne calculer la requete que maintenant
629
+    // car ce qui precede appelle index_pile qui influe dessus
630
+
631
+    $init = (($init = $boucles[$id_boucle]->doublons)
632
+            ? ("\n\t$init = array();") : '')
633
+        . calculer_requete_sql($boucles[$id_boucle]);
634
+
635
+    $contexte = memoriser_contexte_compil($boucle);
636
+
637
+    $a = sprintf(
638
+        CODE_CORPS_BOUCLE,
639
+        $init,
640
+        $boucle->iterateur,
641
+        '$command',
642
+        $contexte,
643
+        $nums,
644
+        $init_lang,
645
+        $corps,
646
+        $fin_lang,
647
+        $trace,
648
+        'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
649
+    );
650
+
651
+    return $a;
652 652
 }
653 653
 
654 654
 
@@ -664,48 +664,48 @@  discard block
 block discarded – undo
664 664
  *     Code PHP compilé définissant les informations de requête
665 665
  **/
666 666
 function calculer_requete_sql($boucle) {
667
-	$init = [];
668
-	$init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
669
-	$init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
670
-	# En absence de champ c'est un decompte :
671
-	$init[] = calculer_dec('from', calculer_from($boucle));
672
-	$init[] = calculer_dec('type', calculer_from_type($boucle));
673
-	$init[] = calculer_dec(
674
-		'groupby',
675
-		'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ')'
676
-	);
677
-	$init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . '")');
678
-	$init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ')');
679
-	$init[] = calculer_dec('where', calculer_dump_array($boucle->where));
680
-	$init[] = calculer_dec('join', calculer_dump_join($boucle->join));
681
-	$init[] = calculer_dec(
682
-		'limit',
683
-		(
684
-			!str_contains($boucle->limit, 'intval') ?
685
-			"'" . ($boucle->limit) . "'" :
686
-			$boucle->limit
687
-		)
688
-	);
689
-	$init[] = calculer_dec('having', calculer_dump_array($boucle->having));
690
-	$s = $d = '';
691
-	// l'index 0 de $i indique si l'affectation est statique (contenu)
692
-	// ou recalculée à chaque passage (vide)
693
-	foreach ($init as $i) {
694
-		if (reset($i)) {
695
-			$s .= "\n\t\t" . end($i);
696
-		} # statique
697
-		else {
698
-			$d .= "\n\t" . end($i);
699
-		} # dynamique
700
-	}
701
-
702
-	return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
703
-	. $boucle->in
704
-	. $boucle->hash
705
-	. "\n\t" . 'if (!isset($command[\'table\'])) {'
706
-	. $s
707
-	. "\n\t}"
708
-	. $d;
667
+    $init = [];
668
+    $init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
669
+    $init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
670
+    # En absence de champ c'est un decompte :
671
+    $init[] = calculer_dec('from', calculer_from($boucle));
672
+    $init[] = calculer_dec('type', calculer_from_type($boucle));
673
+    $init[] = calculer_dec(
674
+        'groupby',
675
+        'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ')'
676
+    );
677
+    $init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . '")');
678
+    $init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ')');
679
+    $init[] = calculer_dec('where', calculer_dump_array($boucle->where));
680
+    $init[] = calculer_dec('join', calculer_dump_join($boucle->join));
681
+    $init[] = calculer_dec(
682
+        'limit',
683
+        (
684
+            !str_contains($boucle->limit, 'intval') ?
685
+            "'" . ($boucle->limit) . "'" :
686
+            $boucle->limit
687
+        )
688
+    );
689
+    $init[] = calculer_dec('having', calculer_dump_array($boucle->having));
690
+    $s = $d = '';
691
+    // l'index 0 de $i indique si l'affectation est statique (contenu)
692
+    // ou recalculée à chaque passage (vide)
693
+    foreach ($init as $i) {
694
+        if (reset($i)) {
695
+            $s .= "\n\t\t" . end($i);
696
+        } # statique
697
+        else {
698
+            $d .= "\n\t" . end($i);
699
+        } # dynamique
700
+    }
701
+
702
+    return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
703
+    . $boucle->in
704
+    . $boucle->hash
705
+    . "\n\t" . 'if (!isset($command[\'table\'])) {'
706
+    . $s
707
+    . "\n\t}"
708
+    . $d;
709 709
 }
710 710
 
711 711
 /**
@@ -723,13 +723,13 @@  discard block
 block discarded – undo
723 723
  *     qui peut être utilisé pour la production d'un tableau array()
724 724
  **/
725 725
 function memoriser_contexte_compil($p) {
726
-	return join(',', [
727
-		_q($p->descr['sourcefile'] ?? ''),
728
-		_q($p->descr['nom'] ?? ''),
729
-		_q($p->id_boucle ?? ''),
730
-		intval($p->ligne),
731
-		'$GLOBALS[\'spip_lang\']'
732
-	]);
726
+    return join(',', [
727
+        _q($p->descr['sourcefile'] ?? ''),
728
+        _q($p->descr['nom'] ?? ''),
729
+        _q($p->id_boucle ?? ''),
730
+        intval($p->ligne),
731
+        '$GLOBALS[\'spip_lang\']'
732
+    ]);
733 733
 }
734 734
 
735 735
 /**
@@ -747,20 +747,20 @@  discard block
 block discarded – undo
747 747
  *     Objet Contexte
748 748
  **/
749 749
 function reconstruire_contexte_compil($context_compil) {
750
-	if (!is_array($context_compil)) {
751
-		return $context_compil;
752
-	}
753
-	$p = new Contexte();
754
-	$p->descr = [
755
-		'sourcefile' => $context_compil[0] ?? '',
756
-		'nom' => $context_compil[1] ?? '',
757
-	];
758
-
759
-	$p->id_boucle = $context_compil[2] ?? '';
760
-	$p->ligne = (int)($context_compil[3] ?? 0);
761
-	$p->lang = $context_compil[4] ?? '';
762
-
763
-	return $p;
750
+    if (!is_array($context_compil)) {
751
+        return $context_compil;
752
+    }
753
+    $p = new Contexte();
754
+    $p->descr = [
755
+        'sourcefile' => $context_compil[0] ?? '',
756
+        'nom' => $context_compil[1] ?? '',
757
+    ];
758
+
759
+    $p->id_boucle = $context_compil[2] ?? '';
760
+    $p->ligne = (int)($context_compil[3] ?? 0);
761
+    $p->lang = $context_compil[4] ?? '';
762
+
763
+    return $p;
764 764
 }
765 765
 
766 766
 /**
@@ -786,12 +786,12 @@  discard block
 block discarded – undo
786 786
  *    - index 1 : Code de l'affectation
787 787
  **/
788 788
 function calculer_dec($nom, $val) {
789
-	$static = 'if (!isset($command[\'' . $nom . '\'])) ';
790
-	// si une variable apparait dans le calcul de la clause
791
-	// il faut la re-evaluer a chaque passage
792
-	if (
793
-		str_contains($val, '$')
794
-		/*
789
+    $static = 'if (!isset($command[\'' . $nom . '\'])) ';
790
+    // si une variable apparait dans le calcul de la clause
791
+    // il faut la re-evaluer a chaque passage
792
+    if (
793
+        str_contains($val, '$')
794
+        /*
795 795
 		OR str_contains($val, 'sql_')
796 796
 		OR (
797 797
 			$test = str_replace(array("array(",'\"',"\'"),array("","",""),$val) // supprimer les array( et les echappements de guillemets
@@ -799,11 +799,11 @@  discard block
 block discarded – undo
799 799
 			AND $test = preg_replace(",'[^']*',UimsS","",$test) // supprimer les chaines qui peuvent contenir des fonctions SQL qui ne genent pas
800 800
 			AND preg_match(",\w+\s*\(,UimsS",$test,$regs) // tester la presence de fonctions restantes
801 801
 		)*/
802
-	) {
803
-		$static = '';
804
-	}
802
+    ) {
803
+        $static = '';
804
+    }
805 805
 
806
-	return [$static, '$command[\'' . $nom . '\'] = ' . $val . ';'];
806
+    return [$static, '$command[\'' . $nom . '\'] = ' . $val . ';'];
807 807
 }
808 808
 
809 809
 /**
@@ -823,32 +823,32 @@  discard block
 block discarded – undo
823 823
  *     Expression PHP décrivant un texte ou un tableau
824 824
  **/
825 825
 function calculer_dump_array($a) {
826
-	if (!is_array($a)) {
827
-		return $a;
828
-	}
829
-	$res = '';
830
-	if ($a && $a[0] == "'?'") {
831
-		return ('(' . calculer_dump_array($a[1]) .
832
-			' ? ' . calculer_dump_array($a[2]) .
833
-			' : ' . calculer_dump_array($a[3]) .
834
-			')');
835
-	} else {
836
-		foreach ($a as $k => $v) {
837
-			$showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
838
-			$res .= ', ' . $showk . calculer_dump_array($v);
839
-		}
840
-
841
-		return "\n\t\t\tarray(" . substr($res, 2) . ')';
842
-	}
826
+    if (!is_array($a)) {
827
+        return $a;
828
+    }
829
+    $res = '';
830
+    if ($a && $a[0] == "'?'") {
831
+        return ('(' . calculer_dump_array($a[1]) .
832
+            ' ? ' . calculer_dump_array($a[2]) .
833
+            ' : ' . calculer_dump_array($a[3]) .
834
+            ')');
835
+    } else {
836
+        foreach ($a as $k => $v) {
837
+            $showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
838
+            $res .= ', ' . $showk . calculer_dump_array($v);
839
+        }
840
+
841
+        return "\n\t\t\tarray(" . substr($res, 2) . ')';
842
+    }
843 843
 }
844 844
 
845 845
 function calculer_dump_join($a) {
846
-	$res = '';
847
-	foreach ($a as $k => $v) {
848
-		$res .= ", '$k' => array(" . implode(',', $v) . ')';
849
-	}
846
+    $res = '';
847
+    foreach ($a as $k => $v) {
848
+        $res .= ", '$k' => array(" . implode(',', $v) . ')';
849
+    }
850 850
 
851
-	return 'array(' . substr($res, 2) . ')';
851
+    return 'array(' . substr($res, 2) . ')';
852 852
 }
853 853
 
854 854
 /**
@@ -860,12 +860,12 @@  discard block
 block discarded – undo
860 860
  *     Code PHP construisant un tableau des alias et noms des tables du FROM
861 861
  **/
862 862
 function calculer_from(&$boucle) {
863
-	$res = '';
864
-	foreach ($boucle->from as $k => $v) {
865
-		$res .= ",'$k' => '$v'";
866
-	}
863
+    $res = '';
864
+    foreach ($boucle->from as $k => $v) {
865
+        $res .= ",'$k' => '$v'";
866
+    }
867 867
 
868
-	return 'array(' . substr($res, 1) . ')';
868
+    return 'array(' . substr($res, 1) . ')';
869 869
 }
870 870
 
871 871
 /**
@@ -878,30 +878,30 @@  discard block
 block discarded – undo
878 878
  *     Code PHP construisant un tableau des alias et type de jointure du FROM
879 879
  **/
880 880
 function calculer_from_type(&$boucle) {
881
-	$res = '';
882
-	foreach ($boucle->from_type as $k => $v) {
883
-		$res .= ",'$k' => '$v'";
884
-	}
881
+    $res = '';
882
+    foreach ($boucle->from_type as $k => $v) {
883
+        $res .= ",'$k' => '$v'";
884
+    }
885 885
 
886
-	return 'array(' . substr($res, 1) . ')';
886
+    return 'array(' . substr($res, 1) . ')';
887 887
 }
888 888
 
889 889
 function calculer_order(&$boucle) {
890
-	if (
891
-		!($order = $boucle->order)
892
-		&& !($order = $boucle->default_order)
893
-	) {
894
-		$order = [];
895
-	}
896
-
897
-	/*if (isset($boucle->modificateur['collate'])){
890
+    if (
891
+        !($order = $boucle->order)
892
+        && !($order = $boucle->default_order)
893
+    ) {
894
+        $order = [];
895
+    }
896
+
897
+    /*if (isset($boucle->modificateur['collate'])){
898 898
 		$col = "." . $boucle->modificateur['collate'];
899 899
 		foreach($order as $k=>$o)
900 900
 			if (strpos($order[$k],'COLLATE')===false)
901 901
 				$order[$k].= $col;
902 902
 	}*/
903 903
 
904
-	return join(', ', $order);
904
+    return join(', ', $order);
905 905
 }
906 906
 
907 907
 // Production du code PHP a partir de la sequence livree par le phraseur
@@ -910,62 +910,62 @@  discard block
 block discarded – undo
910 910
 // (qui sera argument d'un Return ou la partie droite d'une affectation).
911 911
 
912 912
 function calculer_liste($tableau, $descr, &$boucles, $id_boucle = '') {
913
-	if (!$tableau) {
914
-		return "''";
915
-	}
916
-	if (is_string($descr)) {
917
-		if (isset($boucles[$descr])) {
918
-			$idb = $descr;
919
-			$descr = [];
920
-			if (isset($boucles[$idb]->descr['id_mere_contexte'])) {
921
-				$descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte'];
922
-			}
923
-			if (isset($boucles[$idb]->descr['sourcefile'])) {
924
-				$descr['sourcefile'] = $boucles[$idb]->descr['sourcefile'];
925
-			}
926
-		}
927
-		else {
928
-			$descr = [];
929
-		}
930
-	}
931
-	if (!isset($descr['niv'])) {
932
-		$descr['niv'] = 0;
933
-	}
934
-	$codes = compile_cas($tableau, $descr, $boucles, $id_boucle);
935
-	if ($codes === false) {
936
-		return false;
937
-	}
938
-	$n = is_countable($codes) ? count($codes) : 0;
939
-	if (!$n) {
940
-		return "''";
941
-	}
942
-	$tab = str_repeat("\t", $descr['niv']);
943
-	if (_request('var_mode_affiche') != 'validation') {
944
-		if ($n == 1) {
945
-			return $codes[0];
946
-		} else {
947
-			$res = '';
948
-			foreach ($codes as $code) {
949
-				if (
950
-					!preg_match("/^'[^']*'$/", $code)
951
-					|| !str_ends_with($res, "'")
952
-				) {
953
-					$res .= " .\n$tab$code";
954
-				} else {
955
-					$res = substr($res, 0, -1) . substr($code, 1);
956
-				}
957
-			}
958
-
959
-			return '(' . substr($res, 2 + $descr['niv']) . ')';
960
-		}
961
-	} else {
962
-		$nom = $descr['nom'] . $id_boucle . ($descr['niv'] ?: '');
963
-
964
-		return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(
965
-			" ,\n$tab",
966
-			$codes
967
-		) . ')))';
968
-	}
913
+    if (!$tableau) {
914
+        return "''";
915
+    }
916
+    if (is_string($descr)) {
917
+        if (isset($boucles[$descr])) {
918
+            $idb = $descr;
919
+            $descr = [];
920
+            if (isset($boucles[$idb]->descr['id_mere_contexte'])) {
921
+                $descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte'];
922
+            }
923
+            if (isset($boucles[$idb]->descr['sourcefile'])) {
924
+                $descr['sourcefile'] = $boucles[$idb]->descr['sourcefile'];
925
+            }
926
+        }
927
+        else {
928
+            $descr = [];
929
+        }
930
+    }
931
+    if (!isset($descr['niv'])) {
932
+        $descr['niv'] = 0;
933
+    }
934
+    $codes = compile_cas($tableau, $descr, $boucles, $id_boucle);
935
+    if ($codes === false) {
936
+        return false;
937
+    }
938
+    $n = is_countable($codes) ? count($codes) : 0;
939
+    if (!$n) {
940
+        return "''";
941
+    }
942
+    $tab = str_repeat("\t", $descr['niv']);
943
+    if (_request('var_mode_affiche') != 'validation') {
944
+        if ($n == 1) {
945
+            return $codes[0];
946
+        } else {
947
+            $res = '';
948
+            foreach ($codes as $code) {
949
+                if (
950
+                    !preg_match("/^'[^']*'$/", $code)
951
+                    || !str_ends_with($res, "'")
952
+                ) {
953
+                    $res .= " .\n$tab$code";
954
+                } else {
955
+                    $res = substr($res, 0, -1) . substr($code, 1);
956
+                }
957
+            }
958
+
959
+            return '(' . substr($res, 2 + $descr['niv']) . ')';
960
+        }
961
+    } else {
962
+        $nom = $descr['nom'] . $id_boucle . ($descr['niv'] ?: '');
963
+
964
+        return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(
965
+            " ,\n$tab",
966
+            $codes
967
+        ) . ')))';
968
+    }
969 969
 }
970 970
 
971 971
 
@@ -984,212 +984,212 @@  discard block
 block discarded – undo
984 984
  */
985 985
 function compile_cas($tableau, $descr, &$boucles, $id_boucle) {
986 986
 
987
-	$codes = [];
988
-	// cas de la boucle recursive
989
-	if (is_array($id_boucle)) {
990
-		$id_boucle = $id_boucle[0];
991
-	}
992
-	$type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete;
993
-	$tab = str_repeat("\t", ++$descr['niv']);
994
-	$mode = _request('var_mode_affiche');
995
-	$err_e_c = '';
996
-	// chaque commentaire introduit dans le code doit commencer
997
-	// par un caractere distinguant le cas, pour exploitation par debug.
998
-	foreach ($tableau as $p) {
999
-		switch ($p->type) {
1000
-			// texte seul
1001
-			case 'texte':
1002
-				$code = sandbox_composer_texte($p->texte, $p);
1003
-				$commentaire = strlen($p->texte) . ' signes';
1004
-				$avant = '';
1005
-				$apres = '';
1006
-				$altern = "''";
1007
-				break;
1008
-
1009
-			case 'polyglotte':
1010
-				$code = '';
1011
-				foreach ($p->traductions as $k => $v) {
1012
-					$code .= ",'" .
1013
-						str_replace(['\\', "'"], ['\\\\', "\\'"], $k) .
1014
-						"' => '" .
1015
-						str_replace(['\\', "'"], ['\\\\', "\\'"], $v) .
1016
-						"'";
1017
-				}
1018
-				$code = 'choisir_traduction(array(' .
1019
-					substr($code, 1) .
1020
-					'))';
1021
-				$commentaire = '&';
1022
-				$avant = '';
1023
-				$apres = '';
1024
-				$altern = "''";
1025
-				break;
1026
-
1027
-			// inclure
1028
-			case 'include':
1029
-				$p->descr = $descr;
1030
-				$code = calculer_inclure($p, $boucles, $id_boucle);
1031
-				if ($code === false) {
1032
-					$err_e_c = true;
1033
-					$code = "''";
1034
-				} else {
1035
-					$commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1036
-					$avant = '';
1037
-					$apres = '';
1038
-					$altern = "''";
1039
-				}
1040
-				break;
1041
-
1042
-			// boucle
1043
-			case TYPE_RECURSIF:
1044
-				$nom = $p->id_boucle;
1045
-				$newdescr = $descr;
1046
-				$newdescr['id_mere'] = $nom;
1047
-				$newdescr['niv']++;
1048
-				$preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle);
1049
-				$avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle);
1050
-				$apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle);
1051
-				$postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle);
1052
-				$newdescr['niv']--;
1053
-				$altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle);
1054
-				if (
1055
-					$preaff === false
1056
-					|| $avant === false
1057
-					|| $apres === false
1058
-					|| $altern === false
1059
-					|| $postaff === false
1060
-				) {
1061
-					$err_e_c = true;
1062
-					$code = "''";
1063
-				} else {
1064
-					$code = 'BOUCLE' .
1065
-						str_replace('-', '_', $nom) . $descr['nom'] .
1066
-						'($Cache, $Pile, $doublons, $Numrows, $SP)';
1067
-					$commentaire = "?$nom";
1068
-					if (
1069
-						!$boucles[$nom]->milieu
1070
-						&& $boucles[$nom]->type_requete <> TYPE_RECURSIF
1071
-					) {
1072
-						if ($preaff != "''") {
1073
-							$code .= "\n. $preaff";
1074
-						}
1075
-						if ($altern != "''") {
1076
-							$code .= "\n. $altern";
1077
-						}
1078
-						if ($postaff != "''") {
1079
-							$code .= "\n. $postaff";
1080
-						}
1081
-						if ($avant <> "''" || $apres <> "''") {
1082
-							spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]");
1083
-						}
1084
-						$avant = $apres = $altern = "''";
1085
-					} else {
1086
-						if ($preaff != "''") {
1087
-							$avant = compile_concatene_parties_codes($preaff, $avant);
1088
-							$altern = compile_concatene_parties_codes($preaff, $altern);
1089
-						}
1090
-						if ($postaff != "''") {
1091
-							$apres = compile_concatene_parties_codes($apres, $postaff);
1092
-							$altern = compile_concatene_parties_codes($altern, $postaff);
1093
-						}
1094
-						if ($altern != "''") {
1095
-							$altern = "($altern)";
1096
-						}
1097
-					}
1098
-				}
1099
-				break;
1100
-
1101
-			case 'idiome':
1102
-				$l = [];
1103
-				$code = '';
1104
-				foreach ($p->arg as $k => $v) {
1105
-					$_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1106
-					if ($k) {
1107
-						$l[] = _q($k) . ' => ' . $_v;
1108
-					} else {
1109
-						$code = $_v;
1110
-					}
1111
-				}
1112
-				// Si le module n'est pas fourni, l'expliciter sauf si calculé
1113
-				if ($p->module) {
1114
-					$m = $p->module . ':' . $p->nom_champ;
1115
-				} elseif ($p->nom_champ) {
1116
-					$m = MODULES_IDIOMES . ':' . $p->nom_champ;
1117
-				} else {
1118
-					$m = '';
1119
-				}
1120
-
1121
-				$code = (!$code ? "'$m'" :
1122
-						($m ? "'$m' . $code" :
1123
-							("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1124
-					. (!$l ? '' : (', array(' . implode(",\n", $l) . ')'));
1125
-				$code = "_T($code)";
1126
-				if ($p->param) {
1127
-					$p->id_boucle = $id_boucle;
1128
-					$p->boucles = &$boucles;
1129
-					$code = compose_filtres($p, $code);
1130
-				}
1131
-				$commentaire = ':';
1132
-				$avant = '';
1133
-				$apres = '';
1134
-				$altern = "''";
1135
-				break;
1136
-
1137
-			case 'champ':
1138
-				// cette structure pourrait etre completee des le phrase' (a faire)
1139
-				$p->id_boucle = $id_boucle;
1140
-				$p->boucles = &$boucles;
1141
-				$p->descr = $descr;
1142
-				#$p->interdire_scripts = true;
1143
-				$p->type_requete = $type;
1144
-
1145
-				$code = calculer_champ($p);
1146
-				$commentaire = '#' . $p->nom_champ . $p->etoile;
1147
-				$avant = calculer_liste(
1148
-					$p->avant,
1149
-					$descr,
1150
-					$boucles,
1151
-					$id_boucle
1152
-				);
1153
-				$apres = calculer_liste(
1154
-					$p->apres,
1155
-					$descr,
1156
-					$boucles,
1157
-					$id_boucle
1158
-				);
1159
-				$altern = "''";
1160
-				// Si la valeur est destinee a une comparaison a ''
1161
-				// forcer la conversion en une chaine par strval
1162
-				// si ca peut etre autre chose qu'une chaine
1163
-				if (
1164
-					($avant != "''" || $apres != "''")
1165
-					&& $code[0] != "'"
1166
-					&& !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code)
1167
-					&& !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code)
1168
-					&& !preg_match(_REGEXP_CONCAT_NON_VIDE, $code)
1169
-				) {
1170
-					$code = "strval($code)";
1171
-				}
1172
-				break;
1173
-
1174
-			default:
1175
-				// Erreur de construction de l'arbre de syntaxe abstraite
1176
-				$code = "''";
1177
-				$p->descr = $descr;
1178
-				$err_e_c = _T('zbug_erreur_compilation');
1179
-				erreur_squelette($err_e_c, $p);
1180
-		} // switch
1181
-
1182
-		if ($code != "''") {
1183
-			$code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1184
-			$codes[] = (($mode == 'validation') ?
1185
-				"array($code, '$commentaire', " . $p->ligne . ')'
1186
-				: (($mode == 'code') ?
1187
-					"\n// $commentaire\n$code" :
1188
-					$code));
1189
-		}
1190
-	} // foreach
1191
-
1192
-	return $err_e_c ? false : $codes;
987
+    $codes = [];
988
+    // cas de la boucle recursive
989
+    if (is_array($id_boucle)) {
990
+        $id_boucle = $id_boucle[0];
991
+    }
992
+    $type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete;
993
+    $tab = str_repeat("\t", ++$descr['niv']);
994
+    $mode = _request('var_mode_affiche');
995
+    $err_e_c = '';
996
+    // chaque commentaire introduit dans le code doit commencer
997
+    // par un caractere distinguant le cas, pour exploitation par debug.
998
+    foreach ($tableau as $p) {
999
+        switch ($p->type) {
1000
+            // texte seul
1001
+            case 'texte':
1002
+                $code = sandbox_composer_texte($p->texte, $p);
1003
+                $commentaire = strlen($p->texte) . ' signes';
1004
+                $avant = '';
1005
+                $apres = '';
1006
+                $altern = "''";
1007
+                break;
1008
+
1009
+            case 'polyglotte':
1010
+                $code = '';
1011
+                foreach ($p->traductions as $k => $v) {
1012
+                    $code .= ",'" .
1013
+                        str_replace(['\\', "'"], ['\\\\', "\\'"], $k) .
1014
+                        "' => '" .
1015
+                        str_replace(['\\', "'"], ['\\\\', "\\'"], $v) .
1016
+                        "'";
1017
+                }
1018
+                $code = 'choisir_traduction(array(' .
1019
+                    substr($code, 1) .
1020
+                    '))';
1021
+                $commentaire = '&';
1022
+                $avant = '';
1023
+                $apres = '';
1024
+                $altern = "''";
1025
+                break;
1026
+
1027
+            // inclure
1028
+            case 'include':
1029
+                $p->descr = $descr;
1030
+                $code = calculer_inclure($p, $boucles, $id_boucle);
1031
+                if ($code === false) {
1032
+                    $err_e_c = true;
1033
+                    $code = "''";
1034
+                } else {
1035
+                    $commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1036
+                    $avant = '';
1037
+                    $apres = '';
1038
+                    $altern = "''";
1039
+                }
1040
+                break;
1041
+
1042
+            // boucle
1043
+            case TYPE_RECURSIF:
1044
+                $nom = $p->id_boucle;
1045
+                $newdescr = $descr;
1046
+                $newdescr['id_mere'] = $nom;
1047
+                $newdescr['niv']++;
1048
+                $preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle);
1049
+                $avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle);
1050
+                $apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle);
1051
+                $postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle);
1052
+                $newdescr['niv']--;
1053
+                $altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle);
1054
+                if (
1055
+                    $preaff === false
1056
+                    || $avant === false
1057
+                    || $apres === false
1058
+                    || $altern === false
1059
+                    || $postaff === false
1060
+                ) {
1061
+                    $err_e_c = true;
1062
+                    $code = "''";
1063
+                } else {
1064
+                    $code = 'BOUCLE' .
1065
+                        str_replace('-', '_', $nom) . $descr['nom'] .
1066
+                        '($Cache, $Pile, $doublons, $Numrows, $SP)';
1067
+                    $commentaire = "?$nom";
1068
+                    if (
1069
+                        !$boucles[$nom]->milieu
1070
+                        && $boucles[$nom]->type_requete <> TYPE_RECURSIF
1071
+                    ) {
1072
+                        if ($preaff != "''") {
1073
+                            $code .= "\n. $preaff";
1074
+                        }
1075
+                        if ($altern != "''") {
1076
+                            $code .= "\n. $altern";
1077
+                        }
1078
+                        if ($postaff != "''") {
1079
+                            $code .= "\n. $postaff";
1080
+                        }
1081
+                        if ($avant <> "''" || $apres <> "''") {
1082
+                            spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]");
1083
+                        }
1084
+                        $avant = $apres = $altern = "''";
1085
+                    } else {
1086
+                        if ($preaff != "''") {
1087
+                            $avant = compile_concatene_parties_codes($preaff, $avant);
1088
+                            $altern = compile_concatene_parties_codes($preaff, $altern);
1089
+                        }
1090
+                        if ($postaff != "''") {
1091
+                            $apres = compile_concatene_parties_codes($apres, $postaff);
1092
+                            $altern = compile_concatene_parties_codes($altern, $postaff);
1093
+                        }
1094
+                        if ($altern != "''") {
1095
+                            $altern = "($altern)";
1096
+                        }
1097
+                    }
1098
+                }
1099
+                break;
1100
+
1101
+            case 'idiome':
1102
+                $l = [];
1103
+                $code = '';
1104
+                foreach ($p->arg as $k => $v) {
1105
+                    $_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1106
+                    if ($k) {
1107
+                        $l[] = _q($k) . ' => ' . $_v;
1108
+                    } else {
1109
+                        $code = $_v;
1110
+                    }
1111
+                }
1112
+                // Si le module n'est pas fourni, l'expliciter sauf si calculé
1113
+                if ($p->module) {
1114
+                    $m = $p->module . ':' . $p->nom_champ;
1115
+                } elseif ($p->nom_champ) {
1116
+                    $m = MODULES_IDIOMES . ':' . $p->nom_champ;
1117
+                } else {
1118
+                    $m = '';
1119
+                }
1120
+
1121
+                $code = (!$code ? "'$m'" :
1122
+                        ($m ? "'$m' . $code" :
1123
+                            ("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1124
+                    . (!$l ? '' : (', array(' . implode(",\n", $l) . ')'));
1125
+                $code = "_T($code)";
1126
+                if ($p->param) {
1127
+                    $p->id_boucle = $id_boucle;
1128
+                    $p->boucles = &$boucles;
1129
+                    $code = compose_filtres($p, $code);
1130
+                }
1131
+                $commentaire = ':';
1132
+                $avant = '';
1133
+                $apres = '';
1134
+                $altern = "''";
1135
+                break;
1136
+
1137
+            case 'champ':
1138
+                // cette structure pourrait etre completee des le phrase' (a faire)
1139
+                $p->id_boucle = $id_boucle;
1140
+                $p->boucles = &$boucles;
1141
+                $p->descr = $descr;
1142
+                #$p->interdire_scripts = true;
1143
+                $p->type_requete = $type;
1144
+
1145
+                $code = calculer_champ($p);
1146
+                $commentaire = '#' . $p->nom_champ . $p->etoile;
1147
+                $avant = calculer_liste(
1148
+                    $p->avant,
1149
+                    $descr,
1150
+                    $boucles,
1151
+                    $id_boucle
1152
+                );
1153
+                $apres = calculer_liste(
1154
+                    $p->apres,
1155
+                    $descr,
1156
+                    $boucles,
1157
+                    $id_boucle
1158
+                );
1159
+                $altern = "''";
1160
+                // Si la valeur est destinee a une comparaison a ''
1161
+                // forcer la conversion en une chaine par strval
1162
+                // si ca peut etre autre chose qu'une chaine
1163
+                if (
1164
+                    ($avant != "''" || $apres != "''")
1165
+                    && $code[0] != "'"
1166
+                    && !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code)
1167
+                    && !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code)
1168
+                    && !preg_match(_REGEXP_CONCAT_NON_VIDE, $code)
1169
+                ) {
1170
+                    $code = "strval($code)";
1171
+                }
1172
+                break;
1173
+
1174
+            default:
1175
+                // Erreur de construction de l'arbre de syntaxe abstraite
1176
+                $code = "''";
1177
+                $p->descr = $descr;
1178
+                $err_e_c = _T('zbug_erreur_compilation');
1179
+                erreur_squelette($err_e_c, $p);
1180
+        } // switch
1181
+
1182
+        if ($code != "''") {
1183
+            $code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1184
+            $codes[] = (($mode == 'validation') ?
1185
+                "array($code, '$commentaire', " . $p->ligne . ')'
1186
+                : (($mode == 'code') ?
1187
+                    "\n// $commentaire\n$code" :
1188
+                    $code));
1189
+        }
1190
+    } // foreach
1191
+
1192
+    return $err_e_c ? false : $codes;
1193 1193
 }
1194 1194
 
1195 1195
 /**
@@ -1199,13 +1199,13 @@  discard block
 block discarded – undo
1199 1199
  * @return string
1200 1200
  */
1201 1201
 function compile_concatene_parties_codes($partie1, $partie2) {
1202
-	if ($partie1 === "''") {
1203
-		return $partie2;
1204
-	}
1205
-	if ($partie2 === "''") {
1206
-		return $partie1;
1207
-	}
1208
-	return "$partie1\n. $partie2";
1202
+    if ($partie1 === "''") {
1203
+        return $partie2;
1204
+    }
1205
+    if ($partie2 === "''") {
1206
+        return $partie1;
1207
+    }
1208
+    return "$partie1\n. $partie2";
1209 1209
 }
1210 1210
 
1211 1211
 
@@ -1229,56 +1229,56 @@  discard block
 block discarded – undo
1229 1229
  * @return mixed|string
1230 1230
  */
1231 1231
 function compile_retour($code, $avant, $apres, $altern, $tab, $n) {
1232
-	if ($avant === "''") {
1233
-		$avant = '';
1234
-	}
1235
-	if ($apres === "''") {
1236
-		$apres = '';
1237
-	}
1238
-	if ($avant || $apres || $altern !== "''") {
1239
-		if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)) {
1240
-			$t = $code;
1241
-			$cond = '';
1242
-		} elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1243
-			$t = $r[2];
1244
-			$cond = '!' . $r[1];
1245
-		} else {
1246
-			if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) {
1247
-				$t = $r[2];
1248
-				$cond = $r[1];
1249
-			} else {
1250
-				$t = '$t' . $n;
1251
-				$cond = "($t = $code)!==''";
1252
-			}
1253
-		}
1254
-
1255
-		$res = (!$avant ? '' : "$avant . ") .
1256
-			$t .
1257
-			(!$apres ? '' : " . $apres");
1258
-
1259
-		if ($res !== $t) {
1260
-			$res = "($res)";
1261
-		}
1262
-
1263
-		$code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)");
1264
-	}
1265
-
1266
-	return $code;
1232
+    if ($avant === "''") {
1233
+        $avant = '';
1234
+    }
1235
+    if ($apres === "''") {
1236
+        $apres = '';
1237
+    }
1238
+    if ($avant || $apres || $altern !== "''") {
1239
+        if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)) {
1240
+            $t = $code;
1241
+            $cond = '';
1242
+        } elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1243
+            $t = $r[2];
1244
+            $cond = '!' . $r[1];
1245
+        } else {
1246
+            if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) {
1247
+                $t = $r[2];
1248
+                $cond = $r[1];
1249
+            } else {
1250
+                $t = '$t' . $n;
1251
+                $cond = "($t = $code)!==''";
1252
+            }
1253
+        }
1254
+
1255
+        $res = (!$avant ? '' : "$avant . ") .
1256
+            $t .
1257
+            (!$apres ? '' : " . $apres");
1258
+
1259
+        if ($res !== $t) {
1260
+            $res = "($res)";
1261
+        }
1262
+
1263
+        $code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)");
1264
+    }
1265
+
1266
+    return $code;
1267 1267
 }
1268 1268
 
1269 1269
 
1270 1270
 function compile_inclure_doublons($lexemes) {
1271
-	foreach ($lexemes as $v) {
1272
-		if ($v->type === 'include' && $v->param) {
1273
-			foreach ($v->param as $r) {
1274
-				if (trim($r[0]) === 'doublons') {
1275
-					return true;
1276
-				}
1277
-			}
1278
-		}
1279
-	}
1280
-
1281
-	return false;
1271
+    foreach ($lexemes as $v) {
1272
+        if ($v->type === 'include' && $v->param) {
1273
+            foreach ($v->param as $r) {
1274
+                if (trim($r[0]) === 'doublons') {
1275
+                    return true;
1276
+                }
1277
+            }
1278
+        }
1279
+    }
1280
+
1281
+    return false;
1282 1282
 }
1283 1283
 
1284 1284
 // Prend en argument le texte d'un squelette, le nom de son fichier d'origine,
@@ -1297,355 +1297,355 @@  discard block
 block discarded – undo
1297 1297
 // En cas d'erreur, elle retournera un tableau des 2 premiers elements seulement
1298 1298
 
1299 1299
 function public_compiler_dist($squelette, $nom, $gram, $sourcefile, string $connect = '') {
1300
-	// Pre-traitement : reperer le charset du squelette, et le convertir
1301
-	// Bonus : supprime le BOM
1302
-	include_spip('inc/charsets');
1303
-	$squelette = transcoder_page($squelette);
1304
-
1305
-	// rendre inertes les echappements de #[](){}<>
1306
-	$i = 0;
1307
-	while (str_contains($squelette, $inerte = '-INERTE' . $i)) {
1308
-		$i++;
1309
-	}
1310
-	$squelette = preg_replace_callback(
1311
-		',\\\\([#[()\]{}<>]),',
1312
-		fn($a) => "$inerte-" . ord($a[1]) . '-',
1313
-		$squelette,
1314
-		-1,
1315
-		$esc
1316
-	);
1317
-
1318
-	$descr = [
1319
-		'nom' => $nom,
1320
-		'gram' => $gram,
1321
-		'sourcefile' => $sourcefile,
1322
-		'squelette' => $squelette
1323
-	];
1324
-
1325
-	// Phraser le squelette, selon sa grammaire
1326
-
1327
-	$boucles = [];
1328
-	$f = charger_fonction('phraser_' . $gram, 'public');
1329
-
1330
-	$squelette = $f($squelette, '', $boucles, $descr);
1331
-
1332
-	$boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect);
1333
-
1334
-	// restituer les echappements
1335
-	if ($esc) {
1336
-		foreach ($boucles as $i => $boucle) {
1337
-			$boucles[$i]->return = preg_replace_callback(
1338
-				",$inerte-(\d+)-,",
1339
-				fn ($a) => chr((int) $a[1]),
1340
-				$boucle->return
1341
-			);
1342
-			$boucles[$i]->descr['squelette'] = preg_replace_callback(
1343
-				",$inerte-(\d+)-,",
1344
-				fn ($a) => '\\\\' . chr($a[1]),
1345
-				$boucle->descr['squelette']
1346
-			);
1347
-		}
1348
-	}
1349
-
1350
-	$debug = ($boucles && defined('_VAR_MODE') && _VAR_MODE == 'debug');
1351
-	if ($debug) {
1352
-		include_spip('public/decompiler');
1353
-		foreach ($boucles as $id => $boucle) {
1354
-			if ($id) {
1355
-				$decomp = "\n/* BOUCLE " .
1356
-					$boucle->type_requete .
1357
-					' ' .
1358
-					str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1359
-					($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1360
-					" */\n";
1361
-			} else {
1362
-				$decomp = ("\n/*\n" .
1363
-					str_replace('*/', '* /', public_decompiler($squelette, $gram))
1364
-					. "\n*/");
1365
-			}
1366
-			$boucles[$id]->return = $decomp . $boucle->return;
1367
-			$GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1368
-		}
1369
-	}
1370
-
1371
-	return $boucles;
1300
+    // Pre-traitement : reperer le charset du squelette, et le convertir
1301
+    // Bonus : supprime le BOM
1302
+    include_spip('inc/charsets');
1303
+    $squelette = transcoder_page($squelette);
1304
+
1305
+    // rendre inertes les echappements de #[](){}<>
1306
+    $i = 0;
1307
+    while (str_contains($squelette, $inerte = '-INERTE' . $i)) {
1308
+        $i++;
1309
+    }
1310
+    $squelette = preg_replace_callback(
1311
+        ',\\\\([#[()\]{}<>]),',
1312
+        fn($a) => "$inerte-" . ord($a[1]) . '-',
1313
+        $squelette,
1314
+        -1,
1315
+        $esc
1316
+    );
1317
+
1318
+    $descr = [
1319
+        'nom' => $nom,
1320
+        'gram' => $gram,
1321
+        'sourcefile' => $sourcefile,
1322
+        'squelette' => $squelette
1323
+    ];
1324
+
1325
+    // Phraser le squelette, selon sa grammaire
1326
+
1327
+    $boucles = [];
1328
+    $f = charger_fonction('phraser_' . $gram, 'public');
1329
+
1330
+    $squelette = $f($squelette, '', $boucles, $descr);
1331
+
1332
+    $boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect);
1333
+
1334
+    // restituer les echappements
1335
+    if ($esc) {
1336
+        foreach ($boucles as $i => $boucle) {
1337
+            $boucles[$i]->return = preg_replace_callback(
1338
+                ",$inerte-(\d+)-,",
1339
+                fn ($a) => chr((int) $a[1]),
1340
+                $boucle->return
1341
+            );
1342
+            $boucles[$i]->descr['squelette'] = preg_replace_callback(
1343
+                ",$inerte-(\d+)-,",
1344
+                fn ($a) => '\\\\' . chr($a[1]),
1345
+                $boucle->descr['squelette']
1346
+            );
1347
+        }
1348
+    }
1349
+
1350
+    $debug = ($boucles && defined('_VAR_MODE') && _VAR_MODE == 'debug');
1351
+    if ($debug) {
1352
+        include_spip('public/decompiler');
1353
+        foreach ($boucles as $id => $boucle) {
1354
+            if ($id) {
1355
+                $decomp = "\n/* BOUCLE " .
1356
+                    $boucle->type_requete .
1357
+                    ' ' .
1358
+                    str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1359
+                    ($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1360
+                    " */\n";
1361
+            } else {
1362
+                $decomp = ("\n/*\n" .
1363
+                    str_replace('*/', '* /', public_decompiler($squelette, $gram))
1364
+                    . "\n*/");
1365
+            }
1366
+            $boucles[$id]->return = $decomp . $boucle->return;
1367
+            $GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1368
+        }
1369
+    }
1370
+
1371
+    return $boucles;
1372 1372
 }
1373 1373
 
1374 1374
 // Point d'entree pour arbre de syntaxe abstraite fourni en premier argument
1375 1375
 // Autres specifications comme ci-dessus
1376 1376
 
1377 1377
 function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, string $connect = '') {
1378
-	static $trouver_table;
1379
-	spip_timer('calcul_skel');
1380
-
1381
-	if (defined('_VAR_MODE') && _VAR_MODE == 'debug') {
1382
-		$GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
1383
-		$GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;
1384
-
1385
-		if (!isset($GLOBALS['debug_objets']['principal'])) {
1386
-			$GLOBALS['debug_objets']['principal'] = $nom;
1387
-		}
1388
-	}
1389
-	foreach ($boucles as $id => $boucle) {
1390
-		$GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1391
-	}
1392
-	$descr['documents'] = compile_inclure_doublons($squelette);
1393
-
1394
-	// Demander la description des tables une fois pour toutes
1395
-	if (!$trouver_table) {
1396
-		$trouver_table = charger_fonction('trouver_table', 'base');
1397
-	}
1398
-
1399
-	// reperer si les doublons sont demandes
1400
-	// pour un inclure ou une boucle document
1401
-	// c'est utile a la fonction champs_traitements
1402
-	foreach ($boucles as $id => $boucle) {
1403
-		if (!($type = $boucle->type_requete)) {
1404
-			continue;
1405
-		}
1406
-		if (
1407
-			!$descr['documents']
1408
-			&& (
1409
-				$type == 'documents' && $boucle->doublons
1410
-				|| compile_inclure_doublons($boucle->avant)
1411
-				|| compile_inclure_doublons($boucle->apres)
1412
-				|| compile_inclure_doublons($boucle->milieu)
1413
-				|| compile_inclure_doublons($boucle->altern)
1414
-			)
1415
-		) {
1416
-			$descr['documents'] = true;
1417
-		}
1418
-		if ($type != TYPE_RECURSIF) {
1419
-			if (!$boucles[$id]->sql_serveur && $connect) {
1420
-				$boucles[$id]->sql_serveur = $connect;
1421
-			}
1422
-
1423
-			// chercher dans les iterateurs du repertoire iterateur/
1424
-			if (
1425
-				$g = charger_fonction(
1426
-					preg_replace('/\W/', '_', $boucle->type_requete),
1427
-					'iterateur',
1428
-					true
1429
-				)
1430
-			) {
1431
-				$boucles[$id] = $g($boucle);
1432
-
1433
-				// sinon, en cas de requeteur d'un type predefini,
1434
-				// utiliser les informations donnees par le requeteur
1435
-				// cas "php:xx" et "data:xx".
1436
-			} else {
1437
-				if ($boucle->sql_serveur && ($requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true))) {
1438
-					$requeteur($boucles, $boucle, $id);
1439
-
1440
-					// utiliser la description des champs transmis
1441
-				} else {
1442
-					$show = $trouver_table($type, $boucles[$id]->sql_serveur);
1443
-					// si la table n'existe pas avec le connecteur par defaut,
1444
-					// c'est peut etre une table qui necessite son connecteur dedie fourni
1445
-					// permet une ecriture allegee (GEO) -> (geo:GEO)
1446
-					if (
1447
-						!$show
1448
-						&& ($show = $trouver_table($type, strtolower($type)))
1449
-					) {
1450
-						$boucles[$id]->sql_serveur = strtolower($type);
1451
-					}
1452
-					if ($show) {
1453
-						$boucles[$id]->show = $show;
1454
-						// recopie les infos les plus importantes
1455
-						$boucles[$id]->primary = $show['key']['PRIMARY KEY'] ?? '';
1456
-						$boucles[$id]->id_table = $x = preg_replace(',^spip_,', '', $show['id_table']);
1457
-						$boucles[$id]->from[$x] = $nom_table = $show['table'];
1458
-						$boucles[$id]->iterateur = 'SQL';
1459
-
1460
-						if (empty($boucles[$id]->descr)) {
1461
-							$boucles[$id]->descr = &$descr;
1462
-						}
1463
-						if (
1464
-							!$boucles[$id]->jointures
1465
-							&& is_array($show['tables_jointures'])
1466
-							&& count($x = $show['tables_jointures'])
1467
-						) {
1468
-							$boucles[$id]->jointures = $x;
1469
-						}
1470
-						if ($boucles[$id]->jointures_explicites) {
1471
-							$jointures = preg_split('/\s+/', $boucles[$id]->jointures_explicites);
1472
-							while ($j = array_pop($jointures)) {
1473
-								array_unshift($boucles[$id]->jointures, $j);
1474
-							}
1475
-						}
1476
-					} else {
1477
-						// Pas une erreur si la table est optionnelle
1478
-						if ($boucles[$id]->table_optionnelle) {
1479
-							$boucles[$id]->type_requete = '';
1480
-						} else {
1481
-							$boucles[$id]->type_requete = false;
1482
-							$boucle = $boucles[$id];
1483
-							$x = (!$boucle->sql_serveur ? '' :
1484
-									($boucle->sql_serveur . ':')) .
1485
-								$type;
1486
-							$msg = [
1487
-								'zbug_table_inconnue',
1488
-								['table' => $x]
1489
-							];
1490
-							erreur_squelette($msg, $boucle);
1491
-						}
1492
-					}
1493
-				}
1494
-			}
1495
-		}
1496
-	}
1497
-
1498
-	// Commencer par reperer les boucles appelees explicitement
1499
-	// car elles indexent les arguments de maniere derogatoire
1500
-	foreach ($boucles as $id => $boucle) {
1501
-		if ($boucle->type_requete == TYPE_RECURSIF && $boucle->param) {
1502
-			$boucles[$id]->descr = &$descr;
1503
-			$rec = &$boucles[$boucle->param[0]];
1504
-			if (!$rec) {
1505
-				$msg = [
1506
-					'zbug_boucle_recursive_undef',
1507
-					['nom' => $boucle->param[0]]
1508
-				];
1509
-				erreur_squelette($msg, $boucle);
1510
-				$boucles[$id]->type_requete = false;
1511
-			} else {
1512
-				$rec->externe = $id;
1513
-				$descr['id_mere'] = $id;
1514
-				$boucles[$id]->return =
1515
-					calculer_liste(
1516
-						[$rec],
1517
-						$descr,
1518
-						$boucles,
1519
-						$boucle->param
1520
-					);
1521
-			}
1522
-		}
1523
-	}
1524
-	foreach ($boucles as $id => $boucle) {
1525
-		$id = strval($id); // attention au type dans index_pile
1526
-		$type = $boucle->type_requete;
1527
-		if ($type && $type != TYPE_RECURSIF) {
1528
-			$res = '';
1529
-			if ($boucle->param) {
1530
-				// retourne un tableau en cas d'erreur
1531
-				$res = calculer_criteres($id, $boucles);
1532
-			}
1533
-			$descr['id_mere'] = $id;
1534
-			$boucles[$id]->return =
1535
-				calculer_liste(
1536
-					$boucle->milieu,
1537
-					$descr,
1538
-					$boucles,
1539
-					$id
1540
-				);
1541
-			// Si les criteres se sont mal compiles
1542
-			// ne pas tenter d'assembler le code final
1543
-			// (mais compiler le corps pour detection d'erreurs)
1544
-			if (is_array($res)) {
1545
-				$boucles[$id]->type_requete = false;
1546
-			}
1547
-		}
1548
-	}
1549
-
1550
-	// idem pour la racine
1551
-	$descr['id_mere'] = '';
1552
-	$corps = calculer_liste($squelette, $descr, $boucles);
1553
-
1554
-
1555
-	// Calcul du corps de toutes les fonctions PHP,
1556
-	// en particulier les requetes SQL et TOTAL_BOUCLE
1557
-	// de'terminables seulement maintenant
1558
-
1559
-	foreach ($boucles as $id => $boucle) {
1560
-		$boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
1561
-		if ($boucle->return === false) {
1562
-			$corps = false;
1563
-			continue;
1564
-		}
1565
-		// appeler la fonction de definition de la boucle
1566
-
1567
-		if ($req = $boucle->type_requete) {
1568
-			// boucle personnalisée ?
1569
-			$table = strtoupper($boucle->type_requete);
1570
-			$serveur = strtolower($boucle->sql_serveur);
1571
-			if (
1572
-				// fonction de boucle avec serveur & table
1573
-				(
1574
-					!$serveur
1575
-					|| !function_exists($f = 'boucle_' . $serveur . '_' . $table) && !function_exists($f = $f . '_dist')
1576
-				)
1577
-				// fonction de boucle avec table
1578
-				&& !function_exists($f = 'boucle_' . $table)
1579
-				&& !function_exists($f = $f . '_dist')
1580
-			) {
1581
-				// fonction de boucle standard
1582
-				if (!function_exists($f = 'boucle_DEFAUT')) {
1583
-					$f = 'boucle_DEFAUT_dist';
1584
-				}
1585
-			}
1586
-
1587
-			$req = "\n\n\tstatic \$command = array();\n\t" .
1588
-				"static \$connect;\n\t" .
1589
-				"\$command['connect'] = \$connect = " .
1590
-				_q($boucle->sql_serveur) .
1591
-				';' .
1592
-				$f($id, $boucles);
1593
-		} else {
1594
-			$req = ("\n\treturn '';");
1595
-		}
1596
-
1597
-		$boucles[$id]->return =
1598
-			"\n\nfunction BOUCLE" . strtr($id, '-', '_') . $nom .
1599
-			'(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1600
-			$req .
1601
-			"\n}\n";
1602
-	}
1603
-
1604
-	// Au final, si le corps ou un critere au moins s'est mal compile
1605
-	// retourner False, sinon inserer leur decompilation
1606
-	if (is_bool($corps)) {
1607
-		return false;
1608
-	}
1609
-
1610
-	$principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1378
+    static $trouver_table;
1379
+    spip_timer('calcul_skel');
1380
+
1381
+    if (defined('_VAR_MODE') && _VAR_MODE == 'debug') {
1382
+        $GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
1383
+        $GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;
1384
+
1385
+        if (!isset($GLOBALS['debug_objets']['principal'])) {
1386
+            $GLOBALS['debug_objets']['principal'] = $nom;
1387
+        }
1388
+    }
1389
+    foreach ($boucles as $id => $boucle) {
1390
+        $GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1391
+    }
1392
+    $descr['documents'] = compile_inclure_doublons($squelette);
1393
+
1394
+    // Demander la description des tables une fois pour toutes
1395
+    if (!$trouver_table) {
1396
+        $trouver_table = charger_fonction('trouver_table', 'base');
1397
+    }
1398
+
1399
+    // reperer si les doublons sont demandes
1400
+    // pour un inclure ou une boucle document
1401
+    // c'est utile a la fonction champs_traitements
1402
+    foreach ($boucles as $id => $boucle) {
1403
+        if (!($type = $boucle->type_requete)) {
1404
+            continue;
1405
+        }
1406
+        if (
1407
+            !$descr['documents']
1408
+            && (
1409
+                $type == 'documents' && $boucle->doublons
1410
+                || compile_inclure_doublons($boucle->avant)
1411
+                || compile_inclure_doublons($boucle->apres)
1412
+                || compile_inclure_doublons($boucle->milieu)
1413
+                || compile_inclure_doublons($boucle->altern)
1414
+            )
1415
+        ) {
1416
+            $descr['documents'] = true;
1417
+        }
1418
+        if ($type != TYPE_RECURSIF) {
1419
+            if (!$boucles[$id]->sql_serveur && $connect) {
1420
+                $boucles[$id]->sql_serveur = $connect;
1421
+            }
1422
+
1423
+            // chercher dans les iterateurs du repertoire iterateur/
1424
+            if (
1425
+                $g = charger_fonction(
1426
+                    preg_replace('/\W/', '_', $boucle->type_requete),
1427
+                    'iterateur',
1428
+                    true
1429
+                )
1430
+            ) {
1431
+                $boucles[$id] = $g($boucle);
1432
+
1433
+                // sinon, en cas de requeteur d'un type predefini,
1434
+                // utiliser les informations donnees par le requeteur
1435
+                // cas "php:xx" et "data:xx".
1436
+            } else {
1437
+                if ($boucle->sql_serveur && ($requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true))) {
1438
+                    $requeteur($boucles, $boucle, $id);
1439
+
1440
+                    // utiliser la description des champs transmis
1441
+                } else {
1442
+                    $show = $trouver_table($type, $boucles[$id]->sql_serveur);
1443
+                    // si la table n'existe pas avec le connecteur par defaut,
1444
+                    // c'est peut etre une table qui necessite son connecteur dedie fourni
1445
+                    // permet une ecriture allegee (GEO) -> (geo:GEO)
1446
+                    if (
1447
+                        !$show
1448
+                        && ($show = $trouver_table($type, strtolower($type)))
1449
+                    ) {
1450
+                        $boucles[$id]->sql_serveur = strtolower($type);
1451
+                    }
1452
+                    if ($show) {
1453
+                        $boucles[$id]->show = $show;
1454
+                        // recopie les infos les plus importantes
1455
+                        $boucles[$id]->primary = $show['key']['PRIMARY KEY'] ?? '';
1456
+                        $boucles[$id]->id_table = $x = preg_replace(',^spip_,', '', $show['id_table']);
1457
+                        $boucles[$id]->from[$x] = $nom_table = $show['table'];
1458
+                        $boucles[$id]->iterateur = 'SQL';
1459
+
1460
+                        if (empty($boucles[$id]->descr)) {
1461
+                            $boucles[$id]->descr = &$descr;
1462
+                        }
1463
+                        if (
1464
+                            !$boucles[$id]->jointures
1465
+                            && is_array($show['tables_jointures'])
1466
+                            && count($x = $show['tables_jointures'])
1467
+                        ) {
1468
+                            $boucles[$id]->jointures = $x;
1469
+                        }
1470
+                        if ($boucles[$id]->jointures_explicites) {
1471
+                            $jointures = preg_split('/\s+/', $boucles[$id]->jointures_explicites);
1472
+                            while ($j = array_pop($jointures)) {
1473
+                                array_unshift($boucles[$id]->jointures, $j);
1474
+                            }
1475
+                        }
1476
+                    } else {
1477
+                        // Pas une erreur si la table est optionnelle
1478
+                        if ($boucles[$id]->table_optionnelle) {
1479
+                            $boucles[$id]->type_requete = '';
1480
+                        } else {
1481
+                            $boucles[$id]->type_requete = false;
1482
+                            $boucle = $boucles[$id];
1483
+                            $x = (!$boucle->sql_serveur ? '' :
1484
+                                    ($boucle->sql_serveur . ':')) .
1485
+                                $type;
1486
+                            $msg = [
1487
+                                'zbug_table_inconnue',
1488
+                                ['table' => $x]
1489
+                            ];
1490
+                            erreur_squelette($msg, $boucle);
1491
+                        }
1492
+                    }
1493
+                }
1494
+            }
1495
+        }
1496
+    }
1497
+
1498
+    // Commencer par reperer les boucles appelees explicitement
1499
+    // car elles indexent les arguments de maniere derogatoire
1500
+    foreach ($boucles as $id => $boucle) {
1501
+        if ($boucle->type_requete == TYPE_RECURSIF && $boucle->param) {
1502
+            $boucles[$id]->descr = &$descr;
1503
+            $rec = &$boucles[$boucle->param[0]];
1504
+            if (!$rec) {
1505
+                $msg = [
1506
+                    'zbug_boucle_recursive_undef',
1507
+                    ['nom' => $boucle->param[0]]
1508
+                ];
1509
+                erreur_squelette($msg, $boucle);
1510
+                $boucles[$id]->type_requete = false;
1511
+            } else {
1512
+                $rec->externe = $id;
1513
+                $descr['id_mere'] = $id;
1514
+                $boucles[$id]->return =
1515
+                    calculer_liste(
1516
+                        [$rec],
1517
+                        $descr,
1518
+                        $boucles,
1519
+                        $boucle->param
1520
+                    );
1521
+            }
1522
+        }
1523
+    }
1524
+    foreach ($boucles as $id => $boucle) {
1525
+        $id = strval($id); // attention au type dans index_pile
1526
+        $type = $boucle->type_requete;
1527
+        if ($type && $type != TYPE_RECURSIF) {
1528
+            $res = '';
1529
+            if ($boucle->param) {
1530
+                // retourne un tableau en cas d'erreur
1531
+                $res = calculer_criteres($id, $boucles);
1532
+            }
1533
+            $descr['id_mere'] = $id;
1534
+            $boucles[$id]->return =
1535
+                calculer_liste(
1536
+                    $boucle->milieu,
1537
+                    $descr,
1538
+                    $boucles,
1539
+                    $id
1540
+                );
1541
+            // Si les criteres se sont mal compiles
1542
+            // ne pas tenter d'assembler le code final
1543
+            // (mais compiler le corps pour detection d'erreurs)
1544
+            if (is_array($res)) {
1545
+                $boucles[$id]->type_requete = false;
1546
+            }
1547
+        }
1548
+    }
1549
+
1550
+    // idem pour la racine
1551
+    $descr['id_mere'] = '';
1552
+    $corps = calculer_liste($squelette, $descr, $boucles);
1553
+
1554
+
1555
+    // Calcul du corps de toutes les fonctions PHP,
1556
+    // en particulier les requetes SQL et TOTAL_BOUCLE
1557
+    // de'terminables seulement maintenant
1558
+
1559
+    foreach ($boucles as $id => $boucle) {
1560
+        $boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
1561
+        if ($boucle->return === false) {
1562
+            $corps = false;
1563
+            continue;
1564
+        }
1565
+        // appeler la fonction de definition de la boucle
1566
+
1567
+        if ($req = $boucle->type_requete) {
1568
+            // boucle personnalisée ?
1569
+            $table = strtoupper($boucle->type_requete);
1570
+            $serveur = strtolower($boucle->sql_serveur);
1571
+            if (
1572
+                // fonction de boucle avec serveur & table
1573
+                (
1574
+                    !$serveur
1575
+                    || !function_exists($f = 'boucle_' . $serveur . '_' . $table) && !function_exists($f = $f . '_dist')
1576
+                )
1577
+                // fonction de boucle avec table
1578
+                && !function_exists($f = 'boucle_' . $table)
1579
+                && !function_exists($f = $f . '_dist')
1580
+            ) {
1581
+                // fonction de boucle standard
1582
+                if (!function_exists($f = 'boucle_DEFAUT')) {
1583
+                    $f = 'boucle_DEFAUT_dist';
1584
+                }
1585
+            }
1586
+
1587
+            $req = "\n\n\tstatic \$command = array();\n\t" .
1588
+                "static \$connect;\n\t" .
1589
+                "\$command['connect'] = \$connect = " .
1590
+                _q($boucle->sql_serveur) .
1591
+                ';' .
1592
+                $f($id, $boucles);
1593
+        } else {
1594
+            $req = ("\n\treturn '';");
1595
+        }
1596
+
1597
+        $boucles[$id]->return =
1598
+            "\n\nfunction BOUCLE" . strtr($id, '-', '_') . $nom .
1599
+            '(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1600
+            $req .
1601
+            "\n}\n";
1602
+    }
1603
+
1604
+    // Au final, si le corps ou un critere au moins s'est mal compile
1605
+    // retourner False, sinon inserer leur decompilation
1606
+    if (is_bool($corps)) {
1607
+        return false;
1608
+    }
1609
+
1610
+    $principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1611 1611
 '
1612
-		// reporter de maniere securisee les doublons inclus
1613
-		. '
1612
+        // reporter de maniere securisee les doublons inclus
1613
+        . '
1614 1614
 	if (isset($Pile[0]["doublons"]) AND is_array($Pile[0]["doublons"]))
1615 1615
 		$doublons = nettoyer_env_doublons($Pile[0]["doublons"]);
1616 1616
 
1617 1617
 	$connect = ' .
1618
-		_q($connect) . ';
1618
+        _q($connect) . ';
1619 1619
 	$page = ' .
1620
-		// ATTENTION, le calcul de l'expression $corps affectera $Cache
1621
-		// c'est pourquoi on l'affecte a la variable auxiliaire $page.
1622
-		// avant de referencer $Cache
1623
-		$corps . ';
1620
+        // ATTENTION, le calcul de l'expression $corps affectera $Cache
1621
+        // c'est pourquoi on l'affecte a la variable auxiliaire $page.
1622
+        // avant de referencer $Cache
1623
+        $corps . ';
1624 1624
 
1625 1625
 	return analyse_resultat_skel(' . var_export($nom, true)
1626
-		. ', $Cache, $page, ' . var_export($sourcefile, true) . ');
1626
+        . ', $Cache, $page, ' . var_export($sourcefile, true) . ');
1627 1627
 }';
1628 1628
 
1629
-	$secondes = spip_timer('calcul_skel');
1630
-	spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
1631
-	// $connect n'est pas sûr : on nettoie
1632
-	$connect = preg_replace(',[^\w],', '', $connect);
1629
+    $secondes = spip_timer('calcul_skel');
1630
+    spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
1631
+    // $connect n'est pas sûr : on nettoie
1632
+    $connect = preg_replace(',[^\w],', '', $connect);
1633 1633
 
1634
-	// Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple
1635
-	$code = new Boucle();
1636
-	$code->descr = $descr;
1637
-	$code->return = '
1634
+    // Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple
1635
+    $code = new Boucle();
1636
+    $code->descr = $descr;
1637
+    $code->return = '
1638 1638
 //
1639 1639
 // Fonction principale du squelette ' .
1640
-		$sourcefile .
1641
-		($connect ? " pour $connect" : '') .
1642
-		(!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1643
-		"\n//\n" .
1644
-		$principal;
1640
+        $sourcefile .
1641
+        ($connect ? " pour $connect" : '') .
1642
+        (!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1643
+        "\n//\n" .
1644
+        $principal;
1645 1645
 
1646
-	$boucles[''] = $code;
1646
+    $boucles[''] = $code;
1647 1647
 
1648
-	return $boucles;
1648
+    return $boucles;
1649 1649
 }
1650 1650
 
1651 1651
 
@@ -1662,18 +1662,18 @@  discard block
 block discarded – undo
1662 1662
  *
1663 1663
  **/
1664 1664
 function requeteur_php_dist(&$boucles, &$boucle, &$id) {
1665
-	if (class_exists($boucle->type_requete)) {
1666
-		$g = charger_fonction('php', 'iterateur');
1667
-		$boucles[$id] = $g($boucle, $boucle->type_requete);
1668
-	} else {
1669
-		$x = $boucle->type_requete;
1670
-		$boucle->type_requete = false;
1671
-		$msg = [
1672
-			'zbug_iterateur_inconnu',
1673
-			['iterateur' => $x]
1674
-		];
1675
-		erreur_squelette($msg, $boucle);
1676
-	}
1665
+    if (class_exists($boucle->type_requete)) {
1666
+        $g = charger_fonction('php', 'iterateur');
1667
+        $boucles[$id] = $g($boucle, $boucle->type_requete);
1668
+    } else {
1669
+        $x = $boucle->type_requete;
1670
+        $boucle->type_requete = false;
1671
+        $msg = [
1672
+            'zbug_iterateur_inconnu',
1673
+            ['iterateur' => $x]
1674
+        ];
1675
+        erreur_squelette($msg, $boucle);
1676
+    }
1677 1677
 }
1678 1678
 
1679 1679
 
@@ -1691,22 +1691,22 @@  discard block
 block discarded – undo
1691 1691
  *
1692 1692
  **/
1693 1693
 function requeteur_data_dist(&$boucles, &$boucle, &$id) {
1694
-	include_spip('iterateur/data');
1695
-	if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1696
-		$g = charger_fonction('data', 'iterateur');
1697
-		$boucles[$id] = $g($boucle);
1698
-		// from[0] stocke le type de data (rss, yql, ...)
1699
-		$boucles[$id]->from[] = $boucle->type_requete;
1700
-	} else {
1701
-		$x = $boucle->type_requete;
1702
-		$boucle->type_requete = false;
1703
-		$msg = [
1704
-			'zbug_requeteur_inconnu',
1705
-			[
1706
-				'requeteur' => 'data',
1707
-				'type' => $x
1708
-			]
1709
-		];
1710
-		erreur_squelette($msg, $boucle);
1711
-	}
1694
+    include_spip('iterateur/data');
1695
+    if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1696
+        $g = charger_fonction('data', 'iterateur');
1697
+        $boucles[$id] = $g($boucle);
1698
+        // from[0] stocke le type de data (rss, yql, ...)
1699
+        $boucles[$id]->from[] = $boucle->type_requete;
1700
+    } else {
1701
+        $x = $boucle->type_requete;
1702
+        $boucle->type_requete = false;
1703
+        $msg = [
1704
+            'zbug_requeteur_inconnu',
1705
+            [
1706
+                'requeteur' => 'data',
1707
+                'type' => $x
1708
+            ]
1709
+        ];
1710
+        erreur_squelette($msg, $boucle);
1711
+    }
1712 1712
 }
Please login to merge, or discard this patch.
ecrire/public/composer.php 1 patch
Indentation   +765 added lines, -765 removed lines patch added patch discarded remove patch
@@ -19,7 +19,7 @@  discard block
 block discarded – undo
19 19
  **/
20 20
 
21 21
 if (!defined('_ECRIRE_INC_VERSION')) {
22
-	return;
22
+    return;
23 23
 }
24 24
 
25 25
 include_spip('inc/texte');
@@ -42,229 +42,229 @@  discard block
 block discarded – undo
42 42
 
43 43
 function public_composer_dist($squelette, $mime_type, $gram, $source, string $connect = '') {
44 44
 
45
-	$skel = null;
46
-	$boucle = null;
47
-	$nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect);
48
-
49
-	//  si deja en memoire (INCLURE  a repetition) c'est bon.
50
-	if (function_exists($nom)) {
51
-		return $nom;
52
-	}
53
-
54
-	if (defined('_VAR_MODE') && _VAR_MODE == 'debug') {
55
-		$GLOBALS['debug_objets']['courant'] = $nom;
56
-	}
57
-
58
-	$phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php';
59
-
60
-	// si squelette est deja compile et perenne, le charger
61
-	if (!squelette_obsolete($phpfile, $source)) {
62
-		include_once $phpfile;
63
-		#if (!squelette_obsolete($phpfile, $source)
64
-		#  AND lire_fichier ($phpfile, $skel_code,
65
-		#  array('critique' => 'oui', 'phpcheck' => 'oui'))){
66
-		## eval('?'.'>'.$skel_code);
67
-		#	 spip_log($skel_code, 'comp')
68
-		#}
69
-	}
70
-
71
-	if (file_exists($lib = $squelette . '_fonctions' . '.php')) {
72
-		include_once $lib;
73
-	}
74
-
75
-	// tester si le eval ci-dessus a mis le squelette en memoire
76
-
77
-	if (function_exists($nom)) {
78
-		return $nom;
79
-	}
80
-
81
-	// charger le source, si possible, et compiler
82
-	$skel_code = '';
83
-	if (lire_fichier($source, $skel)) {
84
-		$compiler = charger_fonction('compiler', 'public');
85
-		$skel_code = $compiler($skel, $nom, $gram, $source, $connect);
86
-	}
87
-
88
-	// Ne plus rien faire si le compilateur n'a pas pu operer.
89
-	if (!$skel_code) {
90
-		return false;
91
-	}
92
-
93
-	foreach ($skel_code as $id => $boucle) {
94
-		$f = $boucle->return;
95
-		try {
96
-			eval("return true; $f ;");
97
-		} catch (\ParseError $e) {
98
-			// Code syntaxiquement faux (critere etc mal programme')
99
-			$msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage();
100
-			erreur_squelette($msg, $boucle);
101
-			// continuer pour trouver d'autres fautes eventuelles
102
-			// mais prevenir que c'est mort
103
-			$nom = '';
104
-		}
105
-
106
-		// contexte de compil inutile a present
107
-		// (mais la derniere valeur de $boucle est utilisee ci-dessous)
108
-		$skel_code[$id] = $f;
109
-	}
110
-
111
-	$code = '';
112
-	if ($nom) {
113
-		// Si le code est bon, concatener et mettre en cache
114
-		if (function_exists($nom)) {
115
-			$code = squelette_traduit($skel, $source, $phpfile, $skel_code);
116
-		} else {
117
-			// code semantiquement faux: bug du compilateur
118
-			// $boucle est en fait ici la fct principale du squelette
119
-			$msg = _T('zbug_erreur_compilation');
120
-			erreur_squelette($msg, $boucle);
121
-			$nom = '';
122
-		}
123
-	}
124
-
125
-	if (defined('_VAR_MODE') && _VAR_MODE == 'debug') {
126
-		// Tracer ce qui vient d'etre compile
127
-		$GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code;
128
-
129
-		// si c'est ce que demande le debusqueur, lui passer la main
130
-		if (
131
-			$GLOBALS['debug_objets']['sourcefile']
132
-			&& _request('var_mode_objet') == $nom
133
-			&& _request('var_mode_affiche') == 'code'
134
-		) {
135
-			erreur_squelette();
136
-		}
137
-	}
138
-
139
-	return $nom ?: false;
45
+    $skel = null;
46
+    $boucle = null;
47
+    $nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect);
48
+
49
+    //  si deja en memoire (INCLURE  a repetition) c'est bon.
50
+    if (function_exists($nom)) {
51
+        return $nom;
52
+    }
53
+
54
+    if (defined('_VAR_MODE') && _VAR_MODE == 'debug') {
55
+        $GLOBALS['debug_objets']['courant'] = $nom;
56
+    }
57
+
58
+    $phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php';
59
+
60
+    // si squelette est deja compile et perenne, le charger
61
+    if (!squelette_obsolete($phpfile, $source)) {
62
+        include_once $phpfile;
63
+        #if (!squelette_obsolete($phpfile, $source)
64
+        #  AND lire_fichier ($phpfile, $skel_code,
65
+        #  array('critique' => 'oui', 'phpcheck' => 'oui'))){
66
+        ## eval('?'.'>'.$skel_code);
67
+        #	 spip_log($skel_code, 'comp')
68
+        #}
69
+    }
70
+
71
+    if (file_exists($lib = $squelette . '_fonctions' . '.php')) {
72
+        include_once $lib;
73
+    }
74
+
75
+    // tester si le eval ci-dessus a mis le squelette en memoire
76
+
77
+    if (function_exists($nom)) {
78
+        return $nom;
79
+    }
80
+
81
+    // charger le source, si possible, et compiler
82
+    $skel_code = '';
83
+    if (lire_fichier($source, $skel)) {
84
+        $compiler = charger_fonction('compiler', 'public');
85
+        $skel_code = $compiler($skel, $nom, $gram, $source, $connect);
86
+    }
87
+
88
+    // Ne plus rien faire si le compilateur n'a pas pu operer.
89
+    if (!$skel_code) {
90
+        return false;
91
+    }
92
+
93
+    foreach ($skel_code as $id => $boucle) {
94
+        $f = $boucle->return;
95
+        try {
96
+            eval("return true; $f ;");
97
+        } catch (\ParseError $e) {
98
+            // Code syntaxiquement faux (critere etc mal programme')
99
+            $msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage();
100
+            erreur_squelette($msg, $boucle);
101
+            // continuer pour trouver d'autres fautes eventuelles
102
+            // mais prevenir que c'est mort
103
+            $nom = '';
104
+        }
105
+
106
+        // contexte de compil inutile a present
107
+        // (mais la derniere valeur de $boucle est utilisee ci-dessous)
108
+        $skel_code[$id] = $f;
109
+    }
110
+
111
+    $code = '';
112
+    if ($nom) {
113
+        // Si le code est bon, concatener et mettre en cache
114
+        if (function_exists($nom)) {
115
+            $code = squelette_traduit($skel, $source, $phpfile, $skel_code);
116
+        } else {
117
+            // code semantiquement faux: bug du compilateur
118
+            // $boucle est en fait ici la fct principale du squelette
119
+            $msg = _T('zbug_erreur_compilation');
120
+            erreur_squelette($msg, $boucle);
121
+            $nom = '';
122
+        }
123
+    }
124
+
125
+    if (defined('_VAR_MODE') && _VAR_MODE == 'debug') {
126
+        // Tracer ce qui vient d'etre compile
127
+        $GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code;
128
+
129
+        // si c'est ce que demande le debusqueur, lui passer la main
130
+        if (
131
+            $GLOBALS['debug_objets']['sourcefile']
132
+            && _request('var_mode_objet') == $nom
133
+            && _request('var_mode_affiche') == 'code'
134
+        ) {
135
+            erreur_squelette();
136
+        }
137
+    }
138
+
139
+    return $nom ?: false;
140 140
 }
141 141
 
142 142
 function squelette_traduit($squelette, $sourcefile, $phpfile, $boucles) {
143 143
 
144
-	$code = null;
145
-	// Le dernier index est '' (fonction principale)
146
-	$noms = substr(join(', ', array_keys($boucles)), 0, -2);
147
-	if (CODE_COMMENTE) {
148
-		$code = "
144
+    $code = null;
145
+    // Le dernier index est '' (fonction principale)
146
+    $noms = substr(join(', ', array_keys($boucles)), 0, -2);
147
+    if (CODE_COMMENTE) {
148
+        $code = "
149 149
 /*
150 150
  * Squelette : $sourcefile
151 151
  * Date :      " . gmdate('D, d M Y H:i:s', @filemtime($sourcefile)) . ' GMT
152 152
  * Compile :   ' . gmdate('D, d M Y H:i:s', time()) . ' GMT
153 153
  * ' . (!$boucles ? 'Pas de boucle' : ('Boucles :   ' . $noms)) . '
154 154
  */ ';
155
-	}
155
+    }
156 156
 
157
-	$code = '<' . "?php\n" . $code . join('', $boucles) . "\n";
158
-	if (!defined('_VAR_NOCACHE') || !_VAR_NOCACHE) {
159
-		ecrire_fichier($phpfile, $code);
160
-	}
157
+    $code = '<' . "?php\n" . $code . join('', $boucles) . "\n";
158
+    if (!defined('_VAR_NOCACHE') || !_VAR_NOCACHE) {
159
+        ecrire_fichier($phpfile, $code);
160
+    }
161 161
 
162
-	return $code;
162
+    return $code;
163 163
 }
164 164
 
165 165
 // Le squelette compile est-il trop vieux ?
166 166
 function squelette_obsolete($skel, $squelette) {
167
-	static $date_change = null;
168
-	// ne verifier la date de mes_fonctions et mes_options qu'une seule fois
169
-	// par hit
170
-	if (is_null($date_change)) {
171
-		if (@file_exists($fonc = 'mes_fonctions.php')) {
172
-			$date_change = @filemtime($fonc);
173
-		} # compatibilite
174
-		if (defined('_FILE_OPTIONS')) {
175
-			$date_change = max($date_change, @filemtime(_FILE_OPTIONS));
176
-		}
177
-	}
178
-
179
-	return (
180
-		defined('_VAR_MODE') && in_array(_VAR_MODE, ['recalcul', 'preview', 'debug'])
181
-		|| !@file_exists($skel)
182
-		|| (@file_exists($squelette) ? @filemtime($squelette) : 0) > ($date = @filemtime($skel))
183
-		|| $date_change > $date
184
-	);
167
+    static $date_change = null;
168
+    // ne verifier la date de mes_fonctions et mes_options qu'une seule fois
169
+    // par hit
170
+    if (is_null($date_change)) {
171
+        if (@file_exists($fonc = 'mes_fonctions.php')) {
172
+            $date_change = @filemtime($fonc);
173
+        } # compatibilite
174
+        if (defined('_FILE_OPTIONS')) {
175
+            $date_change = max($date_change, @filemtime(_FILE_OPTIONS));
176
+        }
177
+    }
178
+
179
+    return (
180
+        defined('_VAR_MODE') && in_array(_VAR_MODE, ['recalcul', 'preview', 'debug'])
181
+        || !@file_exists($skel)
182
+        || (@file_exists($squelette) ? @filemtime($squelette) : 0) > ($date = @filemtime($skel))
183
+        || $date_change > $date
184
+    );
185 185
 }
186 186
 
187 187
 // Activer l'invalideur de session
188 188
 function invalideur_session(&$Cache, $code = null) {
189
-	$Cache['session'] = spip_session();
189
+    $Cache['session'] = spip_session();
190 190
 
191
-	return $code;
191
+    return $code;
192 192
 }
193 193
 
194 194
 
195 195
 function analyse_resultat_skel($nom, $cache, $corps, $source = '') {
196
-	static $filtres = [];
197
-	$headers = [];
198
-	$corps ??= '';
199
-
200
-	// Recupere les < ?php header('Xx: y'); ? > pour $page['headers']
201
-	// note: on essaie d'attrapper aussi certains de ces entetes codes
202
-	// "a la main" dans les squelettes, mais evidemment sans exhaustivite
203
-	if (
204
-		stripos($corps, 'header') !== false
205
-		&& preg_match_all(
206
-			'/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims',
207
-			$corps,
208
-			$regs,
209
-			PREG_SET_ORDER
210
-		)
211
-	) {
212
-		foreach ($regs as $r) {
213
-			$corps = str_replace($r[0], '', $corps);
214
-			# $j = Content-Type, et pas content-TYPE.
215
-			$j = join('-', array_map('ucwords', explode('-', strtolower($r[2]))));
216
-
217
-			if ($j == 'X-Spip-Filtre' && isset($headers[$j])) {
218
-				$headers[$j] .= '|' . $r[3];
219
-			} else {
220
-				$headers[$j] = str_replace(['\\\\',"\\'",'\\"'], ['\\',"'",'"'], $r[3]);
221
-			}
222
-		}
223
-	}
224
-	// S'agit-il d'un resultat constant ou contenant du code php
225
-	$process_ins = (
226
-		!str_contains($corps, '<' . '?')
227
-		|| str_contains($corps, '<' . '?xml') && !str_contains(str_replace('<' . '?xml', '', $corps), '<' . '?')
228
-	)
229
-		? 'html'
230
-		: 'php';
231
-
232
-	$skel = [
233
-		'squelette' => $nom,
234
-		'source' => $source,
235
-		'process_ins' => $process_ins,
236
-		'invalideurs' => $cache,
237
-		'entetes' => $headers,
238
-		'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0
239
-	];
240
-
241
-	// traiter #FILTRE{} et filtres
242
-	if (!isset($filtres[$nom])) {
243
-		$filtres[$nom] = pipeline('declarer_filtres_squelettes', ['args' => $skel, 'data' => []]);
244
-	}
245
-	$filtres_headers = [];
246
-	if (isset($headers['X-Spip-Filtre']) && strlen($headers['X-Spip-Filtre'])) {
247
-		$filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre']));
248
-		unset($headers['X-Spip-Filtre']);
249
-	}
250
-	if ((is_countable($filtres[$nom]) ? count($filtres[$nom]) : 0) || count($filtres_headers)) {
251
-		include_spip('public/sandbox');
252
-		$corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]);
253
-
254
-		if ($process_ins == 'html') {
255
-			$skel['process_ins'] = (
256
-				!str_contains($corps, '<' . '?')
257
-				|| str_contains($corps, '<' . '?xml') && !str_contains(str_replace('<' . '?xml', '', $corps), '<' . '?')
258
-			)
259
-				? 'html'
260
-				: 'php';
261
-		}
262
-	}
263
-
264
-	$skel['entetes'] = $headers;
265
-	$skel['texte'] = $corps;
266
-
267
-	return $skel;
196
+    static $filtres = [];
197
+    $headers = [];
198
+    $corps ??= '';
199
+
200
+    // Recupere les < ?php header('Xx: y'); ? > pour $page['headers']
201
+    // note: on essaie d'attrapper aussi certains de ces entetes codes
202
+    // "a la main" dans les squelettes, mais evidemment sans exhaustivite
203
+    if (
204
+        stripos($corps, 'header') !== false
205
+        && preg_match_all(
206
+            '/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims',
207
+            $corps,
208
+            $regs,
209
+            PREG_SET_ORDER
210
+        )
211
+    ) {
212
+        foreach ($regs as $r) {
213
+            $corps = str_replace($r[0], '', $corps);
214
+            # $j = Content-Type, et pas content-TYPE.
215
+            $j = join('-', array_map('ucwords', explode('-', strtolower($r[2]))));
216
+
217
+            if ($j == 'X-Spip-Filtre' && isset($headers[$j])) {
218
+                $headers[$j] .= '|' . $r[3];
219
+            } else {
220
+                $headers[$j] = str_replace(['\\\\',"\\'",'\\"'], ['\\',"'",'"'], $r[3]);
221
+            }
222
+        }
223
+    }
224
+    // S'agit-il d'un resultat constant ou contenant du code php
225
+    $process_ins = (
226
+        !str_contains($corps, '<' . '?')
227
+        || str_contains($corps, '<' . '?xml') && !str_contains(str_replace('<' . '?xml', '', $corps), '<' . '?')
228
+    )
229
+        ? 'html'
230
+        : 'php';
231
+
232
+    $skel = [
233
+        'squelette' => $nom,
234
+        'source' => $source,
235
+        'process_ins' => $process_ins,
236
+        'invalideurs' => $cache,
237
+        'entetes' => $headers,
238
+        'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0
239
+    ];
240
+
241
+    // traiter #FILTRE{} et filtres
242
+    if (!isset($filtres[$nom])) {
243
+        $filtres[$nom] = pipeline('declarer_filtres_squelettes', ['args' => $skel, 'data' => []]);
244
+    }
245
+    $filtres_headers = [];
246
+    if (isset($headers['X-Spip-Filtre']) && strlen($headers['X-Spip-Filtre'])) {
247
+        $filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre']));
248
+        unset($headers['X-Spip-Filtre']);
249
+    }
250
+    if ((is_countable($filtres[$nom]) ? count($filtres[$nom]) : 0) || count($filtres_headers)) {
251
+        include_spip('public/sandbox');
252
+        $corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]);
253
+
254
+        if ($process_ins == 'html') {
255
+            $skel['process_ins'] = (
256
+                !str_contains($corps, '<' . '?')
257
+                || str_contains($corps, '<' . '?xml') && !str_contains(str_replace('<' . '?xml', '', $corps), '<' . '?')
258
+            )
259
+                ? 'html'
260
+                : 'php';
261
+        }
262
+    }
263
+
264
+    $skel['entetes'] = $headers;
265
+    $skel['texte'] = $corps;
266
+
267
+    return $skel;
268 268
 }
269 269
 
270 270
 //
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
 inserer_balise_dynamique(balise_%s_dyn(%s), array(%s));
279 279
 if ($lang_select) lang_select();
280 280
 ?'
281
-	. '>');
281
+    . '>');
282 282
 
283 283
 /**
284 284
  * Synthétise une balise dynamique : crée l'appel à l'inclusion
@@ -298,35 +298,35 @@  discard block
 block discarded – undo
298 298
  *     Code PHP pour inclure le squelette de la balise dynamique
299 299
  **/
300 300
 function synthetiser_balise_dynamique($nom, $args, $file, $context_compil) {
301
-	if (
302
-		!str_starts_with($file, '/')
303
-		// pas de lien symbolique sous Windows
304
-		&& !(stristr(PHP_OS, 'WIN') && str_contains($file, ':'))
305
-	) {
306
-		$file = './" . _DIR_RACINE . "' . $file;
307
-	}
308
-
309
-	$lang = $context_compil[4];
310
-	if (preg_match(',\W,', $lang)) {
311
-		$lang = '';
312
-	}
313
-
314
-	$args = array_map('argumenter_squelette', $args);
315
-	if (!empty($context_compil['appel_php_depuis_modele'])) {
316
-		$args[0] = 'arguments_balise_dyn_depuis_modele(' . $args[0] . ')';
317
-	}
318
-	$args = join(', ', $args);
319
-
320
-	$r = sprintf(
321
-		CODE_INCLURE_BALISE,
322
-		$file,
323
-		$lang,
324
-		$nom,
325
-		$args,
326
-		join(', ', array_map('_q', $context_compil))
327
-	);
328
-
329
-	return $r;
301
+    if (
302
+        !str_starts_with($file, '/')
303
+        // pas de lien symbolique sous Windows
304
+        && !(stristr(PHP_OS, 'WIN') && str_contains($file, ':'))
305
+    ) {
306
+        $file = './" . _DIR_RACINE . "' . $file;
307
+    }
308
+
309
+    $lang = $context_compil[4];
310
+    if (preg_match(',\W,', $lang)) {
311
+        $lang = '';
312
+    }
313
+
314
+    $args = array_map('argumenter_squelette', $args);
315
+    if (!empty($context_compil['appel_php_depuis_modele'])) {
316
+        $args[0] = 'arguments_balise_dyn_depuis_modele(' . $args[0] . ')';
317
+    }
318
+    $args = join(', ', $args);
319
+
320
+    $r = sprintf(
321
+        CODE_INCLURE_BALISE,
322
+        $file,
323
+        $lang,
324
+        $nom,
325
+        $args,
326
+        join(', ', array_map('_q', $context_compil))
327
+    );
328
+
329
+    return $r;
330 330
 }
331 331
 
332 332
 /**
@@ -344,18 +344,18 @@  discard block
 block discarded – undo
344 344
  **/
345 345
 function argumenter_squelette($v) {
346 346
 
347
-	if (is_object($v)) {
348
-		return var_export($v, true);
349
-	} elseif (!is_array($v)) {
350
-		return "'" . texte_script((string) $v) . "'";
351
-	} else {
352
-		$out = [];
353
-		foreach ($v as $k => $val) {
354
-			$out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val);
355
-		}
356
-
357
-		return 'array(' . join(', ', $out) . ')';
358
-	}
347
+    if (is_object($v)) {
348
+        return var_export($v, true);
349
+    } elseif (!is_array($v)) {
350
+        return "'" . texte_script((string) $v) . "'";
351
+    } else {
352
+        $out = [];
353
+        foreach ($v as $k => $val) {
354
+            $out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val);
355
+        }
356
+
357
+        return 'array(' . join(', ', $out) . ')';
358
+    }
359 359
 }
360 360
 
361 361
 /**
@@ -374,13 +374,13 @@  discard block
 block discarded – undo
374 374
  * @return string
375 375
  */
376 376
 function executer_balise_dynamique_dans_un_modele(...$args) {
377
-	if (test_espace_prive()) {
378
-		return executer_balise_dynamique(...$args);
379
-	}
380
-	else {
381
-		$str_args = base64_encode(serialize($args));
382
-		return '<?' . "php \$_zargs=unserialize(base64_decode('$str_args'));echo executer_balise_dynamique(...\$_zargs); ?" . ">\n";
383
-	}
377
+    if (test_espace_prive()) {
378
+        return executer_balise_dynamique(...$args);
379
+    }
380
+    else {
381
+        $str_args = base64_encode(serialize($args));
382
+        return '<?' . "php \$_zargs=unserialize(base64_decode('$str_args'));echo executer_balise_dynamique(...\$_zargs); ?" . ">\n";
383
+    }
384 384
 }
385 385
 
386 386
 
@@ -411,87 +411,87 @@  discard block
 block discarded – undo
411 411
  *     Code PHP d'exécutant l'inclusion du squelette (ou texte) de la balise dynamique
412 412
  **/
413 413
 function executer_balise_dynamique($nom, $args, $context_compil) {
414
-	/** @var string Nom de la balise à charger (balise demandée ou balise générique) */
415
-	$nom_balise = $nom;
416
-	/** @var string Nom de la balise générique (si utilisée) */
417
-	$nom_balise_generique = '';
418
-
419
-	$appel_php_depuis_modele = false;
420
-	if (
421
-		is_array($context_compil)
422
-		&& !is_numeric($context_compil[3])
423
-		&& empty($context_compil[0])
424
-		&& empty($context_compil[1])
425
-		&& empty($context_compil[2])
426
-		&& empty($context_compil[3])
427
-	) {
428
-		$appel_php_depuis_modele = true;
429
-	}
430
-
431
-	if (!$fonction_balise = charger_fonction($nom_balise, 'balise', true)) {
432
-		// Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article')
433
-		if ($balise_generique = chercher_balise_generique($nom)) {
434
-			// injecter en premier arg le nom de la balise
435
-			array_unshift($args, $nom);
436
-			$nom_balise_generique = $balise_generique['nom_generique'];
437
-			$fonction_balise = $balise_generique['fonction_generique'];
438
-			$nom_balise = $nom_balise_generique;
439
-		}
440
-		unset($balise_generique);
441
-	}
442
-
443
-	if (!$fonction_balise) {
444
-		$msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
445
-		erreur_squelette($msg, $context_compil);
446
-
447
-		return '';
448
-	}
449
-
450
-	// retrouver le fichier qui a déclaré la fonction
451
-	// même si la fonction dynamique est déclarée dans un fichier de fonctions.
452
-	// Attention sous windows, getFileName() retourne un antislash.
453
-	$reflector = new ReflectionFunction($fonction_balise);
454
-	$file = str_replace('\\', '/', $reflector->getFileName());
455
-	if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) {
456
-		$file = substr($file, strlen(_ROOT_RACINE));
457
-	}
458
-
459
-	// Y a-t-il une fonction de traitement des arguments ?
460
-	$f = 'balise_' . $nom_balise . '_stat';
461
-
462
-	$r = !function_exists($f) ? $args : $f($args, $context_compil);
463
-
464
-	if (!is_array($r)) {
465
-		return $r;
466
-	}
467
-
468
-	// verifier que la fonction dyn est la,
469
-	// sinon se replier sur la generique si elle existe
470
-	if (!function_exists('balise_' . $nom_balise . '_dyn')) {
471
-		if (
472
-			($balise_generique = chercher_balise_generique($nom))
473
-			&& ($nom_balise_generique = $balise_generique['nom_generique'])
474
-			&& ($file = include_spip('balise/' . strtolower($nom_balise_generique)))
475
-			&& function_exists('balise_' . $nom_balise_generique . '_dyn')
476
-		) {
477
-			// et lui injecter en premier arg le nom de la balise
478
-			array_unshift($r, $nom);
479
-			$nom_balise = $nom_balise_generique;
480
-			if (!_DIR_RESTREINT) {
481
-				$file = _DIR_RESTREINT_ABS . $file;
482
-			}
483
-		} else {
484
-			$msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
485
-			erreur_squelette($msg, $context_compil);
486
-
487
-			return '';
488
-		}
489
-	}
490
-
491
-	if ($appel_php_depuis_modele) {
492
-		$context_compil['appel_php_depuis_modele'] = true;
493
-	}
494
-	return synthetiser_balise_dynamique($nom_balise, $r, $file, $context_compil);
414
+    /** @var string Nom de la balise à charger (balise demandée ou balise générique) */
415
+    $nom_balise = $nom;
416
+    /** @var string Nom de la balise générique (si utilisée) */
417
+    $nom_balise_generique = '';
418
+
419
+    $appel_php_depuis_modele = false;
420
+    if (
421
+        is_array($context_compil)
422
+        && !is_numeric($context_compil[3])
423
+        && empty($context_compil[0])
424
+        && empty($context_compil[1])
425
+        && empty($context_compil[2])
426
+        && empty($context_compil[3])
427
+    ) {
428
+        $appel_php_depuis_modele = true;
429
+    }
430
+
431
+    if (!$fonction_balise = charger_fonction($nom_balise, 'balise', true)) {
432
+        // Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article')
433
+        if ($balise_generique = chercher_balise_generique($nom)) {
434
+            // injecter en premier arg le nom de la balise
435
+            array_unshift($args, $nom);
436
+            $nom_balise_generique = $balise_generique['nom_generique'];
437
+            $fonction_balise = $balise_generique['fonction_generique'];
438
+            $nom_balise = $nom_balise_generique;
439
+        }
440
+        unset($balise_generique);
441
+    }
442
+
443
+    if (!$fonction_balise) {
444
+        $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
445
+        erreur_squelette($msg, $context_compil);
446
+
447
+        return '';
448
+    }
449
+
450
+    // retrouver le fichier qui a déclaré la fonction
451
+    // même si la fonction dynamique est déclarée dans un fichier de fonctions.
452
+    // Attention sous windows, getFileName() retourne un antislash.
453
+    $reflector = new ReflectionFunction($fonction_balise);
454
+    $file = str_replace('\\', '/', $reflector->getFileName());
455
+    if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) {
456
+        $file = substr($file, strlen(_ROOT_RACINE));
457
+    }
458
+
459
+    // Y a-t-il une fonction de traitement des arguments ?
460
+    $f = 'balise_' . $nom_balise . '_stat';
461
+
462
+    $r = !function_exists($f) ? $args : $f($args, $context_compil);
463
+
464
+    if (!is_array($r)) {
465
+        return $r;
466
+    }
467
+
468
+    // verifier que la fonction dyn est la,
469
+    // sinon se replier sur la generique si elle existe
470
+    if (!function_exists('balise_' . $nom_balise . '_dyn')) {
471
+        if (
472
+            ($balise_generique = chercher_balise_generique($nom))
473
+            && ($nom_balise_generique = $balise_generique['nom_generique'])
474
+            && ($file = include_spip('balise/' . strtolower($nom_balise_generique)))
475
+            && function_exists('balise_' . $nom_balise_generique . '_dyn')
476
+        ) {
477
+            // et lui injecter en premier arg le nom de la balise
478
+            array_unshift($r, $nom);
479
+            $nom_balise = $nom_balise_generique;
480
+            if (!_DIR_RESTREINT) {
481
+                $file = _DIR_RESTREINT_ABS . $file;
482
+            }
483
+        } else {
484
+            $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
485
+            erreur_squelette($msg, $context_compil);
486
+
487
+            return '';
488
+        }
489
+    }
490
+
491
+    if ($appel_php_depuis_modele) {
492
+        $context_compil['appel_php_depuis_modele'] = true;
493
+    }
494
+    return synthetiser_balise_dynamique($nom_balise, $r, $file, $context_compil);
495 495
 }
496 496
 
497 497
 /**
@@ -506,23 +506,23 @@  discard block
 block discarded – undo
506 506
  * @return array|null
507 507
  */
508 508
 function chercher_balise_generique($nom) {
509
-	if (!str_contains($nom, '_')) {
510
-		return null;
511
-	}
512
-	$nom_generique = $nom;
513
-	while (false !== ($p = strrpos($nom_generique, '_'))) {
514
-		$nom_generique = substr($nom_generique, 0, $p + 1);
515
-		$fonction_generique = charger_fonction($nom_generique, 'balise', true);
516
-		if ($fonction_generique) {
517
-			return [
518
-				'nom' => $nom,
519
-				'nom_generique' => $nom_generique,
520
-				'fonction_generique' => $fonction_generique,
521
-			];
522
-		}
523
-		$nom_generique = substr($nom_generique, 0, -1);
524
-	}
525
-	return null;
509
+    if (!str_contains($nom, '_')) {
510
+        return null;
511
+    }
512
+    $nom_generique = $nom;
513
+    while (false !== ($p = strrpos($nom_generique, '_'))) {
514
+        $nom_generique = substr($nom_generique, 0, $p + 1);
515
+        $fonction_generique = charger_fonction($nom_generique, 'balise', true);
516
+        if ($fonction_generique) {
517
+            return [
518
+                'nom' => $nom,
519
+                'nom_generique' => $nom_generique,
520
+                'fonction_generique' => $fonction_generique,
521
+            ];
522
+        }
523
+        $nom_generique = substr($nom_generique, 0, -1);
524
+    }
525
+    return null;
526 526
 }
527 527
 
528 528
 
@@ -546,51 +546,51 @@  discard block
 block discarded – undo
546 546
  * @return null;
547 547
  **/
548 548
 function lang_select_public($lang, $lang_select, $titre = null) {
549
-	// Cas 1. forcer_lang = true et pas de critere {lang_select}
550
-	if (
551
-		isset($GLOBALS['forcer_lang'])
552
-		&& $GLOBALS['forcer_lang']
553
-		&& $lang_select !== 'oui'
554
-	) {
555
-		$lang = $GLOBALS['spip_lang'];
556
-	} // Cas 2. l'objet n'a pas de langue definie (ou definie a '')
557
-	elseif (!strlen($lang)) {
558
-		$lang = $GLOBALS['spip_lang'];
559
-	} // Cas 3. l'objet est multilingue !
560
-	elseif (
561
-		$lang_select !== 'oui'
562
-		&& strlen($titre) > 10
563
-		&& str_contains($titre, '<multi>')
564
-		&& str_contains(CollecteurHtmlTag::proteger_balisesHtml($titre), '<multi>')
565
-	) {
566
-		$lang = $GLOBALS['spip_lang'];
567
-	}
568
-
569
-	// faire un lang_select() eventuellement sur la langue inchangee
570
-	lang_select($lang);
571
-
572
-	return;
549
+    // Cas 1. forcer_lang = true et pas de critere {lang_select}
550
+    if (
551
+        isset($GLOBALS['forcer_lang'])
552
+        && $GLOBALS['forcer_lang']
553
+        && $lang_select !== 'oui'
554
+    ) {
555
+        $lang = $GLOBALS['spip_lang'];
556
+    } // Cas 2. l'objet n'a pas de langue definie (ou definie a '')
557
+    elseif (!strlen($lang)) {
558
+        $lang = $GLOBALS['spip_lang'];
559
+    } // Cas 3. l'objet est multilingue !
560
+    elseif (
561
+        $lang_select !== 'oui'
562
+        && strlen($titre) > 10
563
+        && str_contains($titre, '<multi>')
564
+        && str_contains(CollecteurHtmlTag::proteger_balisesHtml($titre), '<multi>')
565
+    ) {
566
+        $lang = $GLOBALS['spip_lang'];
567
+    }
568
+
569
+    // faire un lang_select() eventuellement sur la langue inchangee
570
+    lang_select($lang);
571
+
572
+    return;
573 573
 }
574 574
 
575 575
 
576 576
 // Si un tableau &doublons[articles] est passe en parametre,
577 577
 // il faut le nettoyer car il pourrait etre injecte en SQL
578 578
 function nettoyer_env_doublons($envd) {
579
-	foreach ($envd as $table => $liste) {
580
-		$n = '';
581
-		foreach (explode(',', $liste) as $val) {
582
-			if (($a = intval($val)) && $val === strval($a)) {
583
-				$n .= ',' . $val;
584
-			}
585
-		}
586
-		if (strlen($n)) {
587
-			$envd[$table] = $n;
588
-		} else {
589
-			unset($envd[$table]);
590
-		}
591
-	}
592
-
593
-	return $envd;
579
+    foreach ($envd as $table => $liste) {
580
+        $n = '';
581
+        foreach (explode(',', $liste) as $val) {
582
+            if (($a = intval($val)) && $val === strval($a)) {
583
+                $n .= ',' . $val;
584
+            }
585
+        }
586
+        if (strlen($n)) {
587
+            $envd[$table] = $n;
588
+        } else {
589
+            unset($envd[$table]);
590
+        }
591
+    }
592
+
593
+    return $envd;
594 594
 }
595 595
 
596 596
 /**
@@ -609,21 +609,21 @@  discard block
 block discarded – undo
609 609
  *     Opérateur trouvé (SELF ou SUBSELECT) sinon false.
610 610
  **/
611 611
 function match_self($w) {
612
-	if (is_string($w)) {
613
-		return false;
614
-	}
615
-	if (is_array($w)) {
616
-		if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
617
-			return $w;
618
-		}
619
-		foreach (array_filter($w, 'is_array') as $sw) {
620
-			if ($m = match_self($sw)) {
621
-				return $m;
622
-			}
623
-		}
624
-	}
625
-
626
-	return false;
612
+    if (is_string($w)) {
613
+        return false;
614
+    }
615
+    if (is_array($w)) {
616
+        if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
617
+            return $w;
618
+        }
619
+        foreach (array_filter($w, 'is_array') as $sw) {
620
+            if ($m = match_self($sw)) {
621
+                return $m;
622
+            }
623
+        }
624
+    }
625
+
626
+    return false;
627 627
 }
628 628
 
629 629
 /**
@@ -639,16 +639,16 @@  discard block
 block discarded – undo
639 639
  *     est remplacée par son code.
640 640
  **/
641 641
 function remplace_sous_requete($w, $sousrequete) {
642
-	if (is_array($w)) {
643
-		if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
644
-			return $sousrequete;
645
-		}
646
-		foreach ($w as $k => $sw) {
647
-			$w[$k] = remplace_sous_requete($sw, $sousrequete);
648
-		}
649
-	}
650
-
651
-	return $w;
642
+    if (is_array($w)) {
643
+        if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
644
+            return $sousrequete;
645
+        }
646
+        foreach ($w as $k => $sw) {
647
+            $w[$k] = remplace_sous_requete($sw, $sousrequete);
648
+        }
649
+    }
650
+
651
+    return $w;
652 652
 }
653 653
 
654 654
 /**
@@ -662,17 +662,17 @@  discard block
 block discarded – undo
662 662
  *     - Conditions avec des sous requêtes
663 663
  **/
664 664
 function trouver_sous_requetes($where) {
665
-	$where_simples = [];
666
-	$where_sous = [];
667
-	foreach ($where as $k => $w) {
668
-		if (match_self($w)) {
669
-			$where_sous[$k] = $w;
670
-		} else {
671
-			$where_simples[$k] = $w;
672
-		}
673
-	}
674
-
675
-	return [$where_simples, $where_sous];
665
+    $where_simples = [];
666
+    $where_sous = [];
667
+    foreach ($where as $k => $w) {
668
+        if (match_self($w)) {
669
+            $where_sous[$k] = $w;
670
+        } else {
671
+            $where_simples[$k] = $w;
672
+        }
673
+    }
674
+
675
+    return [$where_simples, $where_sous];
676 676
 }
677 677
 
678 678
 
@@ -698,293 +698,293 @@  discard block
 block discarded – undo
698 698
  * @return resource
699 699
  */
700 700
 function calculer_select(
701
-	$select = [],
702
-	$from = [],
703
-	$from_type = [],
704
-	$where = [],
705
-	$join = [],
706
-	$groupby = [],
707
-	$orderby = [],
708
-	$limit = '',
709
-	$having = [],
710
-	$table = '',
711
-	$id = '',
712
-	$serveur = '',
713
-	$requeter = true
701
+    $select = [],
702
+    $from = [],
703
+    $from_type = [],
704
+    $where = [],
705
+    $join = [],
706
+    $groupby = [],
707
+    $orderby = [],
708
+    $limit = '',
709
+    $having = [],
710
+    $table = '',
711
+    $id = '',
712
+    $serveur = '',
713
+    $requeter = true
714 714
 ) {
715 715
 
716
-	// retirer les criteres vides:
717
-	// {X ?} avec X absent de l'URL
718
-	// {par #ENV{X}} avec X absent de l'URL
719
-	// IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil)
720
-	$menage = false;
721
-	foreach ($where as $k => $v) {
722
-		if (is_array($v) && count($v)) {
723
-			if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) {
724
-				$op = false;
725
-			} elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) {
726
-				$op = false;
727
-			} else {
728
-				$op = $v[0] ?: $v;
729
-			}
730
-		} else {
731
-			$op = $v;
732
-		}
733
-		if (!$op || $op == 1 || $op == '0=0') {
734
-			unset($where[$k]);
735
-			$menage = true;
736
-		}
737
-	}
738
-
739
-	// evacuer les eventuels groupby vide issus d'un calcul dynamique
740
-	$groupby = array_diff($groupby, ['']);
741
-
742
-	// remplacer les sous requetes recursives au calcul
743
-	[$where_simples, $where_sous] = trouver_sous_requetes($where);
744
-	foreach ($where_sous as $k => $w) {
745
-		$menage = true;
746
-		// on recupere la sous requete
747
-		$sous = match_self($w);
748
-		if ($sous[0] == 'SELF') {
749
-			// c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where)
750
-			array_push($where_simples, $sous[2]);
751
-			$wheresub = [
752
-				$sous[2],
753
-				'0=0'
754
-			]; // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where
755
-			$jsub = $join;
756
-			// trouver les jointures utiles a
757
-			// reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees
758
-			// ie L1.objet='article'
759
-			// on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction
760
-			$i = 0;
761
-			do {
762
-				$where[$k] = remplace_sous_requete($w, '(' . calculer_select(
763
-					[$sous[1] . ' AS id'],
764
-					$from,
765
-					$from_type,
766
-					$wheresub,
767
-					$jsub,
768
-					[],
769
-					[],
770
-					'',
771
-					$having,
772
-					$table,
773
-					$id,
774
-					$serveur,
775
-					false
776
-				) . ')');
777
-				if (!$i) {
778
-					$i = 1;
779
-					$wherestring = calculer_where_to_string($where[$k]);
780
-					foreach ($join as $cle => $wj) {
781
-						if (
782
-							(is_countable($wj) ? count($wj) : 0) == 4 && str_contains($wherestring, (string) "{$cle}.")
783
-						) {
784
-							$i = 0;
785
-							$wheresub[] = $wj[3];
786
-							unset($jsub[$cle][3]);
787
-						}
788
-					}
789
-				}
790
-			} while ($i++ < 1);
791
-		}
792
-		if ($sous[0] == 'SUBSELECT') {
793
-			// c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having)
794
-			array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ?
795
-			$where[$k] = remplace_sous_requete($w, '(' . calculer_select(
796
-				$sous[1], # select
797
-				$sous[2], #from
798
-				[], #from_type
799
-				$sous[3] ? (is_array($sous[3]) ? $sous[3] : [$sous[3]]) : [],
800
-				#where, qui peut etre de la forme string comme dans sql_select
801
-					[], #join
802
-				$sous[4] ?: [], #groupby
803
-				$sous[5] ?: [], #orderby
804
-				$sous[6], #limit
805
-				$sous[7] ?: [], #having
806
-				$table,
807
-				$id,
808
-				$serveur,
809
-				false
810
-			) . ')');
811
-		}
812
-		array_pop($where_simples);
813
-	}
814
-
815
-	foreach ($having as $k => $v) {
816
-		if (!$v || $v == 1 || $v == '0=0') {
817
-			unset($having[$k]);
818
-		}
819
-	}
820
-
821
-	// Installer les jointures.
822
-	// Retirer celles seulement utiles aux criteres finalement absents mais
823
-	// parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln
824
-	// si elle est seulement utile a Ln+1 elle meme inutile
825
-
826
-	$afrom = [];
827
-	$equiv = [];
828
-	$k = count($join);
829
-	foreach (array_reverse($join, true) as $cledef => $j) {
830
-		$cle = $cledef;
831
-		// le format de join est :
832
-		// array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]])
833
-		$join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber
834
-		if (count($join[$cle]) == 2) {
835
-			$join[$cle][] = $join[$cle][1];
836
-		}
837
-		if ((is_countable($join[$cle]) ? count($join[$cle]) : 0) == 3) {
838
-			$join[$cle][] = '';
839
-		}
840
-		[$t, $c, $carr, $and] = $join[$cle];
841
-		// si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste
842
-		// pour compat avec ancienne convention
843
-		if (is_numeric($cle)) {
844
-			$cle = "L$k";
845
-		}
846
-		$cle_where_lie = "JOIN-$cle";
847
-		if (
848
-			!$menage
849
-			|| isset($afrom[$cle])
850
-			|| calculer_jointnul($cle, $select)
851
-			|| calculer_jointnul($cle, array_diff_key($join, [$cle => $join[$cle]]))
852
-			|| calculer_jointnul($cle, $having)
853
-			|| calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => '']))
854
-		) {
855
-			// corriger les references non explicites dans select
856
-			// ou groupby
857
-			foreach ($select as $i => $s) {
858
-				if ($s == $c) {
859
-					$select[$i] = "$cle.$c AS $c";
860
-					break;
861
-				}
862
-			}
863
-			foreach ($groupby as $i => $g) {
864
-				if ($g == $c) {
865
-					$groupby[$i] = "$cle.$c";
866
-					break;
867
-				}
868
-			}
869
-			// on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin
870
-			// sans recours a preg_match
871
-			// un implode(' ',..) est fait dans reinjecte_joint un peu plus bas
872
-			$afrom[$t][$cle] = [
873
-				"\n" .
874
-				($from_type[$cle] ?? 'INNER') . ' JOIN',
875
-				$from[$cle],
876
-				"AS $cle",
877
-				'ON (',
878
-				"$cle.$c",
879
-				'=',
880
-				"$t.$carr",
881
-				($and ? 'AND ' . $and : '') .
882
-				')'
883
-			];
884
-			if (isset($afrom[$cle])) {
885
-				$afrom[$t] = $afrom[$t] + $afrom[$cle];
886
-				unset($afrom[$cle]);
887
-			}
888
-			$equiv[] = $carr;
889
-		} else {
890
-			unset($join[$cledef]);
891
-			if (isset($where_simples[$cle_where_lie])) {
892
-				unset($where_simples[$cle_where_lie]);
893
-				unset($where[$cle_where_lie]);
894
-			}
895
-		}
896
-		unset($from[$cle]);
897
-		$k--;
898
-	}
899
-
900
-	if (count($afrom)) {
901
-		// Regarder si la table principale ne sert finalement a rien comme dans
902
-		//<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3>
903
-		//<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2>
904
-		//<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5>
905
-		// ou dans
906
-		//<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8>
907
-		// qui comporte plusieurs jointures
908
-		// ou dans
909
-		// <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6>
910
-		// <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7>
911
-		// penser a regarder aussi la clause orderby pour ne pas simplifier abusivement
912
-		// <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9>
913
-		// penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement
914
-		// <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10>
915
-
916
-		$t = key($from);
917
-		$c = current($from);
918
-		reset($from);
919
-		$e = '/\b(' . "$t\\." . join('|' . $t . '\.', $equiv) . ')\b/';
920
-		if (
921
-			!(
922
-				strpos($t, ' ')
923
-				// jointure des le depart cf boucle_doc
924
-				|| calculer_jointnul($t, $select, $e)
925
-				|| calculer_jointnul($t, $join, $e)
926
-				|| calculer_jointnul($t, $where, $e)
927
-				|| calculer_jointnul($t, $orderby, $e)
928
-				|| calculer_jointnul($t, $groupby, $e) || calculer_jointnul($t, $having, $e)
929
-			)
930
-			&& count($afrom[$t])
931
-		) {
932
-			$nfrom = reset($afrom[$t]);
933
-			$nt = array_key_first($afrom[$t]);
934
-			unset($from[$t]);
935
-			$from[$nt] = $nfrom[1];
936
-			unset($afrom[$t][$nt]);
937
-			$afrom[$nt] = $afrom[$t];
938
-			unset($afrom[$t]);
939
-			$e = '/\b' . preg_quote($nfrom[6]) . '\b/';
940
-			$t = $nfrom[4];
941
-			$alias = '';
942
-			// verifier que les deux cles sont homonymes, sinon installer un alias dans le select
943
-			$oldcle = explode('.', $nfrom[6]);
944
-			$oldcle = end($oldcle);
945
-			$newcle = explode('.', $nfrom[4]);
946
-			$newcle = end($newcle);
947
-			if ($newcle != $oldcle) {
948
-				// si l'ancienne cle etait deja dans le select avec un AS
949
-				// reprendre simplement ce AS
950
-				$as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/';
951
-				if (preg_match($as, implode(',', $select), $m)) {
952
-					$alias = '';
953
-				} else {
954
-					$alias = ', ' . $nfrom[4] . " AS $oldcle";
955
-				}
956
-			}
957
-			$select = remplacer_jointnul($t . $alias, $select, $e);
958
-			$join = remplacer_jointnul($t, $join, $e);
959
-			$where = remplacer_jointnul($t, $where, $e);
960
-			$having = remplacer_jointnul($t, $having, $e);
961
-			$groupby = remplacer_jointnul($t, $groupby, $e);
962
-			$orderby = remplacer_jointnul($t, $orderby, $e);
963
-		}
964
-		$from = reinjecte_joint($afrom, $from);
965
-	}
966
-	if (empty($GLOBALS['debug']) || !is_array($GLOBALS['debug'])) {
967
-		$wasdebug = empty($GLOBALS['debug']) ? false : $GLOBALS['debug'];
968
-		$GLOBALS['debug'] = [];
969
-		if ($wasdebug) {
970
-			$GLOBALS['debug']['debug'] = true;
971
-		}
972
-	}
973
-	$GLOBALS['debug']['aucasou'] = [$table, $id, $serveur, $requeter];
974
-	$r = sql_select(
975
-		$select,
976
-		$from,
977
-		$where,
978
-		$groupby,
979
-		array_filter($orderby),
980
-		$limit,
981
-		$having,
982
-		$serveur,
983
-		$requeter
984
-	);
985
-	unset($GLOBALS['debug']['aucasou']);
986
-
987
-	return $r;
716
+    // retirer les criteres vides:
717
+    // {X ?} avec X absent de l'URL
718
+    // {par #ENV{X}} avec X absent de l'URL
719
+    // IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil)
720
+    $menage = false;
721
+    foreach ($where as $k => $v) {
722
+        if (is_array($v) && count($v)) {
723
+            if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) {
724
+                $op = false;
725
+            } elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) {
726
+                $op = false;
727
+            } else {
728
+                $op = $v[0] ?: $v;
729
+            }
730
+        } else {
731
+            $op = $v;
732
+        }
733
+        if (!$op || $op == 1 || $op == '0=0') {
734
+            unset($where[$k]);
735
+            $menage = true;
736
+        }
737
+    }
738
+
739
+    // evacuer les eventuels groupby vide issus d'un calcul dynamique
740
+    $groupby = array_diff($groupby, ['']);
741
+
742
+    // remplacer les sous requetes recursives au calcul
743
+    [$where_simples, $where_sous] = trouver_sous_requetes($where);
744
+    foreach ($where_sous as $k => $w) {
745
+        $menage = true;
746
+        // on recupere la sous requete
747
+        $sous = match_self($w);
748
+        if ($sous[0] == 'SELF') {
749
+            // c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where)
750
+            array_push($where_simples, $sous[2]);
751
+            $wheresub = [
752
+                $sous[2],
753
+                '0=0'
754
+            ]; // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where
755
+            $jsub = $join;
756
+            // trouver les jointures utiles a
757
+            // reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees
758
+            // ie L1.objet='article'
759
+            // on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction
760
+            $i = 0;
761
+            do {
762
+                $where[$k] = remplace_sous_requete($w, '(' . calculer_select(
763
+                    [$sous[1] . ' AS id'],
764
+                    $from,
765
+                    $from_type,
766
+                    $wheresub,
767
+                    $jsub,
768
+                    [],
769
+                    [],
770
+                    '',
771
+                    $having,
772
+                    $table,
773
+                    $id,
774
+                    $serveur,
775
+                    false
776
+                ) . ')');
777
+                if (!$i) {
778
+                    $i = 1;
779
+                    $wherestring = calculer_where_to_string($where[$k]);
780
+                    foreach ($join as $cle => $wj) {
781
+                        if (
782
+                            (is_countable($wj) ? count($wj) : 0) == 4 && str_contains($wherestring, (string) "{$cle}.")
783
+                        ) {
784
+                            $i = 0;
785
+                            $wheresub[] = $wj[3];
786
+                            unset($jsub[$cle][3]);
787
+                        }
788
+                    }
789
+                }
790
+            } while ($i++ < 1);
791
+        }
792
+        if ($sous[0] == 'SUBSELECT') {
793
+            // c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having)
794
+            array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ?
795
+            $where[$k] = remplace_sous_requete($w, '(' . calculer_select(
796
+                $sous[1], # select
797
+                $sous[2], #from
798
+                [], #from_type
799
+                $sous[3] ? (is_array($sous[3]) ? $sous[3] : [$sous[3]]) : [],
800
+                #where, qui peut etre de la forme string comme dans sql_select
801
+                    [], #join
802
+                $sous[4] ?: [], #groupby
803
+                $sous[5] ?: [], #orderby
804
+                $sous[6], #limit
805
+                $sous[7] ?: [], #having
806
+                $table,
807
+                $id,
808
+                $serveur,
809
+                false
810
+            ) . ')');
811
+        }
812
+        array_pop($where_simples);
813
+    }
814
+
815
+    foreach ($having as $k => $v) {
816
+        if (!$v || $v == 1 || $v == '0=0') {
817
+            unset($having[$k]);
818
+        }
819
+    }
820
+
821
+    // Installer les jointures.
822
+    // Retirer celles seulement utiles aux criteres finalement absents mais
823
+    // parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln
824
+    // si elle est seulement utile a Ln+1 elle meme inutile
825
+
826
+    $afrom = [];
827
+    $equiv = [];
828
+    $k = count($join);
829
+    foreach (array_reverse($join, true) as $cledef => $j) {
830
+        $cle = $cledef;
831
+        // le format de join est :
832
+        // array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]])
833
+        $join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber
834
+        if (count($join[$cle]) == 2) {
835
+            $join[$cle][] = $join[$cle][1];
836
+        }
837
+        if ((is_countable($join[$cle]) ? count($join[$cle]) : 0) == 3) {
838
+            $join[$cle][] = '';
839
+        }
840
+        [$t, $c, $carr, $and] = $join[$cle];
841
+        // si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste
842
+        // pour compat avec ancienne convention
843
+        if (is_numeric($cle)) {
844
+            $cle = "L$k";
845
+        }
846
+        $cle_where_lie = "JOIN-$cle";
847
+        if (
848
+            !$menage
849
+            || isset($afrom[$cle])
850
+            || calculer_jointnul($cle, $select)
851
+            || calculer_jointnul($cle, array_diff_key($join, [$cle => $join[$cle]]))
852
+            || calculer_jointnul($cle, $having)
853
+            || calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => '']))
854
+        ) {
855
+            // corriger les references non explicites dans select
856
+            // ou groupby
857
+            foreach ($select as $i => $s) {
858
+                if ($s == $c) {
859
+                    $select[$i] = "$cle.$c AS $c";
860
+                    break;
861
+                }
862
+            }
863
+            foreach ($groupby as $i => $g) {
864
+                if ($g == $c) {
865
+                    $groupby[$i] = "$cle.$c";
866
+                    break;
867
+                }
868
+            }
869
+            // on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin
870
+            // sans recours a preg_match
871
+            // un implode(' ',..) est fait dans reinjecte_joint un peu plus bas
872
+            $afrom[$t][$cle] = [
873
+                "\n" .
874
+                ($from_type[$cle] ?? 'INNER') . ' JOIN',
875
+                $from[$cle],
876
+                "AS $cle",
877
+                'ON (',
878
+                "$cle.$c",
879
+                '=',
880
+                "$t.$carr",
881
+                ($and ? 'AND ' . $and : '') .
882
+                ')'
883
+            ];
884
+            if (isset($afrom[$cle])) {
885
+                $afrom[$t] = $afrom[$t] + $afrom[$cle];
886
+                unset($afrom[$cle]);
887
+            }
888
+            $equiv[] = $carr;
889
+        } else {
890
+            unset($join[$cledef]);
891
+            if (isset($where_simples[$cle_where_lie])) {
892
+                unset($where_simples[$cle_where_lie]);
893
+                unset($where[$cle_where_lie]);
894
+            }
895
+        }
896
+        unset($from[$cle]);
897
+        $k--;
898
+    }
899
+
900
+    if (count($afrom)) {
901
+        // Regarder si la table principale ne sert finalement a rien comme dans
902
+        //<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3>
903
+        //<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2>
904
+        //<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5>
905
+        // ou dans
906
+        //<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8>
907
+        // qui comporte plusieurs jointures
908
+        // ou dans
909
+        // <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6>
910
+        // <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7>
911
+        // penser a regarder aussi la clause orderby pour ne pas simplifier abusivement
912
+        // <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9>
913
+        // penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement
914
+        // <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10>
915
+
916
+        $t = key($from);
917
+        $c = current($from);
918
+        reset($from);
919
+        $e = '/\b(' . "$t\\." . join('|' . $t . '\.', $equiv) . ')\b/';
920
+        if (
921
+            !(
922
+                strpos($t, ' ')
923
+                // jointure des le depart cf boucle_doc
924
+                || calculer_jointnul($t, $select, $e)
925
+                || calculer_jointnul($t, $join, $e)
926
+                || calculer_jointnul($t, $where, $e)
927
+                || calculer_jointnul($t, $orderby, $e)
928
+                || calculer_jointnul($t, $groupby, $e) || calculer_jointnul($t, $having, $e)
929
+            )
930
+            && count($afrom[$t])
931
+        ) {
932
+            $nfrom = reset($afrom[$t]);
933
+            $nt = array_key_first($afrom[$t]);
934
+            unset($from[$t]);
935
+            $from[$nt] = $nfrom[1];
936
+            unset($afrom[$t][$nt]);
937
+            $afrom[$nt] = $afrom[$t];
938
+            unset($afrom[$t]);
939
+            $e = '/\b' . preg_quote($nfrom[6]) . '\b/';
940
+            $t = $nfrom[4];
941
+            $alias = '';
942
+            // verifier que les deux cles sont homonymes, sinon installer un alias dans le select
943
+            $oldcle = explode('.', $nfrom[6]);
944
+            $oldcle = end($oldcle);
945
+            $newcle = explode('.', $nfrom[4]);
946
+            $newcle = end($newcle);
947
+            if ($newcle != $oldcle) {
948
+                // si l'ancienne cle etait deja dans le select avec un AS
949
+                // reprendre simplement ce AS
950
+                $as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/';
951
+                if (preg_match($as, implode(',', $select), $m)) {
952
+                    $alias = '';
953
+                } else {
954
+                    $alias = ', ' . $nfrom[4] . " AS $oldcle";
955
+                }
956
+            }
957
+            $select = remplacer_jointnul($t . $alias, $select, $e);
958
+            $join = remplacer_jointnul($t, $join, $e);
959
+            $where = remplacer_jointnul($t, $where, $e);
960
+            $having = remplacer_jointnul($t, $having, $e);
961
+            $groupby = remplacer_jointnul($t, $groupby, $e);
962
+            $orderby = remplacer_jointnul($t, $orderby, $e);
963
+        }
964
+        $from = reinjecte_joint($afrom, $from);
965
+    }
966
+    if (empty($GLOBALS['debug']) || !is_array($GLOBALS['debug'])) {
967
+        $wasdebug = empty($GLOBALS['debug']) ? false : $GLOBALS['debug'];
968
+        $GLOBALS['debug'] = [];
969
+        if ($wasdebug) {
970
+            $GLOBALS['debug']['debug'] = true;
971
+        }
972
+    }
973
+    $GLOBALS['debug']['aucasou'] = [$table, $id, $serveur, $requeter];
974
+    $r = sql_select(
975
+        $select,
976
+        $from,
977
+        $where,
978
+        $groupby,
979
+        array_filter($orderby),
980
+        $limit,
981
+        $having,
982
+        $serveur,
983
+        $requeter
984
+    );
985
+    unset($GLOBALS['debug']['aucasou']);
986
+
987
+    return $r;
988 988
 }
989 989
 
990 990
 /**
@@ -995,79 +995,79 @@  discard block
 block discarded – undo
995 995
  * @return string
996 996
  */
997 997
 function calculer_where_to_string($v, $join = 'AND') {
998
-	if (empty($v)) {
999
-		return '';
1000
-	}
1001
-
1002
-	if (!is_array($v)) {
1003
-		return $v;
1004
-	} else {
1005
-		$exp = '';
1006
-		if (strtoupper($join) === 'AND') {
1007
-			return $exp . join(" $join ", array_map('calculer_where_to_string', $v));
1008
-		} else {
1009
-			return $exp . join($join, $v);
1010
-		}
1011
-	}
998
+    if (empty($v)) {
999
+        return '';
1000
+    }
1001
+
1002
+    if (!is_array($v)) {
1003
+        return $v;
1004
+    } else {
1005
+        $exp = '';
1006
+        if (strtoupper($join) === 'AND') {
1007
+            return $exp . join(" $join ", array_map('calculer_where_to_string', $v));
1008
+        } else {
1009
+            return $exp . join($join, $v);
1010
+        }
1011
+    }
1012 1012
 }
1013 1013
 
1014 1014
 
1015 1015
 //condition suffisante (mais non necessaire) pour qu'une table soit utile
1016 1016
 
1017 1017
 function calculer_jointnul($cle, $exp, $equiv = '') {
1018
-	if (!is_array($exp)) {
1019
-		if ($equiv) {
1020
-			$exp = preg_replace($equiv, '', $exp);
1021
-		}
1022
-
1023
-		return preg_match("/\\b$cle\\./", $exp);
1024
-	} else {
1025
-		foreach ($exp as $v) {
1026
-			if (calculer_jointnul($cle, $v, $equiv)) {
1027
-				return true;
1028
-			}
1029
-		}
1030
-
1031
-		return false;
1032
-	}
1018
+    if (!is_array($exp)) {
1019
+        if ($equiv) {
1020
+            $exp = preg_replace($equiv, '', $exp);
1021
+        }
1022
+
1023
+        return preg_match("/\\b$cle\\./", $exp);
1024
+    } else {
1025
+        foreach ($exp as $v) {
1026
+            if (calculer_jointnul($cle, $v, $equiv)) {
1027
+                return true;
1028
+            }
1029
+        }
1030
+
1031
+        return false;
1032
+    }
1033 1033
 }
1034 1034
 
1035 1035
 function reinjecte_joint($afrom, $from) {
1036
-	$from_synth = [];
1037
-	foreach ($from as $k => $v) {
1038
-		$from_synth[$k] = $from[$k];
1039
-		if (isset($afrom[$k])) {
1040
-			foreach ($afrom[$k] as $kk => $vv) {
1041
-				$afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]);
1042
-			}
1043
-			$from_synth["$k@"] = implode(' ', $afrom[$k]);
1044
-			unset($afrom[$k]);
1045
-		}
1046
-	}
1047
-
1048
-	return $from_synth;
1036
+    $from_synth = [];
1037
+    foreach ($from as $k => $v) {
1038
+        $from_synth[$k] = $from[$k];
1039
+        if (isset($afrom[$k])) {
1040
+            foreach ($afrom[$k] as $kk => $vv) {
1041
+                $afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]);
1042
+            }
1043
+            $from_synth["$k@"] = implode(' ', $afrom[$k]);
1044
+            unset($afrom[$k]);
1045
+        }
1046
+    }
1047
+
1048
+    return $from_synth;
1049 1049
 }
1050 1050
 
1051 1051
 function remplacer_jointnul($cle, $exp, $equiv = '') {
1052
-	if (!is_array($exp)) {
1053
-		return preg_replace($equiv, $cle, $exp);
1054
-	} else {
1055
-		foreach ($exp as $k => $v) {
1056
-			$exp[$k] = remplacer_jointnul($cle, $v, $equiv);
1057
-		}
1058
-
1059
-		return $exp;
1060
-	}
1052
+    if (!is_array($exp)) {
1053
+        return preg_replace($equiv, $cle, $exp);
1054
+    } else {
1055
+        foreach ($exp as $k => $v) {
1056
+            $exp[$k] = remplacer_jointnul($cle, $v, $equiv);
1057
+        }
1058
+
1059
+        return $exp;
1060
+    }
1061 1061
 }
1062 1062
 
1063 1063
 // calcul du nom du squelette
1064 1064
 function calculer_nom_fonction_squel($skel, $mime_type = 'html', string $connect = '') {
1065
-	// ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine
1066
-	if (($l = strlen(_DIR_RACINE)) && strncmp($skel, _DIR_RACINE, $l) == 0) {
1067
-		$skel = substr($skel, strlen(_DIR_RACINE));
1068
-	}
1069
-
1070
-	return $mime_type
1071
-	. (!$connect ? '' : preg_replace('/\W/', '_', $connect)) . '_'
1072
-	. md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : ''));
1065
+    // ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine
1066
+    if (($l = strlen(_DIR_RACINE)) && strncmp($skel, _DIR_RACINE, $l) == 0) {
1067
+        $skel = substr($skel, strlen(_DIR_RACINE));
1068
+    }
1069
+
1070
+    return $mime_type
1071
+    . (!$connect ? '' : preg_replace('/\W/', '_', $connect)) . '_'
1072
+    . md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : ''));
1073 1073
 }
Please login to merge, or discard this patch.