Completed
Push — master ( 6ed852...137dab )
by cam
01:45
created
ecrire/public/phraser_html.php 1 patch
Indentation   +1032 added lines, -1032 removed lines patch added patch discarded remove patch
@@ -28,7 +28,7 @@  discard block
 block discarded – undo
28 28
  **/
29 29
 
30 30
 if (!defined('_ECRIRE_INC_VERSION')) {
31
-	return;
31
+    return;
32 32
 }
33 33
 
34 34
 /** Début de la partie principale d'une boucle */
@@ -72,82 +72,82 @@  discard block
 block discarded – undo
72 72
 
73 73
 function phraser_inclure($texte, $ligne, $result) {
74 74
 
75
-	while (preg_match(BALISE_INCLURE, $texte, $match)) {
76
-		$match = array_pad($match, 3, null);
77
-		$p = strpos($texte, (string) $match[0]);
78
-		$debut = substr($texte, 0, $p);
79
-		if ($p) {
80
-			$result = phraser_idiomes($debut, $ligne, $result);
81
-		}
82
-		$ligne += substr_count($debut, "\n");
83
-		$champ = new Inclure();
84
-		$champ->ligne = $ligne;
85
-		$ligne += substr_count($match[0], "\n");
86
-		$fichier = $match[2];
87
-		# assurer ici la migration .php3 => .php
88
-		# et de l'ancienne syntaxe INCLURE(page.php3) devenue surperflue
89
-		if ($fichier and preg_match(',^(.*[.]php)3$,', $fichier, $r)) {
90
-			$fichier = $r[1];
91
-		}
92
-		$champ->texte = ($fichier !== 'page.php') ? $fichier : '';
93
-		$texte = substr($texte, $p + strlen($match[0]));
94
-		// on assimile {var=val} a une liste de un argument sans fonction
95
-		$pos_apres = 0;
96
-		phraser_args($texte, '/>', '', $result, $champ, $pos_apres);
97
-		if (!$champ->texte or (is_countable($champ->param) ? count($champ->param) : 0) > 1) {
98
-			if (!function_exists('normaliser_inclure')) {
99
-				include_spip('public/normaliser');
100
-			}
101
-			normaliser_inclure($champ);
102
-		}
103
-		$texte = substr($texte, strpos($texte, '>', $pos_apres) + 1);
104
-		$texte = preg_replace(',^</INCLU[DR]E>,', '', $texte);
105
-		$result[] = $champ;
106
-	}
107
-
108
-	return (($texte === '') ? $result : phraser_idiomes($texte, $ligne, $result));
75
+    while (preg_match(BALISE_INCLURE, $texte, $match)) {
76
+        $match = array_pad($match, 3, null);
77
+        $p = strpos($texte, (string) $match[0]);
78
+        $debut = substr($texte, 0, $p);
79
+        if ($p) {
80
+            $result = phraser_idiomes($debut, $ligne, $result);
81
+        }
82
+        $ligne += substr_count($debut, "\n");
83
+        $champ = new Inclure();
84
+        $champ->ligne = $ligne;
85
+        $ligne += substr_count($match[0], "\n");
86
+        $fichier = $match[2];
87
+        # assurer ici la migration .php3 => .php
88
+        # et de l'ancienne syntaxe INCLURE(page.php3) devenue surperflue
89
+        if ($fichier and preg_match(',^(.*[.]php)3$,', $fichier, $r)) {
90
+            $fichier = $r[1];
91
+        }
92
+        $champ->texte = ($fichier !== 'page.php') ? $fichier : '';
93
+        $texte = substr($texte, $p + strlen($match[0]));
94
+        // on assimile {var=val} a une liste de un argument sans fonction
95
+        $pos_apres = 0;
96
+        phraser_args($texte, '/>', '', $result, $champ, $pos_apres);
97
+        if (!$champ->texte or (is_countable($champ->param) ? count($champ->param) : 0) > 1) {
98
+            if (!function_exists('normaliser_inclure')) {
99
+                include_spip('public/normaliser');
100
+            }
101
+            normaliser_inclure($champ);
102
+        }
103
+        $texte = substr($texte, strpos($texte, '>', $pos_apres) + 1);
104
+        $texte = preg_replace(',^</INCLU[DR]E>,', '', $texte);
105
+        $result[] = $champ;
106
+    }
107
+
108
+    return (($texte === '') ? $result : phraser_idiomes($texte, $ligne, $result));
109 109
 }
110 110
 
111 111
 function phraser_polyglotte($texte, $ligne, $result) {
112 112
 
113
-	if (preg_match_all(BALISE_POLYGLOTTE, $texte, $m, PREG_SET_ORDER)) {
114
-		foreach ($m as $match) {
115
-			$p = strpos($texte, (string) $match[0]);
116
-			$debut = substr($texte, 0, $p);
117
-			if ($p) {
118
-				$champ = new Texte();
119
-				$champ->texte = $debut;
120
-				$champ->ligne = $ligne;
121
-				$result[] = $champ;
122
-				$ligne += substr_count($champ->texte, "\n");
123
-			}
124
-
125
-			$champ = new Polyglotte();
126
-			$champ->ligne = $ligne;
127
-			$ligne += substr_count($match[0], "\n");
128
-			$lang = '';
129
-			$bloc = $match[1];
130
-			$texte = substr($texte, $p + strlen($match[0]));
131
-			while (preg_match('/^[[:space:]]*([^[{]*)[[:space:]]*[[{]([a-z_]+)[]}](.*)$/si', $bloc, $regs)) {
132
-				$trad = $regs[1];
133
-				if ($trad or $lang) {
134
-					$champ->traductions[$lang] = $trad;
135
-				}
136
-				$lang = $regs[2];
137
-				$bloc = $regs[3];
138
-			}
139
-			$champ->traductions[$lang] = $bloc;
140
-			$result[] = $champ;
141
-		}
142
-	}
143
-	if ($texte !== '') {
144
-		$champ = new Texte();
145
-		$champ->texte = $texte;
146
-		$champ->ligne = $ligne;
147
-		$result[] = $champ;
148
-	}
149
-
150
-	return $result;
113
+    if (preg_match_all(BALISE_POLYGLOTTE, $texte, $m, PREG_SET_ORDER)) {
114
+        foreach ($m as $match) {
115
+            $p = strpos($texte, (string) $match[0]);
116
+            $debut = substr($texte, 0, $p);
117
+            if ($p) {
118
+                $champ = new Texte();
119
+                $champ->texte = $debut;
120
+                $champ->ligne = $ligne;
121
+                $result[] = $champ;
122
+                $ligne += substr_count($champ->texte, "\n");
123
+            }
124
+
125
+            $champ = new Polyglotte();
126
+            $champ->ligne = $ligne;
127
+            $ligne += substr_count($match[0], "\n");
128
+            $lang = '';
129
+            $bloc = $match[1];
130
+            $texte = substr($texte, $p + strlen($match[0]));
131
+            while (preg_match('/^[[:space:]]*([^[{]*)[[:space:]]*[[{]([a-z_]+)[]}](.*)$/si', $bloc, $regs)) {
132
+                $trad = $regs[1];
133
+                if ($trad or $lang) {
134
+                    $champ->traductions[$lang] = $trad;
135
+                }
136
+                $lang = $regs[2];
137
+                $bloc = $regs[3];
138
+            }
139
+            $champ->traductions[$lang] = $bloc;
140
+            $result[] = $champ;
141
+        }
142
+    }
143
+    if ($texte !== '') {
144
+        $champ = new Texte();
145
+        $champ->texte = $texte;
146
+        $champ->ligne = $ligne;
147
+        $result[] = $champ;
148
+    }
149
+
150
+    return $result;
151 151
 }
152 152
 
153 153
 
@@ -169,43 +169,43 @@  discard block
 block discarded – undo
169 169
  * @return array
170 170
  **/
171 171
 function phraser_idiomes($texte, $ligne, $result) {
172
-	while (preg_match(BALISE_IDIOMES, $texte, $match)) {
173
-		$match = array_pad($match, 8, null);
174
-		$p = strpos($texte, (string) $match[0]);
175
-		$ko = (!$match[3] && ($match[5][0] !== '='));
176
-		$debut = substr($texte, 0, $p + ($ko ? strlen($match[0]) : 0));
177
-		if ($debut) {
178
-			$result = phraser_champs($debut, $ligne, $result);
179
-		}
180
-		$texte = substr($texte, $p + strlen($match[0]));
181
-		$ligne += substr_count($debut, "\n");
182
-		if ($ko) {
183
-			continue;
184
-		} // faux idiome
185
-		$champ = new Idiome();
186
-		$champ->ligne = $ligne;
187
-		$ligne += substr_count($match[0], "\n");
188
-		// Stocker les arguments de la balise de traduction
189
-		$args = [];
190
-		$largs = $match[5];
191
-		while (preg_match(BALISE_IDIOMES_ARGS, $largs, $r)) {
192
-			$args[$r[1]] = phraser_champs($r[2], 0, []);
193
-			$largs = substr($largs, strlen($r[0]));
194
-		}
195
-		$champ->arg = $args;
196
-		$champ->nom_champ = strtolower($match[3]);
197
-		$champ->module = $match[2];
198
-		// pas d'imbrication pour les filtres sur langue
199
-		$pos_apres = 0;
200
-		phraser_args($match[7] ?? '', ':', '', [], $champ, $pos_apres);
201
-		$champ->apres = substr($match[7] ?? '', $pos_apres);
202
-		$result[] = $champ;
203
-	}
204
-	if ($texte !== '') {
205
-		$result = phraser_champs($texte, $ligne, $result);
206
-	}
207
-
208
-	return $result;
172
+    while (preg_match(BALISE_IDIOMES, $texte, $match)) {
173
+        $match = array_pad($match, 8, null);
174
+        $p = strpos($texte, (string) $match[0]);
175
+        $ko = (!$match[3] && ($match[5][0] !== '='));
176
+        $debut = substr($texte, 0, $p + ($ko ? strlen($match[0]) : 0));
177
+        if ($debut) {
178
+            $result = phraser_champs($debut, $ligne, $result);
179
+        }
180
+        $texte = substr($texte, $p + strlen($match[0]));
181
+        $ligne += substr_count($debut, "\n");
182
+        if ($ko) {
183
+            continue;
184
+        } // faux idiome
185
+        $champ = new Idiome();
186
+        $champ->ligne = $ligne;
187
+        $ligne += substr_count($match[0], "\n");
188
+        // Stocker les arguments de la balise de traduction
189
+        $args = [];
190
+        $largs = $match[5];
191
+        while (preg_match(BALISE_IDIOMES_ARGS, $largs, $r)) {
192
+            $args[$r[1]] = phraser_champs($r[2], 0, []);
193
+            $largs = substr($largs, strlen($r[0]));
194
+        }
195
+        $champ->arg = $args;
196
+        $champ->nom_champ = strtolower($match[3]);
197
+        $champ->module = $match[2];
198
+        // pas d'imbrication pour les filtres sur langue
199
+        $pos_apres = 0;
200
+        phraser_args($match[7] ?? '', ':', '', [], $champ, $pos_apres);
201
+        $champ->apres = substr($match[7] ?? '', $pos_apres);
202
+        $result[] = $champ;
203
+    }
204
+    if ($texte !== '') {
205
+        $result = phraser_champs($texte, $ligne, $result);
206
+    }
207
+
208
+    return $result;
209 209
 }
210 210
 
211 211
 /**
@@ -223,47 +223,47 @@  discard block
 block discarded – undo
223 223
  * @return array
224 224
  **/
225 225
 function phraser_champs($texte, $ligne, $result) {
226
-	while (preg_match('/' . NOM_DE_CHAMP . '/S', $texte, $match)) {
227
-		$p = strpos($texte, (string) $match[0]);
228
-		// texte après la balise
229
-		$suite = substr($texte, $p + strlen($match[0]));
230
-
231
-		$debut = substr($texte, 0, $p);
232
-		if ($p) {
233
-			$result = phraser_polyglotte($debut, $ligne, $result);
234
-		}
235
-		$ligne += substr_count($debut, "\n");
236
-		$champ = new Champ();
237
-		$champ->ligne = $ligne;
238
-		$ligne += substr_count($match[0], "\n");
239
-		$champ->nom_boucle = $match[2];
240
-		$champ->nom_champ = $match[3];
241
-		$champ->etoile = $match[5];
242
-
243
-		if ($suite and $suite[0] == '{') {
244
-			phraser_arg($suite, '', [], $champ);
245
-			// ce ltrim est une ereur de conception
246
-			// mais on le conserve par souci de compatibilite
247
-			$texte = ltrim($suite);
248
-			// Il faudrait le normaliser dans l'arbre de syntaxe abstraite
249
-			// pour faire sauter ce cas particulier a la decompilation.
250
-			/* Ce qui suit est malheureusement incomplet pour cela:
226
+    while (preg_match('/' . NOM_DE_CHAMP . '/S', $texte, $match)) {
227
+        $p = strpos($texte, (string) $match[0]);
228
+        // texte après la balise
229
+        $suite = substr($texte, $p + strlen($match[0]));
230
+
231
+        $debut = substr($texte, 0, $p);
232
+        if ($p) {
233
+            $result = phraser_polyglotte($debut, $ligne, $result);
234
+        }
235
+        $ligne += substr_count($debut, "\n");
236
+        $champ = new Champ();
237
+        $champ->ligne = $ligne;
238
+        $ligne += substr_count($match[0], "\n");
239
+        $champ->nom_boucle = $match[2];
240
+        $champ->nom_champ = $match[3];
241
+        $champ->etoile = $match[5];
242
+
243
+        if ($suite and $suite[0] == '{') {
244
+            phraser_arg($suite, '', [], $champ);
245
+            // ce ltrim est une ereur de conception
246
+            // mais on le conserve par souci de compatibilite
247
+            $texte = ltrim($suite);
248
+            // Il faudrait le normaliser dans l'arbre de syntaxe abstraite
249
+            // pour faire sauter ce cas particulier a la decompilation.
250
+            /* Ce qui suit est malheureusement incomplet pour cela:
251 251
 			if ($n = (strlen($suite) - strlen($texte))) {
252 252
 				$champ->apres = array(new Texte);
253 253
 				$champ->apres[0]->texte = substr($suite,0,$n);
254 254
 			}
255 255
 			*/
256
-		} else {
257
-			$texte = $suite;
258
-		}
259
-		phraser_vieux($champ);
260
-		$result[] = $champ;
261
-	}
262
-	if ($texte !== '') {
263
-		$result = phraser_polyglotte($texte, $ligne, $result);
264
-	}
265
-
266
-	return $result;
256
+        } else {
257
+            $texte = $suite;
258
+        }
259
+        phraser_vieux($champ);
260
+        $result[] = $champ;
261
+    }
262
+    if ($texte !== '') {
263
+        $result = phraser_polyglotte($texte, $ligne, $result);
264
+    }
265
+
266
+    return $result;
267 267
 }
268 268
 
269 269
 // Gestion des imbrications:
@@ -272,15 +272,15 @@  discard block
 block discarded – undo
272 272
 // on recommence tant qu'il y a des [...] en substituant a l'appel suivant
273 273
 
274 274
 function phraser_champs_etendus($texte, $ligne, $result) {
275
-	if ($texte === '') {
276
-		return $result;
277
-	}
278
-	$sep = '##';
279
-	while (strpos($texte, (string) $sep) !== false) {
280
-		$sep .= '#';
281
-	}
282
-
283
-	return array_merge($result, phraser_champs_interieurs($texte, $ligne, $sep, []));
275
+    if ($texte === '') {
276
+        return $result;
277
+    }
278
+    $sep = '##';
279
+    while (strpos($texte, (string) $sep) !== false) {
280
+        $sep .= '#';
281
+    }
282
+
283
+    return array_merge($result, phraser_champs_interieurs($texte, $ligne, $sep, []));
284 284
 }
285 285
 
286 286
 /**
@@ -299,275 +299,275 @@  discard block
 block discarded – undo
299 299
  * @return array
300 300
  */
301 301
 function phraser_args(string $texte, $fin, $sep, $result, &$pointeur_champ, &$pos_debut) {
302
-	$length = strlen($texte);
303
-	while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
304
-		$pos_debut++;
305
-	}
306
-	while (($pos_debut < $length) && !str_contains($fin, $texte[$pos_debut])) {
307
-		// phraser_arg modifie directement le $texte, on fait donc avec ici en passant par une sous chaine
308
-		$st = substr($texte, $pos_debut);
309
-		$result = phraser_arg($st, $sep, $result, $pointeur_champ);
310
-		$pos_debut = $length - strlen($st);
311
-		while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
312
-			$pos_debut++;
313
-		}
314
-	}
315
-
316
-	return $result;
302
+    $length = strlen($texte);
303
+    while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
304
+        $pos_debut++;
305
+    }
306
+    while (($pos_debut < $length) && !str_contains($fin, $texte[$pos_debut])) {
307
+        // phraser_arg modifie directement le $texte, on fait donc avec ici en passant par une sous chaine
308
+        $st = substr($texte, $pos_debut);
309
+        $result = phraser_arg($st, $sep, $result, $pointeur_champ);
310
+        $pos_debut = $length - strlen($st);
311
+        while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
312
+            $pos_debut++;
313
+        }
314
+    }
315
+
316
+    return $result;
317 317
 }
318 318
 
319 319
 function phraser_arg(&$texte, $sep, $result, &$pointeur_champ) {
320
-	preg_match(',^(\|?[^}{)|]*)(.*)$,ms', $texte, $match);
321
-	$suite = ltrim($match[2]);
322
-	$fonc = trim($match[1]);
323
-	if ($fonc && $fonc[0] == '|') {
324
-		$fonc = ltrim(substr($fonc, 1));
325
-	}
326
-	$res = [$fonc];
327
-	$err_f = '';
328
-	// cas du filtre sans argument ou du critere /
329
-	if (($suite && ($suite[0] != '{')) || ($fonc && $fonc[0] == '/')) {
330
-		// si pas d'argument, alors il faut une fonction ou un double |
331
-		if (!$match[1]) {
332
-			$err_f = ['zbug_erreur_filtre', ['filtre' => $texte]];
333
-			erreur_squelette($err_f, $pointeur_champ);
334
-			$texte = '';
335
-		} else {
336
-			$texte = $suite;
337
-		}
338
-		if ($err_f) {
339
-			$pointeur_champ->param = false;
340
-		} elseif ($fonc !== '') {
341
-			$pointeur_champ->param[] = $res;
342
-		}
343
-		// pour les balises avec faux filtres qui boudent ce dur larbeur
344
-		$pointeur_champ->fonctions[] = [$fonc, ''];
345
-
346
-		return $result;
347
-	}
348
-	$args = ltrim(substr($suite, 1)); // virer le '(' initial
349
-	$collecte = [];
350
-	while ($args && $args[0] != '}') {
351
-		if ($args[0] == '"') {
352
-			preg_match('/^(")([^"]*)(")(.*)$/ms', $args, $regs);
353
-		} elseif ($args[0] == "'") {
354
-			preg_match("/^(')([^']*)(')(.*)$/ms", $args, $regs);
355
-		} else {
356
-			preg_match('/^([[:space:]]*)([^,([{}]*([(\[{][^])}]*[])}])?[^,}]*)([,}].*)$/ms', $args, $regs);
357
-			if (!isset($regs[2]) or !strlen($regs[2])) {
358
-				$err_f = ['zbug_erreur_filtre', ['filtre' => $args]];
359
-				erreur_squelette($err_f, $pointeur_champ);
360
-				$champ = new Texte();
361
-				$champ->apres = $champ->avant = $args = '';
362
-				break;
363
-			}
364
-		}
365
-		$arg = $regs[2];
366
-		if (trim($regs[1])) {
367
-			$champ = new Texte();
368
-			$champ->texte = $arg;
369
-			$champ->apres = $champ->avant = $regs[1];
370
-			$result[] = $champ;
371
-			$collecte[] = $champ;
372
-			$args = ltrim($regs[count($regs) - 1]);
373
-		} else {
374
-			if (!preg_match('/' . NOM_DE_CHAMP . '([{|])/', $arg, $r)) {
375
-				// 0 est un aveu d'impuissance. A completer
376
-				$arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
377
-
378
-				$args = ltrim($regs[count($regs) - 1]);
379
-				$collecte = array_merge($collecte, $arg);
380
-				$result = array_merge($result, $arg);
381
-			} else {
382
-				$n = strpos($args, (string) $r[0]);
383
-				$pred = substr($args, 0, $n);
384
-				$par = ',}';
385
-				if (preg_match('/^(.*)\($/', $pred, $m)) {
386
-					$pred = $m[1];
387
-					$par = ')';
388
-				}
389
-				if ($pred) {
390
-					$champ = new Texte();
391
-					$champ->texte = $pred;
392
-					$champ->apres = $champ->avant = '';
393
-					$result[] = $champ;
394
-					$collecte[] = $champ;
395
-				}
396
-				$rec = substr($args, $n + strlen($r[0]) - 1);
397
-				$champ = new Champ();
398
-				$champ->nom_boucle = $r[2];
399
-				$champ->nom_champ = $r[3];
400
-				$champ->etoile = $r[5];
401
-				$next = $r[6];
402
-				while ($next == '{') {
403
-					phraser_arg($rec, $sep, [], $champ);
404
-					$args = ltrim($rec);
405
-					$next = $args[0] ?? '';
406
-				}
407
-				while ($next == '|') {
408
-					$pos_apres = 0;
409
-					phraser_args($rec, $par, $sep, [], $champ, $pos_apres);
410
-					$args = substr($rec, $pos_apres);
411
-					$next = $args[0] ?? '';
412
-				}
413
-				// Si erreur de syntaxe dans un sous-argument, propager.
414
-				if ($champ->param === false) {
415
-					$err_f = true;
416
-				} else {
417
-					phraser_vieux($champ);
418
-				}
419
-				if ($par == ')') {
420
-					$args = substr($args, 1);
421
-				}
422
-				$collecte[] = $champ;
423
-				$result[] = $champ;
424
-			}
425
-		}
426
-		if (isset($args[0]) and $args[0] == ',') {
427
-			$args = ltrim(substr($args, 1));
428
-			if ($collecte) {
429
-				$res[] = $collecte;
430
-				$collecte = [];
431
-			}
432
-		}
433
-	}
434
-	if ($collecte) {
435
-		$res[] = $collecte;
436
-		$collecte = [];
437
-	}
438
-	$texte = substr($args, 1);
439
-	$source = substr($suite, 0, strlen($suite) - strlen($texte));
440
-	// propager les erreurs, et ignorer les param vides
441
-	if ($pointeur_champ->param !== false) {
442
-		if ($err_f) {
443
-			$pointeur_champ->param = false;
444
-		} elseif ($fonc !== '' || count($res) > 1) {
445
-			$pointeur_champ->param[] = $res;
446
-		}
447
-	}
448
-	// pour les balises avec faux filtres qui boudent ce dur larbeur
449
-	$pointeur_champ->fonctions[] = [$fonc, $source];
450
-
451
-	return $result;
320
+    preg_match(',^(\|?[^}{)|]*)(.*)$,ms', $texte, $match);
321
+    $suite = ltrim($match[2]);
322
+    $fonc = trim($match[1]);
323
+    if ($fonc && $fonc[0] == '|') {
324
+        $fonc = ltrim(substr($fonc, 1));
325
+    }
326
+    $res = [$fonc];
327
+    $err_f = '';
328
+    // cas du filtre sans argument ou du critere /
329
+    if (($suite && ($suite[0] != '{')) || ($fonc && $fonc[0] == '/')) {
330
+        // si pas d'argument, alors il faut une fonction ou un double |
331
+        if (!$match[1]) {
332
+            $err_f = ['zbug_erreur_filtre', ['filtre' => $texte]];
333
+            erreur_squelette($err_f, $pointeur_champ);
334
+            $texte = '';
335
+        } else {
336
+            $texte = $suite;
337
+        }
338
+        if ($err_f) {
339
+            $pointeur_champ->param = false;
340
+        } elseif ($fonc !== '') {
341
+            $pointeur_champ->param[] = $res;
342
+        }
343
+        // pour les balises avec faux filtres qui boudent ce dur larbeur
344
+        $pointeur_champ->fonctions[] = [$fonc, ''];
345
+
346
+        return $result;
347
+    }
348
+    $args = ltrim(substr($suite, 1)); // virer le '(' initial
349
+    $collecte = [];
350
+    while ($args && $args[0] != '}') {
351
+        if ($args[0] == '"') {
352
+            preg_match('/^(")([^"]*)(")(.*)$/ms', $args, $regs);
353
+        } elseif ($args[0] == "'") {
354
+            preg_match("/^(')([^']*)(')(.*)$/ms", $args, $regs);
355
+        } else {
356
+            preg_match('/^([[:space:]]*)([^,([{}]*([(\[{][^])}]*[])}])?[^,}]*)([,}].*)$/ms', $args, $regs);
357
+            if (!isset($regs[2]) or !strlen($regs[2])) {
358
+                $err_f = ['zbug_erreur_filtre', ['filtre' => $args]];
359
+                erreur_squelette($err_f, $pointeur_champ);
360
+                $champ = new Texte();
361
+                $champ->apres = $champ->avant = $args = '';
362
+                break;
363
+            }
364
+        }
365
+        $arg = $regs[2];
366
+        if (trim($regs[1])) {
367
+            $champ = new Texte();
368
+            $champ->texte = $arg;
369
+            $champ->apres = $champ->avant = $regs[1];
370
+            $result[] = $champ;
371
+            $collecte[] = $champ;
372
+            $args = ltrim($regs[count($regs) - 1]);
373
+        } else {
374
+            if (!preg_match('/' . NOM_DE_CHAMP . '([{|])/', $arg, $r)) {
375
+                // 0 est un aveu d'impuissance. A completer
376
+                $arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
377
+
378
+                $args = ltrim($regs[count($regs) - 1]);
379
+                $collecte = array_merge($collecte, $arg);
380
+                $result = array_merge($result, $arg);
381
+            } else {
382
+                $n = strpos($args, (string) $r[0]);
383
+                $pred = substr($args, 0, $n);
384
+                $par = ',}';
385
+                if (preg_match('/^(.*)\($/', $pred, $m)) {
386
+                    $pred = $m[1];
387
+                    $par = ')';
388
+                }
389
+                if ($pred) {
390
+                    $champ = new Texte();
391
+                    $champ->texte = $pred;
392
+                    $champ->apres = $champ->avant = '';
393
+                    $result[] = $champ;
394
+                    $collecte[] = $champ;
395
+                }
396
+                $rec = substr($args, $n + strlen($r[0]) - 1);
397
+                $champ = new Champ();
398
+                $champ->nom_boucle = $r[2];
399
+                $champ->nom_champ = $r[3];
400
+                $champ->etoile = $r[5];
401
+                $next = $r[6];
402
+                while ($next == '{') {
403
+                    phraser_arg($rec, $sep, [], $champ);
404
+                    $args = ltrim($rec);
405
+                    $next = $args[0] ?? '';
406
+                }
407
+                while ($next == '|') {
408
+                    $pos_apres = 0;
409
+                    phraser_args($rec, $par, $sep, [], $champ, $pos_apres);
410
+                    $args = substr($rec, $pos_apres);
411
+                    $next = $args[0] ?? '';
412
+                }
413
+                // Si erreur de syntaxe dans un sous-argument, propager.
414
+                if ($champ->param === false) {
415
+                    $err_f = true;
416
+                } else {
417
+                    phraser_vieux($champ);
418
+                }
419
+                if ($par == ')') {
420
+                    $args = substr($args, 1);
421
+                }
422
+                $collecte[] = $champ;
423
+                $result[] = $champ;
424
+            }
425
+        }
426
+        if (isset($args[0]) and $args[0] == ',') {
427
+            $args = ltrim(substr($args, 1));
428
+            if ($collecte) {
429
+                $res[] = $collecte;
430
+                $collecte = [];
431
+            }
432
+        }
433
+    }
434
+    if ($collecte) {
435
+        $res[] = $collecte;
436
+        $collecte = [];
437
+    }
438
+    $texte = substr($args, 1);
439
+    $source = substr($suite, 0, strlen($suite) - strlen($texte));
440
+    // propager les erreurs, et ignorer les param vides
441
+    if ($pointeur_champ->param !== false) {
442
+        if ($err_f) {
443
+            $pointeur_champ->param = false;
444
+        } elseif ($fonc !== '' || count($res) > 1) {
445
+            $pointeur_champ->param[] = $res;
446
+        }
447
+    }
448
+    // pour les balises avec faux filtres qui boudent ce dur larbeur
449
+    $pointeur_champ->fonctions[] = [$fonc, $source];
450
+
451
+    return $result;
452 452
 }
453 453
 
454 454
 
455 455
 function phraser_champs_exterieurs($texte, $ligne, $sep, $nested) {
456
-	$res = [];
457
-	while (($p = strpos($texte, (string) "%$sep")) !== false) {
458
-		if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
459
-			break;
460
-		}
461
-		$debut = substr($texte, 0, $p);
462
-		$texte = substr($texte, $p + strlen($m[0]));
463
-		if ($p) {
464
-			$res = phraser_inclure($debut, $ligne, $res);
465
-		}
466
-		$ligne += substr_count($debut, "\n");
467
-		$res[] = $nested[$m[1]];
468
-	}
469
-
470
-	return (($texte === '') ? $res : phraser_inclure($texte, $ligne, $res));
456
+    $res = [];
457
+    while (($p = strpos($texte, (string) "%$sep")) !== false) {
458
+        if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
459
+            break;
460
+        }
461
+        $debut = substr($texte, 0, $p);
462
+        $texte = substr($texte, $p + strlen($m[0]));
463
+        if ($p) {
464
+            $res = phraser_inclure($debut, $ligne, $res);
465
+        }
466
+        $ligne += substr_count($debut, "\n");
467
+        $res[] = $nested[$m[1]];
468
+    }
469
+
470
+    return (($texte === '') ? $res : phraser_inclure($texte, $ligne, $res));
471 471
 }
472 472
 
473 473
 function phraser_champs_interieurs($texte, $ligne, $sep, $result) {
474
-	$i = 0; // en fait count($result)
475
-	$x = '';
476
-
477
-	while (true) {
478
-		$j = $i;
479
-		$n = $ligne;
480
-		while (preg_match(CHAMP_ETENDU, $texte, $match)) {
481
-			$p = strpos($texte, (string) $match[0]);
482
-			$debut = substr($texte, 0, $p);
483
-			if ($p) {
484
-				$result[$i] = $debut;
485
-				$i++;
486
-			}
487
-			$nom = $match[4];
488
-			$champ = new Champ();
489
-			// ca ne marche pas encore en cas de champ imbrique
490
-			$champ->ligne = $x ? 0 : ($n + substr_count($debut, "\n"));
491
-			$champ->nom_boucle = $match[3];
492
-			$champ->nom_champ = $nom;
493
-			$champ->etoile = $match[6];
494
-			// phraser_args indiquera ou commence apres
495
-			$pos_apres = 0;
496
-			$result = phraser_args($match[7], ')', $sep, $result, $champ, $pos_apres);
497
-			phraser_vieux($champ);
498
-			$champ->avant =	phraser_champs_exterieurs($match[1], $n, $sep, $result);
499
-			$debut = substr($match[7], $pos_apres + 1);
500
-			if (!empty($debut)) {
501
-				$n += substr_count(substr($texte, 0, strpos($texte, $debut)), "\n");
502
-			}
503
-			$champ->apres = phraser_champs_exterieurs($debut, $n, $sep, $result);
504
-
505
-			// reinjecter la boucle si c'en est une
506
-			phraser_boucle_placeholder($champ);
507
-
508
-			$result[$i] = $champ;
509
-			$i++;
510
-			$texte = substr($texte, $p + strlen($match[0]));
511
-		}
512
-		if ($texte !== '') {
513
-			$result[$i] = $texte;
514
-			$i++;
515
-		}
516
-		$x = '';
517
-
518
-		while ($j < $i) {
519
-			$z = $result[$j];
520
-			// j'aurais besoin de connaitre le nombre de lignes...
521
-			if (is_object($z)) {
522
-				$x .= "%$sep$j@";
523
-			} else {
524
-				$x .= $z;
525
-			}
526
-			$j++;
527
-		}
528
-		if (preg_match(CHAMP_ETENDU, $x)) {
529
-			$texte = $x;
530
-		} else {
531
-			return phraser_champs_exterieurs($x, $ligne, $sep, $result);
532
-		}
533
-	}
474
+    $i = 0; // en fait count($result)
475
+    $x = '';
476
+
477
+    while (true) {
478
+        $j = $i;
479
+        $n = $ligne;
480
+        while (preg_match(CHAMP_ETENDU, $texte, $match)) {
481
+            $p = strpos($texte, (string) $match[0]);
482
+            $debut = substr($texte, 0, $p);
483
+            if ($p) {
484
+                $result[$i] = $debut;
485
+                $i++;
486
+            }
487
+            $nom = $match[4];
488
+            $champ = new Champ();
489
+            // ca ne marche pas encore en cas de champ imbrique
490
+            $champ->ligne = $x ? 0 : ($n + substr_count($debut, "\n"));
491
+            $champ->nom_boucle = $match[3];
492
+            $champ->nom_champ = $nom;
493
+            $champ->etoile = $match[6];
494
+            // phraser_args indiquera ou commence apres
495
+            $pos_apres = 0;
496
+            $result = phraser_args($match[7], ')', $sep, $result, $champ, $pos_apres);
497
+            phraser_vieux($champ);
498
+            $champ->avant =	phraser_champs_exterieurs($match[1], $n, $sep, $result);
499
+            $debut = substr($match[7], $pos_apres + 1);
500
+            if (!empty($debut)) {
501
+                $n += substr_count(substr($texte, 0, strpos($texte, $debut)), "\n");
502
+            }
503
+            $champ->apres = phraser_champs_exterieurs($debut, $n, $sep, $result);
504
+
505
+            // reinjecter la boucle si c'en est une
506
+            phraser_boucle_placeholder($champ);
507
+
508
+            $result[$i] = $champ;
509
+            $i++;
510
+            $texte = substr($texte, $p + strlen($match[0]));
511
+        }
512
+        if ($texte !== '') {
513
+            $result[$i] = $texte;
514
+            $i++;
515
+        }
516
+        $x = '';
517
+
518
+        while ($j < $i) {
519
+            $z = $result[$j];
520
+            // j'aurais besoin de connaitre le nombre de lignes...
521
+            if (is_object($z)) {
522
+                $x .= "%$sep$j@";
523
+            } else {
524
+                $x .= $z;
525
+            }
526
+            $j++;
527
+        }
528
+        if (preg_match(CHAMP_ETENDU, $x)) {
529
+            $texte = $x;
530
+        } else {
531
+            return phraser_champs_exterieurs($x, $ligne, $sep, $result);
532
+        }
533
+    }
534 534
 }
535 535
 
536 536
 function phraser_vieux(&$champ) {
537
-	$nom = $champ->nom_champ;
538
-	if ($nom == 'EMBED_DOCUMENT') {
539
-		if (!function_exists('phraser_vieux_emb')) {
540
-			include_spip('public/normaliser');
541
-		}
542
-		phraser_vieux_emb($champ);
543
-	} elseif ($nom == 'EXPOSER') {
544
-		if (!function_exists('phraser_vieux_exposer')) {
545
-			include_spip('public/normaliser');
546
-		}
547
-		phraser_vieux_exposer($champ);
548
-	} elseif ($champ->param) {
549
-		if ($nom == 'FORMULAIRE_RECHERCHE') {
550
-			if (!function_exists('phraser_vieux_recherche')) {
551
-				include_spip('public/normaliser');
552
-			}
553
-			phraser_vieux_recherche($champ);
554
-		} elseif (preg_match(',^LOGO_[A-Z]+,', $nom)) {
555
-			if (!function_exists('phraser_vieux_logos')) {
556
-				include_spip('public/normaliser');
557
-			}
558
-			phraser_vieux_logos($champ);
559
-		} elseif ($nom == 'MODELE') {
560
-			if (!function_exists('phraser_vieux_modele')) {
561
-				include_spip('public/normaliser');
562
-			}
563
-			phraser_vieux_modele($champ);
564
-		} elseif ($nom == 'INCLURE' or $nom == 'INCLUDE') {
565
-			if (!function_exists('phraser_vieux_inclu')) {
566
-				include_spip('public/normaliser');
567
-			}
568
-			phraser_vieux_inclu($champ);
569
-		}
570
-	}
537
+    $nom = $champ->nom_champ;
538
+    if ($nom == 'EMBED_DOCUMENT') {
539
+        if (!function_exists('phraser_vieux_emb')) {
540
+            include_spip('public/normaliser');
541
+        }
542
+        phraser_vieux_emb($champ);
543
+    } elseif ($nom == 'EXPOSER') {
544
+        if (!function_exists('phraser_vieux_exposer')) {
545
+            include_spip('public/normaliser');
546
+        }
547
+        phraser_vieux_exposer($champ);
548
+    } elseif ($champ->param) {
549
+        if ($nom == 'FORMULAIRE_RECHERCHE') {
550
+            if (!function_exists('phraser_vieux_recherche')) {
551
+                include_spip('public/normaliser');
552
+            }
553
+            phraser_vieux_recherche($champ);
554
+        } elseif (preg_match(',^LOGO_[A-Z]+,', $nom)) {
555
+            if (!function_exists('phraser_vieux_logos')) {
556
+                include_spip('public/normaliser');
557
+            }
558
+            phraser_vieux_logos($champ);
559
+        } elseif ($nom == 'MODELE') {
560
+            if (!function_exists('phraser_vieux_modele')) {
561
+                include_spip('public/normaliser');
562
+            }
563
+            phraser_vieux_modele($champ);
564
+        } elseif ($nom == 'INCLURE' or $nom == 'INCLUDE') {
565
+            if (!function_exists('phraser_vieux_inclu')) {
566
+                include_spip('public/normaliser');
567
+            }
568
+            phraser_vieux_inclu($champ);
569
+        }
570
+    }
571 571
 }
572 572
 
573 573
 
@@ -595,200 +595,200 @@  discard block
 block discarded – undo
595 595
  **/
596 596
 function phraser_criteres($params, &$result) {
597 597
 
598
-	$err_ci = ''; // indiquera s'il y a eu une erreur
599
-	$args = [];
600
-	$type = $result->type_requete;
601
-	$doublons = [];
602
-	foreach ($params as $v) {
603
-		$var = $v[1][0];
604
-		$param = ($var->type != 'texte') ? '' : $var->texte;
605
-		if (((is_countable($v) ? count($v) : 0) > 2) && (!preg_match(',[^A-Za-z]IN[^A-Za-z],i', $param))) {
606
-			// plus d'un argument et pas le critere IN:
607
-			// detecter comme on peut si c'est le critere implicite LIMIT debut, fin
608
-			if (
609
-				$var->type != 'texte'
610
-				or preg_match('/^(n|n-|(n-)?\d+)$/S', $param)
611
-			) {
612
-				$op = ',';
613
-				$not = false;
614
-				$cond = false;
615
-			} else {
616
-				// Le debut du premier argument est l'operateur
617
-				preg_match('/^([!]?)([a-zA-Z][a-zA-Z0-9_]*)[[:space:]]*(\??)[[:space:]]*(.*)$/ms', $param, $m);
618
-				$op = $m[2];
619
-				$not = (bool) $m[1];
620
-				$cond = $m[3];
621
-				// virer le premier argument,
622
-				// et mettre son reliquat eventuel
623
-				// Recopier pour ne pas alterer le texte source
624
-				// utile au debusqueur
625
-				if ($m[4]) {
626
-					// une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
627
-					if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
628
-						$c = null;
629
-						eval('$c = ' . $m[4] . ';');
630
-						if (isset($c)) {
631
-							$m[4] = $c;
632
-						}
633
-					}
634
-					$texte = new Texte();
635
-					$texte->texte = $m[4];
636
-					$v[1][0] = $texte;
637
-				} else {
638
-					array_shift($v[1]);
639
-				}
640
-			}
641
-			array_shift($v); // $v[O] est vide
642
-			$crit = new Critere();
643
-			$crit->op = $op;
644
-			$crit->not = $not;
645
-			$crit->cond = $cond;
646
-			$crit->exclus = '';
647
-			$crit->param = $v;
648
-			$args[] = $crit;
649
-		} else {
650
-			if ($var->type != 'texte') {
651
-				// cas 1 seul arg ne commencant pas par du texte brut:
652
-				// erreur ou critere infixe "/"
653
-				if (($v[1][1]->type != 'texte') || (trim($v[1][1]->texte) != '/')) {
654
-					$err_ci = [
655
-						'zbug_critere_inconnu',
656
-						['critere' => $var->nom_champ]
657
-					];
658
-					erreur_squelette($err_ci, $result);
659
-				} else {
660
-					$crit = new Critere();
661
-					$crit->op = '/';
662
-					$crit->not = false;
663
-					$crit->exclus = '';
664
-					$crit->param = [[$v[1][0]], [$v[1][2]]];
665
-					$args[] = $crit;
666
-				}
667
-			} else {
668
-				// traiter qq lexemes particuliers pour faciliter la suite
669
-				// les separateurs
670
-				if ($var->apres) {
671
-					$result->separateur[] = $param;
672
-				} elseif (($param == 'tout') or ($param == 'tous')) {
673
-					$result->modificateur['tout'] = true;
674
-				} elseif ($param == 'plat') {
675
-					$result->modificateur['plat'] = true;
676
-				}
677
-
678
-				// Boucle hierarchie, analyser le critere id_rubrique
679
-				// et les autres critères {id_x} pour forcer {tout} sur
680
-				// ceux-ci pour avoir la rubrique mere...
681
-				// Les autres critères de la boucle hierarchie doivent être
682
-				// traités normalement.
683
-				elseif (
684
-					strcasecmp($type, 'hierarchie') == 0
685
-					and !preg_match(",^id_rubrique\b,", $param)
686
-					and preg_match(',^id_\w+\s*$,', $param)
687
-				) {
688
-					$result->modificateur['tout'] = true;
689
-				} elseif (strcasecmp($type, 'hierarchie') == 0 and $param == 'id_rubrique') {
690
-					// rien a faire sur {id_rubrique} tout seul
691
-				} else {
692
-					// pas d'emplacement statique, faut un dynamique
693
-					// mais il y a 2 cas qui ont les 2 !
694
-					if (($param == 'unique') || (preg_match(',^!?doublons *,', $param))) {
695
-						// cette variable sera inseree dans le code
696
-						// et son nom sert d'indicateur des maintenant
697
-						$result->doublons = '$doublons_index';
698
-						if ($param == 'unique') {
699
-							$param = 'doublons';
700
-						}
701
-					} elseif ($param == 'recherche') {
702
-						// meme chose (a cause de #nom_de_boucle:URL_*)
703
-						$result->hash = ' ';
704
-					}
705
-
706
-					if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
707
-						$crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
708
-					} elseif (
709
-						preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
710
-						')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)
711
-					) {
712
-						$a2 = trim($m[8]);
713
-						if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and ($a2[0] == substr($a2, -1))) {
714
-							$a2 = substr($a2, 1, -1);
715
-						}
716
-						$crit = phraser_critere_infixe(
717
-							$m[2],
718
-							$a2,
719
-							$v,
720
-							(($m[2] == 'lang_select') ? $m[2] : $m[7]),
721
-							$m[6],
722
-							$m[5]
723
-						);
724
-						$crit->exclus = $m[1];
725
-					} elseif (
726
-						preg_match('/^([!]?)\s*(' .
727
-						CHAMP_SQL_PLUS_FONC .
728
-						')\s*(\??)(.*)$/is', $param, $m)
729
-					) {
730
-						// contient aussi les comparaisons implicites !
731
-						// Comme ci-dessus:
732
-						// le premier arg contient l'operateur
733
-						array_shift($v);
734
-						if ($m[6]) {
735
-							$v[0][0] = new Texte();
736
-							$v[0][0]->texte = $m[6];
737
-						} else {
738
-							array_shift($v[0]);
739
-							if (!$v[0]) {
740
-								array_shift($v);
741
-							}
742
-						}
743
-						$crit = new Critere();
744
-						$crit->op = $m[2];
745
-						$crit->param = $v;
746
-						$crit->not = (bool) $m[1];
747
-						$crit->cond = $m[5];
748
-					} else {
749
-						$err_ci = [
750
-							'zbug_critere_inconnu',
751
-							['critere' => $param]
752
-						];
753
-						erreur_squelette($err_ci, $result);
754
-					}
755
-
756
-					if ((!preg_match(',^!?doublons *,', $param)) || $crit->not) {
757
-						$args[] = $crit;
758
-					} else {
759
-						$doublons[] = $crit;
760
-					}
761
-				}
762
-			}
763
-		}
764
-	}
765
-
766
-	// les doublons non nies doivent etre le dernier critere
767
-	// pour que la variable $doublon_index ait la bonne valeur
768
-	// cf critere_doublon
769
-	if ($doublons) {
770
-		$args = [...$args, ...$doublons];
771
-	}
772
-
773
-	// Si erreur, laisser la chaine dans ce champ pour le HTTP 503
774
-	if (!$err_ci) {
775
-		$result->criteres = $args;
776
-	}
598
+    $err_ci = ''; // indiquera s'il y a eu une erreur
599
+    $args = [];
600
+    $type = $result->type_requete;
601
+    $doublons = [];
602
+    foreach ($params as $v) {
603
+        $var = $v[1][0];
604
+        $param = ($var->type != 'texte') ? '' : $var->texte;
605
+        if (((is_countable($v) ? count($v) : 0) > 2) && (!preg_match(',[^A-Za-z]IN[^A-Za-z],i', $param))) {
606
+            // plus d'un argument et pas le critere IN:
607
+            // detecter comme on peut si c'est le critere implicite LIMIT debut, fin
608
+            if (
609
+                $var->type != 'texte'
610
+                or preg_match('/^(n|n-|(n-)?\d+)$/S', $param)
611
+            ) {
612
+                $op = ',';
613
+                $not = false;
614
+                $cond = false;
615
+            } else {
616
+                // Le debut du premier argument est l'operateur
617
+                preg_match('/^([!]?)([a-zA-Z][a-zA-Z0-9_]*)[[:space:]]*(\??)[[:space:]]*(.*)$/ms', $param, $m);
618
+                $op = $m[2];
619
+                $not = (bool) $m[1];
620
+                $cond = $m[3];
621
+                // virer le premier argument,
622
+                // et mettre son reliquat eventuel
623
+                // Recopier pour ne pas alterer le texte source
624
+                // utile au debusqueur
625
+                if ($m[4]) {
626
+                    // une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
627
+                    if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
628
+                        $c = null;
629
+                        eval('$c = ' . $m[4] . ';');
630
+                        if (isset($c)) {
631
+                            $m[4] = $c;
632
+                        }
633
+                    }
634
+                    $texte = new Texte();
635
+                    $texte->texte = $m[4];
636
+                    $v[1][0] = $texte;
637
+                } else {
638
+                    array_shift($v[1]);
639
+                }
640
+            }
641
+            array_shift($v); // $v[O] est vide
642
+            $crit = new Critere();
643
+            $crit->op = $op;
644
+            $crit->not = $not;
645
+            $crit->cond = $cond;
646
+            $crit->exclus = '';
647
+            $crit->param = $v;
648
+            $args[] = $crit;
649
+        } else {
650
+            if ($var->type != 'texte') {
651
+                // cas 1 seul arg ne commencant pas par du texte brut:
652
+                // erreur ou critere infixe "/"
653
+                if (($v[1][1]->type != 'texte') || (trim($v[1][1]->texte) != '/')) {
654
+                    $err_ci = [
655
+                        'zbug_critere_inconnu',
656
+                        ['critere' => $var->nom_champ]
657
+                    ];
658
+                    erreur_squelette($err_ci, $result);
659
+                } else {
660
+                    $crit = new Critere();
661
+                    $crit->op = '/';
662
+                    $crit->not = false;
663
+                    $crit->exclus = '';
664
+                    $crit->param = [[$v[1][0]], [$v[1][2]]];
665
+                    $args[] = $crit;
666
+                }
667
+            } else {
668
+                // traiter qq lexemes particuliers pour faciliter la suite
669
+                // les separateurs
670
+                if ($var->apres) {
671
+                    $result->separateur[] = $param;
672
+                } elseif (($param == 'tout') or ($param == 'tous')) {
673
+                    $result->modificateur['tout'] = true;
674
+                } elseif ($param == 'plat') {
675
+                    $result->modificateur['plat'] = true;
676
+                }
677
+
678
+                // Boucle hierarchie, analyser le critere id_rubrique
679
+                // et les autres critères {id_x} pour forcer {tout} sur
680
+                // ceux-ci pour avoir la rubrique mere...
681
+                // Les autres critères de la boucle hierarchie doivent être
682
+                // traités normalement.
683
+                elseif (
684
+                    strcasecmp($type, 'hierarchie') == 0
685
+                    and !preg_match(",^id_rubrique\b,", $param)
686
+                    and preg_match(',^id_\w+\s*$,', $param)
687
+                ) {
688
+                    $result->modificateur['tout'] = true;
689
+                } elseif (strcasecmp($type, 'hierarchie') == 0 and $param == 'id_rubrique') {
690
+                    // rien a faire sur {id_rubrique} tout seul
691
+                } else {
692
+                    // pas d'emplacement statique, faut un dynamique
693
+                    // mais il y a 2 cas qui ont les 2 !
694
+                    if (($param == 'unique') || (preg_match(',^!?doublons *,', $param))) {
695
+                        // cette variable sera inseree dans le code
696
+                        // et son nom sert d'indicateur des maintenant
697
+                        $result->doublons = '$doublons_index';
698
+                        if ($param == 'unique') {
699
+                            $param = 'doublons';
700
+                        }
701
+                    } elseif ($param == 'recherche') {
702
+                        // meme chose (a cause de #nom_de_boucle:URL_*)
703
+                        $result->hash = ' ';
704
+                    }
705
+
706
+                    if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
707
+                        $crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
708
+                    } elseif (
709
+                        preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
710
+                        ')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)
711
+                    ) {
712
+                        $a2 = trim($m[8]);
713
+                        if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and ($a2[0] == substr($a2, -1))) {
714
+                            $a2 = substr($a2, 1, -1);
715
+                        }
716
+                        $crit = phraser_critere_infixe(
717
+                            $m[2],
718
+                            $a2,
719
+                            $v,
720
+                            (($m[2] == 'lang_select') ? $m[2] : $m[7]),
721
+                            $m[6],
722
+                            $m[5]
723
+                        );
724
+                        $crit->exclus = $m[1];
725
+                    } elseif (
726
+                        preg_match('/^([!]?)\s*(' .
727
+                        CHAMP_SQL_PLUS_FONC .
728
+                        ')\s*(\??)(.*)$/is', $param, $m)
729
+                    ) {
730
+                        // contient aussi les comparaisons implicites !
731
+                        // Comme ci-dessus:
732
+                        // le premier arg contient l'operateur
733
+                        array_shift($v);
734
+                        if ($m[6]) {
735
+                            $v[0][0] = new Texte();
736
+                            $v[0][0]->texte = $m[6];
737
+                        } else {
738
+                            array_shift($v[0]);
739
+                            if (!$v[0]) {
740
+                                array_shift($v);
741
+                            }
742
+                        }
743
+                        $crit = new Critere();
744
+                        $crit->op = $m[2];
745
+                        $crit->param = $v;
746
+                        $crit->not = (bool) $m[1];
747
+                        $crit->cond = $m[5];
748
+                    } else {
749
+                        $err_ci = [
750
+                            'zbug_critere_inconnu',
751
+                            ['critere' => $param]
752
+                        ];
753
+                        erreur_squelette($err_ci, $result);
754
+                    }
755
+
756
+                    if ((!preg_match(',^!?doublons *,', $param)) || $crit->not) {
757
+                        $args[] = $crit;
758
+                    } else {
759
+                        $doublons[] = $crit;
760
+                    }
761
+                }
762
+            }
763
+        }
764
+    }
765
+
766
+    // les doublons non nies doivent etre le dernier critere
767
+    // pour que la variable $doublon_index ait la bonne valeur
768
+    // cf critere_doublon
769
+    if ($doublons) {
770
+        $args = [...$args, ...$doublons];
771
+    }
772
+
773
+    // Si erreur, laisser la chaine dans ce champ pour le HTTP 503
774
+    if (!$err_ci) {
775
+        $result->criteres = $args;
776
+    }
777 777
 }
778 778
 
779 779
 function phraser_critere_infixe($arg1, $arg2, $args, $op, $not, $cond) {
780
-	$args[0] = new Texte();
781
-	$args[0]->texte = $arg1;
782
-	$args[0] = [$args[0]];
783
-	$args[1][0] = new Texte();
784
-	$args[1][0]->texte = $arg2;
785
-	$crit = new Critere();
786
-	$crit->op = $op;
787
-	$crit->not = $not;
788
-	$crit->cond = $cond;
789
-	$crit->param = $args;
790
-
791
-	return $crit;
780
+    $args[0] = new Texte();
781
+    $args[0]->texte = $arg1;
782
+    $args[0] = [$args[0]];
783
+    $args[1][0] = new Texte();
784
+    $args[1][0]->texte = $arg2;
785
+    $crit = new Critere();
786
+    $crit->op = $op;
787
+    $crit->not = $not;
788
+    $crit->cond = $cond;
789
+    $crit->param = $args;
790
+
791
+    return $crit;
792 792
 }
793 793
 
794 794
 /**
@@ -799,12 +799,12 @@  discard block
 block discarded – undo
799 799
  * @return int
800 800
  */
801 801
 function public_compte_ligne($texte, $debut = 0, $fin = null) {
802
-	if (is_null($fin)) {
803
-		return substr_count($texte, "\n", $debut);
804
-	}
805
-	else {
806
-		return substr_count($texte, "\n", $debut, $fin - $debut);
807
-	}
802
+    if (is_null($fin)) {
803
+        return substr_count($texte, "\n", $debut);
804
+    }
805
+    else {
806
+        return substr_count($texte, "\n", $debut, $fin - $debut);
807
+    }
808 808
 }
809 809
 
810 810
 
@@ -820,87 +820,87 @@  discard block
 block discarded – undo
820 820
  * @return array|null
821 821
  */
822 822
 function public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte = 0) {
823
-	$premiere_boucle = null;
824
-	$pos_derniere_boucle_anonyme = $pos_debut_texte;
825
-
826
-	$current_pos = $pos_debut_texte;
827
-	while (($pos_boucle = strpos($texte, BALISE_BOUCLE, $current_pos)) !== false) {
828
-		$current_pos = $pos_boucle + 1;
829
-		$pos_parent = strpos($texte, '(', $pos_boucle);
830
-
831
-		$id_boucle = '';
832
-		if ($pos_parent !== false) {
833
-			$id_boucle = trim(substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)));
834
-		}
835
-		if (
836
-			$pos_parent === false
837
-			or (strlen($id_boucle) and !(is_numeric($id_boucle) or strpos($id_boucle, '_') === 0))
838
-		) {
839
-			$result = new Boucle();
840
-			$result->id_parent = $id_parent;
841
-			$result->descr = $descr;
842
-
843
-			// un id_boucle pour l'affichage de l'erreur
844
-			if (!strlen($id_boucle)) {
845
-				$id_boucle = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
846
-			}
847
-			$result->id_boucle = $id_boucle;
848
-			$err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
849
-			erreur_squelette($err_b, $result);
850
-
851
-			continue;
852
-		}
853
-		else {
854
-			$boucle = [
855
-				'id_boucle' => $id_boucle,
856
-				'id_boucle_err' => $id_boucle,
857
-				'debut_boucle' => $pos_boucle,
858
-				'pos_boucle' => $pos_boucle,
859
-				'pos_parent' => $pos_parent,
860
-				'pos_precond' => false,
861
-				'pos_precond_inside' => false,
862
-				'pos_preaff' => false,
863
-				'pos_preaff_inside' => false,
864
-			];
865
-
866
-			// un id_boucle pour l'affichage de l'erreur sur les boucle anonymes
867
-			if (!strlen($id_boucle)) {
868
-				$boucle['id_boucle_err'] = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
869
-			}
870
-
871
-			// trouver sa position de depart reelle : au <Bxx> ou au <BBxx>
872
-			$precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
873
-			$pos_precond = strpos($texte, $precond_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
874
-			if (
875
-				$pos_precond !== false
876
-				and $pos_precond < $boucle['debut_boucle']
877
-			) {
878
-				$boucle['debut_boucle'] = $pos_precond;
879
-				$boucle['pos_precond'] = $pos_precond;
880
-				$boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
881
-			}
882
-
883
-			$preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
884
-			$pos_preaff = strpos($texte, $preaff_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
885
-			if (
886
-				$pos_preaff !== false
887
-				and $pos_preaff < $boucle['debut_boucle']
888
-			) {
889
-				$boucle['debut_boucle'] = $pos_preaff;
890
-				$boucle['pos_preaff'] = $pos_preaff;
891
-				$boucle['pos_preaff_inside'] = $pos_preaff + strlen($preaff_boucle);
892
-			}
893
-			if (!strlen($id_boucle)) {
894
-				$pos_derniere_boucle_anonyme = $pos_boucle;
895
-			}
896
-
897
-			if (is_null($premiere_boucle) or $premiere_boucle['debut_boucle'] > $boucle['debut_boucle']) {
898
-				$premiere_boucle = $boucle;
899
-			}
900
-		}
901
-	}
902
-
903
-	return $premiere_boucle;
823
+    $premiere_boucle = null;
824
+    $pos_derniere_boucle_anonyme = $pos_debut_texte;
825
+
826
+    $current_pos = $pos_debut_texte;
827
+    while (($pos_boucle = strpos($texte, BALISE_BOUCLE, $current_pos)) !== false) {
828
+        $current_pos = $pos_boucle + 1;
829
+        $pos_parent = strpos($texte, '(', $pos_boucle);
830
+
831
+        $id_boucle = '';
832
+        if ($pos_parent !== false) {
833
+            $id_boucle = trim(substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)));
834
+        }
835
+        if (
836
+            $pos_parent === false
837
+            or (strlen($id_boucle) and !(is_numeric($id_boucle) or strpos($id_boucle, '_') === 0))
838
+        ) {
839
+            $result = new Boucle();
840
+            $result->id_parent = $id_parent;
841
+            $result->descr = $descr;
842
+
843
+            // un id_boucle pour l'affichage de l'erreur
844
+            if (!strlen($id_boucle)) {
845
+                $id_boucle = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
846
+            }
847
+            $result->id_boucle = $id_boucle;
848
+            $err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
849
+            erreur_squelette($err_b, $result);
850
+
851
+            continue;
852
+        }
853
+        else {
854
+            $boucle = [
855
+                'id_boucle' => $id_boucle,
856
+                'id_boucle_err' => $id_boucle,
857
+                'debut_boucle' => $pos_boucle,
858
+                'pos_boucle' => $pos_boucle,
859
+                'pos_parent' => $pos_parent,
860
+                'pos_precond' => false,
861
+                'pos_precond_inside' => false,
862
+                'pos_preaff' => false,
863
+                'pos_preaff_inside' => false,
864
+            ];
865
+
866
+            // un id_boucle pour l'affichage de l'erreur sur les boucle anonymes
867
+            if (!strlen($id_boucle)) {
868
+                $boucle['id_boucle_err'] = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
869
+            }
870
+
871
+            // trouver sa position de depart reelle : au <Bxx> ou au <BBxx>
872
+            $precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
873
+            $pos_precond = strpos($texte, $precond_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
874
+            if (
875
+                $pos_precond !== false
876
+                and $pos_precond < $boucle['debut_boucle']
877
+            ) {
878
+                $boucle['debut_boucle'] = $pos_precond;
879
+                $boucle['pos_precond'] = $pos_precond;
880
+                $boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
881
+            }
882
+
883
+            $preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
884
+            $pos_preaff = strpos($texte, $preaff_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
885
+            if (
886
+                $pos_preaff !== false
887
+                and $pos_preaff < $boucle['debut_boucle']
888
+            ) {
889
+                $boucle['debut_boucle'] = $pos_preaff;
890
+                $boucle['pos_preaff'] = $pos_preaff;
891
+                $boucle['pos_preaff_inside'] = $pos_preaff + strlen($preaff_boucle);
892
+            }
893
+            if (!strlen($id_boucle)) {
894
+                $pos_derniere_boucle_anonyme = $pos_boucle;
895
+            }
896
+
897
+            if (is_null($premiere_boucle) or $premiere_boucle['debut_boucle'] > $boucle['debut_boucle']) {
898
+                $premiere_boucle = $boucle;
899
+            }
900
+        }
901
+    }
902
+
903
+    return $premiere_boucle;
904 904
 }
905 905
 
906 906
 /**
@@ -915,68 +915,68 @@  discard block
 block discarded – undo
915 915
  * @return mixed
916 916
  */
917 917
 function public_trouver_fin_boucle($texte, $id_parent, $boucle, $pos_debut_texte, $result) {
918
-	$id_boucle = $boucle['id_boucle'];
919
-	$pos_courante = $pos_debut_texte;
920
-
921
-	$boucle['pos_postcond'] = false;
922
-	$boucle['pos_postcond_inside'] = false;
923
-	$boucle['pos_altern'] = false;
924
-	$boucle['pos_altern_inside'] = false;
925
-	$boucle['pos_postaff'] = false;
926
-	$boucle['pos_postaff_inside'] = false;
927
-
928
-	$pos_anonyme_next = null;
929
-	// si c'est une boucle anonyme, chercher la position de la prochaine boucle anonyme
930
-	if (!strlen($id_boucle)) {
931
-		$pos_anonyme_next = strpos($texte, BALISE_BOUCLE . '(', $pos_courante);
932
-	}
933
-
934
-	//
935
-	// 1. Recuperer la partie conditionnelle apres
936
-	//
937
-	$apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . '>';
938
-	$pos_apres = strpos($texte, $apres_boucle, $pos_courante);
939
-	if (
940
-		$pos_apres !== false
941
-		and (!$pos_anonyme_next or $pos_apres < $pos_anonyme_next)
942
-	) {
943
-		$boucle['pos_postcond'] = $pos_apres;
944
-		$pos_apres += strlen($apres_boucle);
945
-		$boucle['pos_postcond_inside'] = $pos_apres;
946
-		$pos_courante = $pos_apres ;
947
-	}
948
-
949
-	//
950
-	// 2. Récuperer la partie alternative apres
951
-	//
952
-	$altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . '>';
953
-	$pos_altern = strpos($texte, $altern_boucle, $pos_courante);
954
-	if (
955
-		$pos_altern !== false
956
-		and (!$pos_anonyme_next or $pos_altern < $pos_anonyme_next)
957
-	) {
958
-		$boucle['pos_altern'] = $pos_altern;
959
-		$pos_altern += strlen($altern_boucle);
960
-		$boucle['pos_altern_inside'] = $pos_altern;
961
-		$pos_courante = $pos_altern;
962
-	}
963
-
964
-	//
965
-	// 3. Recuperer la partie footer non alternative
966
-	//
967
-	$postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . '>';
968
-	$pos_postaff = strpos($texte, $postaff_boucle, $pos_courante);
969
-	if (
970
-		$pos_postaff !== false
971
-		and (!$pos_anonyme_next or $pos_postaff < $pos_anonyme_next)
972
-	) {
973
-		$boucle['pos_postaff'] = $pos_postaff;
974
-		$pos_postaff += strlen($postaff_boucle);
975
-		$boucle['pos_postaff_inside'] = $pos_postaff;
976
-		$pos_courante = $pos_postaff ;
977
-	}
978
-
979
-	return $boucle;
918
+    $id_boucle = $boucle['id_boucle'];
919
+    $pos_courante = $pos_debut_texte;
920
+
921
+    $boucle['pos_postcond'] = false;
922
+    $boucle['pos_postcond_inside'] = false;
923
+    $boucle['pos_altern'] = false;
924
+    $boucle['pos_altern_inside'] = false;
925
+    $boucle['pos_postaff'] = false;
926
+    $boucle['pos_postaff_inside'] = false;
927
+
928
+    $pos_anonyme_next = null;
929
+    // si c'est une boucle anonyme, chercher la position de la prochaine boucle anonyme
930
+    if (!strlen($id_boucle)) {
931
+        $pos_anonyme_next = strpos($texte, BALISE_BOUCLE . '(', $pos_courante);
932
+    }
933
+
934
+    //
935
+    // 1. Recuperer la partie conditionnelle apres
936
+    //
937
+    $apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . '>';
938
+    $pos_apres = strpos($texte, $apres_boucle, $pos_courante);
939
+    if (
940
+        $pos_apres !== false
941
+        and (!$pos_anonyme_next or $pos_apres < $pos_anonyme_next)
942
+    ) {
943
+        $boucle['pos_postcond'] = $pos_apres;
944
+        $pos_apres += strlen($apres_boucle);
945
+        $boucle['pos_postcond_inside'] = $pos_apres;
946
+        $pos_courante = $pos_apres ;
947
+    }
948
+
949
+    //
950
+    // 2. Récuperer la partie alternative apres
951
+    //
952
+    $altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . '>';
953
+    $pos_altern = strpos($texte, $altern_boucle, $pos_courante);
954
+    if (
955
+        $pos_altern !== false
956
+        and (!$pos_anonyme_next or $pos_altern < $pos_anonyme_next)
957
+    ) {
958
+        $boucle['pos_altern'] = $pos_altern;
959
+        $pos_altern += strlen($altern_boucle);
960
+        $boucle['pos_altern_inside'] = $pos_altern;
961
+        $pos_courante = $pos_altern;
962
+    }
963
+
964
+    //
965
+    // 3. Recuperer la partie footer non alternative
966
+    //
967
+    $postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . '>';
968
+    $pos_postaff = strpos($texte, $postaff_boucle, $pos_courante);
969
+    if (
970
+        $pos_postaff !== false
971
+        and (!$pos_anonyme_next or $pos_postaff < $pos_anonyme_next)
972
+    ) {
973
+        $boucle['pos_postaff'] = $pos_postaff;
974
+        $pos_postaff += strlen($postaff_boucle);
975
+        $boucle['pos_postaff_inside'] = $pos_postaff;
976
+        $pos_courante = $pos_postaff ;
977
+    }
978
+
979
+    return $boucle;
980 980
 }
981 981
 
982 982
 
@@ -986,21 +986,21 @@  discard block
 block discarded – undo
986 986
  * @param null|object $boucle
987 987
  */
988 988
 function phraser_boucle_placeholder(&$champ, $boucle_placeholder = null, $boucle = null) {
989
-	static $boucles_connues = [];
990
-	// si c'est un appel pour memoriser une boucle, memorisons la
991
-	if (is_string($champ) and !empty($boucle_placeholder) and !empty($boucle)) {
992
-		$boucles_connues[$boucle_placeholder][$champ] = &$boucle;
993
-	}
994
-	else {
995
-		if (!empty($champ->nom_champ) and !empty($boucles_connues[$champ->nom_champ])) {
996
-			$placeholder = $champ->nom_champ;
997
-			$id = reset($champ->param[0][1]);
998
-			$id = $id->texte;
999
-			if (!empty($boucles_connues[$placeholder][$id])) {
1000
-				$champ = $boucles_connues[$placeholder][$id];
1001
-			}
1002
-		}
1003
-	}
989
+    static $boucles_connues = [];
990
+    // si c'est un appel pour memoriser une boucle, memorisons la
991
+    if (is_string($champ) and !empty($boucle_placeholder) and !empty($boucle)) {
992
+        $boucles_connues[$boucle_placeholder][$champ] = &$boucle;
993
+    }
994
+    else {
995
+        if (!empty($champ->nom_champ) and !empty($boucles_connues[$champ->nom_champ])) {
996
+            $placeholder = $champ->nom_champ;
997
+            $id = reset($champ->param[0][1]);
998
+            $id = $id->texte;
999
+            if (!empty($boucles_connues[$placeholder][$id])) {
1000
+                $champ = $boucles_connues[$placeholder][$id];
1001
+            }
1002
+        }
1003
+    }
1004 1004
 }
1005 1005
 
1006 1006
 
@@ -1013,274 +1013,274 @@  discard block
 block discarded – undo
1013 1013
  * @return string
1014 1014
  */
1015 1015
 function public_generer_boucle_placeholder($id_boucle, &$boucle, $boucle_placeholder, $nb_lignes) {
1016
-	$placeholder = "[(#{$boucle_placeholder}{" . $id_boucle . '})' . str_pad('', $nb_lignes, "\n") . ']';
1017
-	//memoriser la boucle a reinjecter
1018
-	$id_boucle = "$id_boucle";
1019
-	phraser_boucle_placeholder($id_boucle, $boucle_placeholder, $boucle);
1020
-	return $placeholder;
1016
+    $placeholder = "[(#{$boucle_placeholder}{" . $id_boucle . '})' . str_pad('', $nb_lignes, "\n") . ']';
1017
+    //memoriser la boucle a reinjecter
1018
+    $id_boucle = "$id_boucle";
1019
+    phraser_boucle_placeholder($id_boucle, $boucle_placeholder, $boucle);
1020
+    return $placeholder;
1021 1021
 }
1022 1022
 
1023 1023
 function public_phraser_html_dist($texte, $id_parent, &$boucles, $descr, $ligne_debut_texte = 1, $boucle_placeholder = null) {
1024 1024
 
1025
-	$all_res = [];
1026
-	// definir un placholder pour les boucles dont on est sur d'avoir aucune occurence dans le squelette
1027
-	if (is_null($boucle_placeholder)) {
1028
-		do {
1029
-			$boucle_placeholder = 'BOUCLE_PLACEHOLDER_' . strtoupper(md5(uniqid()));
1030
-		} while (strpos($texte, $boucle_placeholder) !== false);
1031
-	}
1032
-
1033
-	$ligne_debut_initial = $ligne_debut_texte;
1034
-	$pos_debut_texte = 0;
1035
-	while ($boucle = public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte)) {
1036
-		$err_b = ''; // indiquera s'il y a eu une erreur
1037
-		$result = new Boucle();
1038
-		$result->id_parent = $id_parent;
1039
-		$result->descr = $descr;
1040
-
1041
-		$pos_courante = $boucle['pos_boucle'];
1042
-		$pos_parent = $boucle['pos_parent'];
1043
-		$id_boucle_search = $id_boucle = $boucle['id_boucle'];
1044
-
1045
-		$ligne_preaff = $ligne_avant = $ligne_milieu = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_parent);
1046
-
1047
-		// boucle anonyme ?
1048
-		if (!strlen($id_boucle)) {
1049
-			$id_boucle = '_anon_L' . $ligne_milieu . '_' . substr(md5('anonyme:' . $id_parent . ':' . json_encode($boucle, JSON_THROW_ON_ERROR)), 0, 8);
1050
-		}
1051
-
1052
-		$pos_debut_boucle = $pos_courante;
1053
-
1054
-		$pos_milieu = $pos_parent;
1055
-
1056
-		// Regarder si on a une partie conditionnelle avant <B_xxx>
1057
-		if ($boucle['pos_precond'] !== false) {
1058
-			$pos_debut_boucle = $boucle['pos_precond'];
1059
-
1060
-			$pos_avant = $boucle['pos_precond_inside'];
1061
-			$result->avant = substr($texte, $pos_avant, $pos_courante - $pos_avant);
1062
-			$ligne_avant = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_avant);
1063
-		}
1064
-
1065
-		// Regarder si on a une partie inconditionnelle avant <BB_xxx>
1066
-		if ($boucle['pos_preaff'] !== false) {
1067
-			$end_preaff = $pos_debut_boucle;
1068
-
1069
-			$pos_preaff = $boucle['pos_preaff_inside'];
1070
-			$result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
1071
-			$ligne_preaff = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_preaff);
1072
-		}
1073
-
1074
-		$result->id_boucle = $id_boucle;
1075
-
1076
-		if (
1077
-			!preg_match(SPEC_BOUCLE, $texte, $match, 0, $pos_milieu)
1078
-			or ($pos_match = strpos($texte, (string) $match[0], $pos_milieu)) === false
1079
-			or $pos_match > $pos_milieu
1080
-		) {
1081
-			$err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
1082
-			erreur_squelette($err_b, $result);
1083
-
1084
-			$ligne_debut_texte += public_compte_ligne($texte, $pos_debut_texte, $pos_courante + 1);
1085
-			$pos_debut_texte = $pos_courante + 1;
1086
-			continue;
1087
-		}
1088
-
1089
-		$result->type_requete = $match[0];
1090
-		$pos_milieu += strlen($match[0]);
1091
-		$pos_courante = $pos_milieu; // on s'en sert pour compter les lignes plus precisemment
1092
-
1093
-		$type = $match[1];
1094
-		$jointures = trim($match[2]);
1095
-		$table_optionnelle = ($match[3]);
1096
-		if ($jointures) {
1097
-			// on affecte pas ici les jointures explicites, mais dans la compilation
1098
-			// ou elles seront completees des jointures declarees
1099
-			$result->jointures_explicites = $jointures;
1100
-		}
1101
-
1102
-		if ($table_optionnelle) {
1103
-			$result->table_optionnelle = $type;
1104
-		}
1105
-
1106
-		// 1ere passe sur les criteres, vu comme des arguments sans fct
1107
-		// Resultat mis dans result->param
1108
-		$pos_fin_criteres = $pos_milieu;
1109
-		phraser_args($texte, '/>', '', $all_res, $result, $pos_fin_criteres);
1110
-
1111
-		// En 2e passe result->criteres contiendra un tableau
1112
-		// pour l'instant on met le source (chaine) :
1113
-		// si elle reste ici au final, c'est qu'elle contient une erreur
1114
-		$pos_courante = $pos_fin_criteres; // on s'en sert pour compter les lignes plus precisemment
1115
-		$result->criteres = substr($texte, $pos_milieu, $pos_fin_criteres - $pos_milieu);
1116
-		$pos_milieu = $pos_fin_criteres;
1117
-
1118
-		//
1119
-		// Recuperer la fin :
1120
-		//
1121
-		if ($texte[$pos_milieu] === '/') {
1122
-			// boucle autofermante : pas de partie conditionnelle apres
1123
-			$pos_courante += 2;
1124
-			$result->milieu = '';
1125
-		} else {
1126
-			$pos_milieu += 1;
1127
-
1128
-			$fin_boucle = BALISE_FIN_BOUCLE . $id_boucle_search . '>';
1129
-			$pos_fin = strpos($texte, $fin_boucle, $pos_milieu);
1130
-			if ($pos_fin === false) {
1131
-				$err_b = [
1132
-					'zbug_erreur_boucle_fermant',
1133
-					['id' => $id_boucle]
1134
-				];
1135
-				erreur_squelette($err_b, $result);
1136
-				$pos_courante += strlen($fin_boucle);
1137
-			}
1138
-			else {
1139
-				// verifier une eventuelle imbrication d'une boucle homonyme
1140
-				// (interdite, generera une erreur plus loin, mais permet de signaler la bonne erreur)
1141
-				$search_debut_boucle = BALISE_BOUCLE . $id_boucle_search . '(';
1142
-				$search_from = $pos_milieu;
1143
-				$nb_open = 1;
1144
-				$nb_close = 1;
1145
-				$maxiter = 0;
1146
-				do {
1147
-					while (
1148
-						$nb_close < $nb_open
1149
-						and $p = strpos($texte, $fin_boucle, $pos_fin + 1)
1150
-					) {
1151
-						$nb_close++;
1152
-						$pos_fin = $p;
1153
-					}
1154
-					// si on a pas trouve assez de boucles fermantes, sortir de la, on a fait de notre mieux
1155
-					if ($nb_close < $nb_open) {
1156
-						break;
1157
-					}
1158
-					while (
1159
-						$p = strpos($texte, $search_debut_boucle, $search_from)
1160
-						and $p < $pos_fin
1161
-					) {
1162
-						$nb_open++;
1163
-						$search_from = $p + 1;
1164
-					}
1165
-				} while ($nb_close < $nb_open and $maxiter++ < 5);
1166
-
1167
-				$pos_courante = $pos_fin + strlen($fin_boucle);
1168
-			}
1169
-			$result->milieu = substr($texte, $pos_milieu, $pos_fin - $pos_milieu);
1170
-		}
1171
-
1172
-		$ligne_suite = $ligne_apres = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_courante);
1173
-		$boucle = public_trouver_fin_boucle($texte, $id_parent, $boucle, $pos_courante, $result);
1174
-
1175
-		//
1176
-		// 1. Partie conditionnelle apres ?
1177
-		//
1178
-		if ($boucle['pos_postcond']) {
1179
-			$result->apres = substr($texte, $pos_courante, $boucle['pos_postcond'] - $pos_courante);
1180
-			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postcond_inside']);
1181
-			$pos_courante = $boucle['pos_postcond_inside'] ;
1182
-		}
1183
-
1184
-
1185
-		//
1186
-		// 2. Partie alternative apres ?
1187
-		//
1188
-		$ligne_altern = $ligne_suite;
1189
-		if ($boucle['pos_altern']) {
1190
-			$result->altern = substr($texte, $pos_courante, $boucle['pos_altern'] - $pos_courante);
1191
-			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_altern_inside']);
1192
-			$pos_courante = $boucle['pos_altern_inside'];
1193
-		}
1194
-
1195
-		//
1196
-		// 3. Partie footer non alternative ?
1197
-		//
1198
-		$ligne_postaff = $ligne_suite;
1199
-		if ($boucle['pos_postaff']) {
1200
-			$result->postaff = substr($texte, $pos_courante, $boucle['pos_postaff'] - $pos_courante);
1201
-			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postaff_inside']);
1202
-			$pos_courante = $boucle['pos_postaff_inside'];
1203
-		}
1204
-
1205
-		$result->ligne = $ligne_preaff;
1206
-
1207
-		if ($p = strpos($type, ':')) {
1208
-			$result->sql_serveur = substr($type, 0, $p);
1209
-			$type = substr($type, $p + 1);
1210
-		}
1211
-		$soustype = strtolower($type);
1212
-
1213
-		if (!isset($GLOBALS['table_des_tables'][$soustype])) {
1214
-			$soustype = $type;
1215
-		}
1216
-
1217
-		$result->type_requete = $soustype;
1218
-		// Lancer la 2e passe sur les criteres si la 1ere etait bonne
1219
-		if (!is_array($result->param)) {
1220
-			$err_b = true;
1221
-		} else {
1222
-			phraser_criteres($result->param, $result);
1223
-			if (strncasecmp($soustype, TYPE_RECURSIF, strlen(TYPE_RECURSIF)) == 0) {
1224
-				$result->type_requete = TYPE_RECURSIF;
1225
-				$args = $result->param;
1226
-				array_unshift(
1227
-					$args,
1228
-					substr($type, strlen(TYPE_RECURSIF))
1229
-				);
1230
-				$result->param = $args;
1231
-			}
1232
-		}
1233
-
1234
-		$descr['id_mere_contexte'] = $id_boucle;
1235
-		$result->milieu = public_phraser_html_dist($result->milieu, $id_boucle, $boucles, $descr, $ligne_milieu, $boucle_placeholder);
1236
-		// reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre
1237
-		// ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle
1238
-		// si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite
1239
-		if (empty($boucles[$id_boucle])) {
1240
-			$boucles[$id_boucle] = null;
1241
-		}
1242
-		$result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff, $boucle_placeholder);
1243
-		$result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant, $boucle_placeholder);
1244
-		$result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres, $boucle_placeholder);
1245
-		$result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern, $boucle_placeholder);
1246
-		$result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff, $boucle_placeholder);
1247
-
1248
-		// Prevenir le generateur de code que le squelette est faux
1249
-		if ($err_b) {
1250
-			$result->type_requete = false;
1251
-		}
1252
-
1253
-		// Verifier qu'il n'y a pas double definition
1254
-		// apres analyse des sous-parties (pas avant).
1255
-		if (!empty($boucles[$id_boucle])) {
1256
-			if ($boucles[$id_boucle]->type_requete !== false) {
1257
-				$err_b_d = [
1258
-					'zbug_erreur_boucle_double',
1259
-					['id' => $id_boucle]
1260
-				];
1261
-				erreur_squelette($err_b_d, $result);
1262
-				// Prevenir le generateur de code que le squelette est faux
1263
-				$boucles[$id_boucle]->type_requete = false;
1264
-			}
1265
-		} else {
1266
-			$boucles[$id_boucle] = $result;
1267
-		}
1268
-
1269
-		// remplacer la boucle par un placeholder qui compte le meme nombre de lignes
1270
-		$placeholder = public_generer_boucle_placeholder($id_boucle, $boucles[$id_boucle], $boucle_placeholder, $ligne_suite - $ligne_debut_texte);
1271
-		$longueur_boucle = $pos_courante - $boucle['debut_boucle'];
1272
-		$texte = substr_replace($texte, $placeholder, $boucle['debut_boucle'], $longueur_boucle);
1273
-		$pos_courante = $pos_courante - $longueur_boucle + strlen($placeholder);
1274
-
1275
-		// phraser la partie avant le debut de la boucle
1276
-		#$all_res = phraser_champs_etendus(substr($texte, $pos_debut_texte, $boucle['debut_boucle'] - $pos_debut_texte), $ligne_debut_texte, $all_res);
1277
-		#$all_res[] = &$boucles[$id_boucle];
1278
-
1279
-		$ligne_debut_texte = $ligne_suite;
1280
-		$pos_debut_texte = $pos_courante;
1281
-	}
1282
-
1283
-	$all_res = phraser_champs_etendus($texte, $ligne_debut_initial, $all_res);
1284
-
1285
-	return $all_res;
1025
+    $all_res = [];
1026
+    // definir un placholder pour les boucles dont on est sur d'avoir aucune occurence dans le squelette
1027
+    if (is_null($boucle_placeholder)) {
1028
+        do {
1029
+            $boucle_placeholder = 'BOUCLE_PLACEHOLDER_' . strtoupper(md5(uniqid()));
1030
+        } while (strpos($texte, $boucle_placeholder) !== false);
1031
+    }
1032
+
1033
+    $ligne_debut_initial = $ligne_debut_texte;
1034
+    $pos_debut_texte = 0;
1035
+    while ($boucle = public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte)) {
1036
+        $err_b = ''; // indiquera s'il y a eu une erreur
1037
+        $result = new Boucle();
1038
+        $result->id_parent = $id_parent;
1039
+        $result->descr = $descr;
1040
+
1041
+        $pos_courante = $boucle['pos_boucle'];
1042
+        $pos_parent = $boucle['pos_parent'];
1043
+        $id_boucle_search = $id_boucle = $boucle['id_boucle'];
1044
+
1045
+        $ligne_preaff = $ligne_avant = $ligne_milieu = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_parent);
1046
+
1047
+        // boucle anonyme ?
1048
+        if (!strlen($id_boucle)) {
1049
+            $id_boucle = '_anon_L' . $ligne_milieu . '_' . substr(md5('anonyme:' . $id_parent . ':' . json_encode($boucle, JSON_THROW_ON_ERROR)), 0, 8);
1050
+        }
1051
+
1052
+        $pos_debut_boucle = $pos_courante;
1053
+
1054
+        $pos_milieu = $pos_parent;
1055
+
1056
+        // Regarder si on a une partie conditionnelle avant <B_xxx>
1057
+        if ($boucle['pos_precond'] !== false) {
1058
+            $pos_debut_boucle = $boucle['pos_precond'];
1059
+
1060
+            $pos_avant = $boucle['pos_precond_inside'];
1061
+            $result->avant = substr($texte, $pos_avant, $pos_courante - $pos_avant);
1062
+            $ligne_avant = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_avant);
1063
+        }
1064
+
1065
+        // Regarder si on a une partie inconditionnelle avant <BB_xxx>
1066
+        if ($boucle['pos_preaff'] !== false) {
1067
+            $end_preaff = $pos_debut_boucle;
1068
+
1069
+            $pos_preaff = $boucle['pos_preaff_inside'];
1070
+            $result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
1071
+            $ligne_preaff = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_preaff);
1072
+        }
1073
+
1074
+        $result->id_boucle = $id_boucle;
1075
+
1076
+        if (
1077
+            !preg_match(SPEC_BOUCLE, $texte, $match, 0, $pos_milieu)
1078
+            or ($pos_match = strpos($texte, (string) $match[0], $pos_milieu)) === false
1079
+            or $pos_match > $pos_milieu
1080
+        ) {
1081
+            $err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
1082
+            erreur_squelette($err_b, $result);
1083
+
1084
+            $ligne_debut_texte += public_compte_ligne($texte, $pos_debut_texte, $pos_courante + 1);
1085
+            $pos_debut_texte = $pos_courante + 1;
1086
+            continue;
1087
+        }
1088
+
1089
+        $result->type_requete = $match[0];
1090
+        $pos_milieu += strlen($match[0]);
1091
+        $pos_courante = $pos_milieu; // on s'en sert pour compter les lignes plus precisemment
1092
+
1093
+        $type = $match[1];
1094
+        $jointures = trim($match[2]);
1095
+        $table_optionnelle = ($match[3]);
1096
+        if ($jointures) {
1097
+            // on affecte pas ici les jointures explicites, mais dans la compilation
1098
+            // ou elles seront completees des jointures declarees
1099
+            $result->jointures_explicites = $jointures;
1100
+        }
1101
+
1102
+        if ($table_optionnelle) {
1103
+            $result->table_optionnelle = $type;
1104
+        }
1105
+
1106
+        // 1ere passe sur les criteres, vu comme des arguments sans fct
1107
+        // Resultat mis dans result->param
1108
+        $pos_fin_criteres = $pos_milieu;
1109
+        phraser_args($texte, '/>', '', $all_res, $result, $pos_fin_criteres);
1110
+
1111
+        // En 2e passe result->criteres contiendra un tableau
1112
+        // pour l'instant on met le source (chaine) :
1113
+        // si elle reste ici au final, c'est qu'elle contient une erreur
1114
+        $pos_courante = $pos_fin_criteres; // on s'en sert pour compter les lignes plus precisemment
1115
+        $result->criteres = substr($texte, $pos_milieu, $pos_fin_criteres - $pos_milieu);
1116
+        $pos_milieu = $pos_fin_criteres;
1117
+
1118
+        //
1119
+        // Recuperer la fin :
1120
+        //
1121
+        if ($texte[$pos_milieu] === '/') {
1122
+            // boucle autofermante : pas de partie conditionnelle apres
1123
+            $pos_courante += 2;
1124
+            $result->milieu = '';
1125
+        } else {
1126
+            $pos_milieu += 1;
1127
+
1128
+            $fin_boucle = BALISE_FIN_BOUCLE . $id_boucle_search . '>';
1129
+            $pos_fin = strpos($texte, $fin_boucle, $pos_milieu);
1130
+            if ($pos_fin === false) {
1131
+                $err_b = [
1132
+                    'zbug_erreur_boucle_fermant',
1133
+                    ['id' => $id_boucle]
1134
+                ];
1135
+                erreur_squelette($err_b, $result);
1136
+                $pos_courante += strlen($fin_boucle);
1137
+            }
1138
+            else {
1139
+                // verifier une eventuelle imbrication d'une boucle homonyme
1140
+                // (interdite, generera une erreur plus loin, mais permet de signaler la bonne erreur)
1141
+                $search_debut_boucle = BALISE_BOUCLE . $id_boucle_search . '(';
1142
+                $search_from = $pos_milieu;
1143
+                $nb_open = 1;
1144
+                $nb_close = 1;
1145
+                $maxiter = 0;
1146
+                do {
1147
+                    while (
1148
+                        $nb_close < $nb_open
1149
+                        and $p = strpos($texte, $fin_boucle, $pos_fin + 1)
1150
+                    ) {
1151
+                        $nb_close++;
1152
+                        $pos_fin = $p;
1153
+                    }
1154
+                    // si on a pas trouve assez de boucles fermantes, sortir de la, on a fait de notre mieux
1155
+                    if ($nb_close < $nb_open) {
1156
+                        break;
1157
+                    }
1158
+                    while (
1159
+                        $p = strpos($texte, $search_debut_boucle, $search_from)
1160
+                        and $p < $pos_fin
1161
+                    ) {
1162
+                        $nb_open++;
1163
+                        $search_from = $p + 1;
1164
+                    }
1165
+                } while ($nb_close < $nb_open and $maxiter++ < 5);
1166
+
1167
+                $pos_courante = $pos_fin + strlen($fin_boucle);
1168
+            }
1169
+            $result->milieu = substr($texte, $pos_milieu, $pos_fin - $pos_milieu);
1170
+        }
1171
+
1172
+        $ligne_suite = $ligne_apres = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_courante);
1173
+        $boucle = public_trouver_fin_boucle($texte, $id_parent, $boucle, $pos_courante, $result);
1174
+
1175
+        //
1176
+        // 1. Partie conditionnelle apres ?
1177
+        //
1178
+        if ($boucle['pos_postcond']) {
1179
+            $result->apres = substr($texte, $pos_courante, $boucle['pos_postcond'] - $pos_courante);
1180
+            $ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postcond_inside']);
1181
+            $pos_courante = $boucle['pos_postcond_inside'] ;
1182
+        }
1183
+
1184
+
1185
+        //
1186
+        // 2. Partie alternative apres ?
1187
+        //
1188
+        $ligne_altern = $ligne_suite;
1189
+        if ($boucle['pos_altern']) {
1190
+            $result->altern = substr($texte, $pos_courante, $boucle['pos_altern'] - $pos_courante);
1191
+            $ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_altern_inside']);
1192
+            $pos_courante = $boucle['pos_altern_inside'];
1193
+        }
1194
+
1195
+        //
1196
+        // 3. Partie footer non alternative ?
1197
+        //
1198
+        $ligne_postaff = $ligne_suite;
1199
+        if ($boucle['pos_postaff']) {
1200
+            $result->postaff = substr($texte, $pos_courante, $boucle['pos_postaff'] - $pos_courante);
1201
+            $ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postaff_inside']);
1202
+            $pos_courante = $boucle['pos_postaff_inside'];
1203
+        }
1204
+
1205
+        $result->ligne = $ligne_preaff;
1206
+
1207
+        if ($p = strpos($type, ':')) {
1208
+            $result->sql_serveur = substr($type, 0, $p);
1209
+            $type = substr($type, $p + 1);
1210
+        }
1211
+        $soustype = strtolower($type);
1212
+
1213
+        if (!isset($GLOBALS['table_des_tables'][$soustype])) {
1214
+            $soustype = $type;
1215
+        }
1216
+
1217
+        $result->type_requete = $soustype;
1218
+        // Lancer la 2e passe sur les criteres si la 1ere etait bonne
1219
+        if (!is_array($result->param)) {
1220
+            $err_b = true;
1221
+        } else {
1222
+            phraser_criteres($result->param, $result);
1223
+            if (strncasecmp($soustype, TYPE_RECURSIF, strlen(TYPE_RECURSIF)) == 0) {
1224
+                $result->type_requete = TYPE_RECURSIF;
1225
+                $args = $result->param;
1226
+                array_unshift(
1227
+                    $args,
1228
+                    substr($type, strlen(TYPE_RECURSIF))
1229
+                );
1230
+                $result->param = $args;
1231
+            }
1232
+        }
1233
+
1234
+        $descr['id_mere_contexte'] = $id_boucle;
1235
+        $result->milieu = public_phraser_html_dist($result->milieu, $id_boucle, $boucles, $descr, $ligne_milieu, $boucle_placeholder);
1236
+        // reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre
1237
+        // ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle
1238
+        // si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite
1239
+        if (empty($boucles[$id_boucle])) {
1240
+            $boucles[$id_boucle] = null;
1241
+        }
1242
+        $result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff, $boucle_placeholder);
1243
+        $result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant, $boucle_placeholder);
1244
+        $result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres, $boucle_placeholder);
1245
+        $result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern, $boucle_placeholder);
1246
+        $result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff, $boucle_placeholder);
1247
+
1248
+        // Prevenir le generateur de code que le squelette est faux
1249
+        if ($err_b) {
1250
+            $result->type_requete = false;
1251
+        }
1252
+
1253
+        // Verifier qu'il n'y a pas double definition
1254
+        // apres analyse des sous-parties (pas avant).
1255
+        if (!empty($boucles[$id_boucle])) {
1256
+            if ($boucles[$id_boucle]->type_requete !== false) {
1257
+                $err_b_d = [
1258
+                    'zbug_erreur_boucle_double',
1259
+                    ['id' => $id_boucle]
1260
+                ];
1261
+                erreur_squelette($err_b_d, $result);
1262
+                // Prevenir le generateur de code que le squelette est faux
1263
+                $boucles[$id_boucle]->type_requete = false;
1264
+            }
1265
+        } else {
1266
+            $boucles[$id_boucle] = $result;
1267
+        }
1268
+
1269
+        // remplacer la boucle par un placeholder qui compte le meme nombre de lignes
1270
+        $placeholder = public_generer_boucle_placeholder($id_boucle, $boucles[$id_boucle], $boucle_placeholder, $ligne_suite - $ligne_debut_texte);
1271
+        $longueur_boucle = $pos_courante - $boucle['debut_boucle'];
1272
+        $texte = substr_replace($texte, $placeholder, $boucle['debut_boucle'], $longueur_boucle);
1273
+        $pos_courante = $pos_courante - $longueur_boucle + strlen($placeholder);
1274
+
1275
+        // phraser la partie avant le debut de la boucle
1276
+        #$all_res = phraser_champs_etendus(substr($texte, $pos_debut_texte, $boucle['debut_boucle'] - $pos_debut_texte), $ligne_debut_texte, $all_res);
1277
+        #$all_res[] = &$boucles[$id_boucle];
1278
+
1279
+        $ligne_debut_texte = $ligne_suite;
1280
+        $pos_debut_texte = $pos_courante;
1281
+    }
1282
+
1283
+    $all_res = phraser_champs_etendus($texte, $ligne_debut_initial, $all_res);
1284
+
1285
+    return $all_res;
1286 1286
 }
Please login to merge, or discard this patch.
ecrire/public/criteres.php 1 patch
Indentation   +1717 added lines, -1717 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
  **/
22 22
 
23 23
 if (!defined('_ECRIRE_INC_VERSION')) {
24
-	return;
24
+    return;
25 25
 }
26 26
 
27 27
 /**
@@ -47,12 +47,12 @@  discard block
 block discarded – undo
47 47
  **/
48 48
 function critere_racine_dist($idb, &$boucles, $crit) {
49 49
 
50
-	$not = $crit->not;
51
-	$boucle = &$boucles[$idb];
52
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
50
+    $not = $crit->not;
51
+    $boucle = &$boucles[$idb];
52
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
53 53
 
54
-	$c = ["'='", "'$boucle->id_table." . "$id_parent'", 0];
55
-	$boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
54
+    $c = ["'='", "'$boucle->id_table." . "$id_parent'", 0];
55
+    $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
56 56
 }
57 57
 
58 58
 
@@ -69,15 +69,15 @@  discard block
 block discarded – undo
69 69
  * @return void|array
70 70
  **/
71 71
 function critere_exclus_dist($idb, &$boucles, $crit) {
72
-	$not = $crit->not;
73
-	$boucle = &$boucles[$idb];
74
-	$id = $boucle->primary;
75
-
76
-	if ($not or !$id) {
77
-		return ['zbug_critere_inconnu', ['critere' => $not . $crit->op]];
78
-	}
79
-	$arg = kwote(calculer_argument_precedent($idb, $id, $boucles));
80
-	$boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg];
72
+    $not = $crit->not;
73
+    $boucle = &$boucles[$idb];
74
+    $id = $boucle->primary;
75
+
76
+    if ($not or !$id) {
77
+        return ['zbug_critere_inconnu', ['critere' => $not . $crit->op]];
78
+    }
79
+    $arg = kwote(calculer_argument_precedent($idb, $id, $boucles));
80
+    $boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg];
81 81
 }
82 82
 
83 83
 
@@ -97,73 +97,73 @@  discard block
 block discarded – undo
97 97
  * @return void|array
98 98
  **/
99 99
 function critere_doublons_dist($idb, &$boucles, $crit) {
100
-	$boucle = &$boucles[$idb];
101
-	$primary = $boucle->primary;
102
-
103
-	// la table nécessite une clé primaire, non composée
104
-	if (!$primary or strpos($primary, ',')) {
105
-		return ['zbug_doublon_sur_table_sans_cle_primaire'];
106
-	}
107
-
108
-	$not = ($crit->not ? '' : 'NOT');
109
-
110
-	// le doublon s'applique sur un type de boucle (article)
111
-	$nom = "'" . $boucle->type_requete . "'";
112
-
113
-	// compléter le nom avec un nom précisé {doublons nom}
114
-	// on obtient $nom = "'article' . 'nom'"
115
-	if (isset($crit->param[0])) {
116
-		$nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
117
-	}
118
-
119
-	// code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP)
120
-	$init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n";
121
-	$init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n";
122
-
123
-	// on crée un sql_in avec la clé primaire de la table
124
-	// et la collection des doublons déjà emmagasinés dans le tableau
125
-	// $doublons et son index, ici $nom
126
-
127
-	// debut du code "sql_in('articles.id_article', "
128
-	$debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', ";
129
-	// lecture des données du doublon "$doublons[$doublon_index[] = "
130
-	// Attention : boucle->doublons désigne une variable qu'on affecte
131
-	$debut_doub = '$doublons[' . (!$not ? '' : ($boucle->doublons . '[]= '));
132
-
133
-	// le debut complet du code des doublons
134
-	$debut_doub = $debut_in . $debut_doub;
135
-
136
-	// nom du doublon "('article' . 'nom')]"
137
-	$fin_doub = "($nom)]";
138
-
139
-	// si on trouve un autre critère doublon,
140
-	// on fusionne pour avoir un seul IN, et on s'en va !
141
-	foreach ($boucle->where as $k => $w) {
142
-		if (strpos($w[0], $debut_doub) === 0) {
143
-			// fusionner le sql_in (du where)
144
-			$boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr($w[0], strlen($debut_in));
145
-			// fusionner l'initialisation (du hash) pour faire plus joli
146
-			$x = strpos($boucle->hash, $init_comment);
147
-			$len = strlen($init_comment);
148
-			$boucle->hash =
149
-				substr($boucle->hash, 0, $x + $len) . $init_code . substr($boucle->hash, $x + $len);
150
-
151
-			return;
152
-		}
153
-	}
154
-
155
-	// mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante
156
-	$boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"];
157
-
158
-	// déclarer le doublon s'il n'existe pas encore
159
-	$boucle->hash .= $init_comment . $init_code;
160
-
161
-
162
-	# la ligne suivante avait l'intention d'eviter une collecte deja faite
163
-	# mais elle fait planter une boucle a 2 critere doublons:
164
-	# {!doublons A}{doublons B}
165
-	# (de http://article.gmane.org/gmane.comp.web.spip.devel/31034)
166
-	#	if ($crit->not) $boucle->doublons = "";
100
+    $boucle = &$boucles[$idb];
101
+    $primary = $boucle->primary;
102
+
103
+    // la table nécessite une clé primaire, non composée
104
+    if (!$primary or strpos($primary, ',')) {
105
+        return ['zbug_doublon_sur_table_sans_cle_primaire'];
106
+    }
107
+
108
+    $not = ($crit->not ? '' : 'NOT');
109
+
110
+    // le doublon s'applique sur un type de boucle (article)
111
+    $nom = "'" . $boucle->type_requete . "'";
112
+
113
+    // compléter le nom avec un nom précisé {doublons nom}
114
+    // on obtient $nom = "'article' . 'nom'"
115
+    if (isset($crit->param[0])) {
116
+        $nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
117
+    }
118
+
119
+    // code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP)
120
+    $init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n";
121
+    $init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n";
122
+
123
+    // on crée un sql_in avec la clé primaire de la table
124
+    // et la collection des doublons déjà emmagasinés dans le tableau
125
+    // $doublons et son index, ici $nom
126
+
127
+    // debut du code "sql_in('articles.id_article', "
128
+    $debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', ";
129
+    // lecture des données du doublon "$doublons[$doublon_index[] = "
130
+    // Attention : boucle->doublons désigne une variable qu'on affecte
131
+    $debut_doub = '$doublons[' . (!$not ? '' : ($boucle->doublons . '[]= '));
132
+
133
+    // le debut complet du code des doublons
134
+    $debut_doub = $debut_in . $debut_doub;
135
+
136
+    // nom du doublon "('article' . 'nom')]"
137
+    $fin_doub = "($nom)]";
138
+
139
+    // si on trouve un autre critère doublon,
140
+    // on fusionne pour avoir un seul IN, et on s'en va !
141
+    foreach ($boucle->where as $k => $w) {
142
+        if (strpos($w[0], $debut_doub) === 0) {
143
+            // fusionner le sql_in (du where)
144
+            $boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr($w[0], strlen($debut_in));
145
+            // fusionner l'initialisation (du hash) pour faire plus joli
146
+            $x = strpos($boucle->hash, $init_comment);
147
+            $len = strlen($init_comment);
148
+            $boucle->hash =
149
+                substr($boucle->hash, 0, $x + $len) . $init_code . substr($boucle->hash, $x + $len);
150
+
151
+            return;
152
+        }
153
+    }
154
+
155
+    // mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante
156
+    $boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"];
157
+
158
+    // déclarer le doublon s'il n'existe pas encore
159
+    $boucle->hash .= $init_comment . $init_code;
160
+
161
+
162
+    # la ligne suivante avait l'intention d'eviter une collecte deja faite
163
+    # mais elle fait planter une boucle a 2 critere doublons:
164
+    # {!doublons A}{doublons B}
165
+    # (de http://article.gmane.org/gmane.comp.web.spip.devel/31034)
166
+    #	if ($crit->not) $boucle->doublons = "";
167 167
 }
168 168
 
169 169
 
@@ -184,14 +184,14 @@  discard block
 block discarded – undo
184 184
  * @return void
185 185
  **/
186 186
 function critere_lang_select_dist($idb, &$boucles, $crit) {
187
-	if (!isset($crit->param[1][0]) or !($param = $crit->param[1][0]->texte)) {
188
-		$param = 'oui';
189
-	}
190
-	if ($crit->not) {
191
-		$param = ($param == 'oui') ? 'non' : 'oui';
192
-	}
193
-	$boucle = &$boucles[$idb];
194
-	$boucle->lang_select = $param;
187
+    if (!isset($crit->param[1][0]) or !($param = $crit->param[1][0]->texte)) {
188
+        $param = 'oui';
189
+    }
190
+    if ($crit->not) {
191
+        $param = ($param == 'oui') ? 'non' : 'oui';
192
+    }
193
+    $boucle = &$boucles[$idb];
194
+    $boucle->lang_select = $param;
195 195
 }
196 196
 
197 197
 
@@ -213,15 +213,15 @@  discard block
 block discarded – undo
213 213
  * @return void
214 214
  **/
215 215
 function critere_debut_dist($idb, &$boucles, $crit) {
216
-	[$un, $deux] = $crit->param;
217
-	$un = $un[0]->texte;
218
-	$deux = $deux[0]->texte;
219
-	if ($deux) {
220
-		$boucles[$idb]->limit =
221
-			'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"';
222
-	} else {
223
-		calculer_critere_DEFAUT_dist($idb, $boucles, $crit);
224
-	}
216
+    [$un, $deux] = $crit->param;
217
+    $un = $un[0]->texte;
218
+    $deux = $deux[0]->texte;
219
+    if ($deux) {
220
+        $boucles[$idb]->limit =
221
+            'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"';
222
+    } else {
223
+        calculer_critere_DEFAUT_dist($idb, $boucles, $crit);
224
+    }
225 225
 }
226 226
 
227 227
 
@@ -255,58 +255,58 @@  discard block
 block discarded – undo
255 255
  **/
256 256
 function critere_pagination_dist($idb, &$boucles, $crit) {
257 257
 
258
-	$boucle = &$boucles[$idb];
259
-	// definition de la taille de la page
260
-	$pas = !isset($crit->param[0][0]) ? "''"
261
-		: calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent);
262
-
263
-	if (!preg_match(_CODE_QUOTE, $pas, $r)) {
264
-		$pas = "((\$a = intval($pas)) ? \$a : 10)";
265
-	} else {
266
-		$r = intval($r[2]);
267
-		$pas = strval($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($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 .= '
258
+    $boucle = &$boucles[$idb];
259
+    // definition de la taille de la page
260
+    $pas = !isset($crit->param[0][0]) ? "''"
261
+        : calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent);
262
+
263
+    if (!preg_match(_CODE_QUOTE, $pas, $r)) {
264
+        $pas = "((\$a = intval($pas)) ? \$a : 10)";
265
+    } else {
266
+        $r = intval($r[2]);
267
+        $pas = strval($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($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
-		and !preg_match('/[,\s]/', $boucle->primary)
306
-		and !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
+        and !preg_match('/[,\s]/', $boucle->primary)
306
+        and !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 or strpos($boucle->primary, ',')) {
334
-		erreur_squelette(_T('zbug_critere_sur_table_sans_cle_primaire', ['critere' => 'recherche']), $boucle);
333
+    if (!$boucle->primary or strpos($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' or 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' or 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,37 +491,37 @@  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 ? $c :
524
-		("($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')');
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 ? $c :
524
+        ("($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')');
525 525
 }
526 526
 
527 527
 /**
@@ -537,15 +537,15 @@  discard block
 block discarded – undo
537 537
  **/
538 538
 function critere_logo_dist($idb, &$boucles, $crit) {
539 539
 
540
-	$boucle = &$boucles[$idb];
541
-	$not = ($crit->not ? 'NOT' : '');
542
-	$serveur = $boucle->sql_serveur;
540
+    $boucle = &$boucles[$idb];
541
+    $not = ($crit->not ? 'NOT' : '');
542
+    $serveur = $boucle->sql_serveur;
543 543
 
544
-	$c = "sql_in('" .
545
-		$boucle->id_table . '.' . $boucle->primary
546
-		. "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')";
544
+    $c = "sql_in('" .
545
+        $boucle->id_table . '.' . $boucle->primary
546
+        . "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')";
547 547
 
548
-	$boucle->where[] = $c;
548
+    $boucle->where[] = $c;
549 549
 }
550 550
 
551 551
 
@@ -567,31 +567,31 @@  discard block
 block discarded – undo
567 567
  * @return void|array
568 568
  **/
569 569
 function critere_fusion_dist($idb, &$boucles, $crit) {
570
-	if ($t = isset($crit->param[0])) {
571
-		$t = $crit->param[0];
572
-		if ($t[0]->type == 'texte') {
573
-			$t = $t[0]->texte;
574
-			if (preg_match('/^(.*)\.(.*)$/', $t, $r)) {
575
-				$t = table_objet_sql($r[1]);
576
-				$t = array_search($t, $boucles[$idb]->from);
577
-				if ($t) {
578
-					$t .= '.' . $r[2];
579
-				}
580
-			}
581
-		} else {
582
-			$t = '".'
583
-				. calculer_critere_arg_dynamique($idb, $boucles, $t)
584
-				. '."';
585
-		}
586
-	}
587
-	if ($t) {
588
-		$boucles[$idb]->group[] = $t;
589
-		if (!in_array($t, $boucles[$idb]->select)) {
590
-			$boucles[$idb]->select[] = $t;
591
-		}
592
-	} else {
593
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
594
-	}
570
+    if ($t = isset($crit->param[0])) {
571
+        $t = $crit->param[0];
572
+        if ($t[0]->type == 'texte') {
573
+            $t = $t[0]->texte;
574
+            if (preg_match('/^(.*)\.(.*)$/', $t, $r)) {
575
+                $t = table_objet_sql($r[1]);
576
+                $t = array_search($t, $boucles[$idb]->from);
577
+                if ($t) {
578
+                    $t .= '.' . $r[2];
579
+                }
580
+            }
581
+        } else {
582
+            $t = '".'
583
+                . calculer_critere_arg_dynamique($idb, $boucles, $t)
584
+                . '."';
585
+        }
586
+    }
587
+    if ($t) {
588
+        $boucles[$idb]->group[] = $t;
589
+        if (!in_array($t, $boucles[$idb]->select)) {
590
+            $boucles[$idb]->select[] = $t;
591
+        }
592
+    } else {
593
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
594
+    }
595 595
 }
596 596
 
597 597
 /**
@@ -611,7 +611,7 @@  discard block
 block discarded – undo
611 611
  * @return void
612 612
  **/
613 613
 function critere_fusion_supprimer_dist($idb, &$boucles, $crit) {
614
-	$boucles[$idb]->group = [];
614
+    $boucles[$idb]->group = [];
615 615
 }
616 616
 
617 617
 /**
@@ -648,44 +648,44 @@  discard block
 block discarded – undo
648 648
  * @param Critere $crit Paramètres du critère dans cette boucle
649 649
  */
650 650
 function critere_collecte_dist($idb, &$boucles, $crit) {
651
-	if (isset($crit->param[0])) {
652
-		$_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
653
-		$boucle = $boucles[$idb];
654
-		$boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')";
655
-		$n = is_countable($boucle->order) ? count($boucle->order) : 0;
656
-		if ($n && (strpos($boucle->order[$n - 1], 'COLLATE') === false)) {
657
-			// l'instruction COLLATE doit être placée avant ASC ou DESC
658
-			// notamment lors de l'utilisation `{!par xxx}{collate yyy}`
659
-			if (
660
-				(false !== $i = strpos($boucle->order[$n - 1], 'ASC'))
661
-				or (false !== $i = strpos($boucle->order[$n - 1], 'DESC'))
662
-			) {
663
-				$boucle->order[$n - 1] = substr_replace($boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0);
664
-			} else {
665
-				$boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate'];
666
-			}
667
-		}
668
-	} else {
669
-		return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]);
670
-	}
651
+    if (isset($crit->param[0])) {
652
+        $_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
653
+        $boucle = $boucles[$idb];
654
+        $boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')";
655
+        $n = is_countable($boucle->order) ? count($boucle->order) : 0;
656
+        if ($n && (strpos($boucle->order[$n - 1], 'COLLATE') === false)) {
657
+            // l'instruction COLLATE doit être placée avant ASC ou DESC
658
+            // notamment lors de l'utilisation `{!par xxx}{collate yyy}`
659
+            if (
660
+                (false !== $i = strpos($boucle->order[$n - 1], 'ASC'))
661
+                or (false !== $i = strpos($boucle->order[$n - 1], 'DESC'))
662
+            ) {
663
+                $boucle->order[$n - 1] = substr_replace($boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0);
664
+            } else {
665
+                $boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate'];
666
+            }
667
+        }
668
+    } else {
669
+        return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]);
670
+    }
671 671
 }
672 672
 
673 673
 function calculer_critere_arg_dynamique($idb, &$boucles, $crit, $suffix = '') {
674
-	$boucle = $boucles[$idb];
675
-	$alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')';
676
-	$var = '$champs_' . $idb;
677
-	$desc = (strpos($boucle->in, (string) "static $var =") !== false);
678
-	if (!$desc) {
679
-		$desc = $boucle->show['field'];
680
-		$desc = implode(',', array_map('_q', array_keys($desc)));
681
-		$boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');';
682
-	}
683
-	if ($desc) {
684
-		$alt = "(in_array(\$x, $var)  ? $alt :(\$x$suffix))";
685
-	}
686
-	$arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent);
687
-
688
-	return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')";
674
+    $boucle = $boucles[$idb];
675
+    $alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')';
676
+    $var = '$champs_' . $idb;
677
+    $desc = (strpos($boucle->in, (string) "static $var =") !== false);
678
+    if (!$desc) {
679
+        $desc = $boucle->show['field'];
680
+        $desc = implode(',', array_map('_q', array_keys($desc)));
681
+        $boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');';
682
+    }
683
+    if ($desc) {
684
+        $alt = "(in_array(\$x, $var)  ? $alt :(\$x$suffix))";
685
+    }
686
+    $arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent);
687
+
688
+    return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')";
689 689
 }
690 690
 
691 691
 /**
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
  * @param Critere $crit Paramètres du critère dans cette boucle
725 725
  */
726 726
 function critere_par_dist($idb, &$boucles, $crit) {
727
-	return critere_parinverse($idb, $boucles, $crit);
727
+    return critere_parinverse($idb, $boucles, $crit);
728 728
 }
729 729
 
730 730
 /**
@@ -746,93 +746,93 @@  discard block
 block discarded – undo
746 746
  * @param Critere $crit Paramètres du critère dans cette boucle
747 747
  */
748 748
 function critere_parinverse($idb, &$boucles, $crit) {
749
-	$boucle = &$boucles[$idb];
750
-
751
-	$sens = $collecte = '';
752
-	if ($crit->not) {
753
-		$sens = " . ' DESC'";
754
-	}
755
-	if (isset($boucle->modificateur['collate'])) {
756
-		$collecte = ' . ' . $boucle->modificateur['collate'];
757
-	}
758
-
759
-	// Pour chaque paramètre du critère
760
-	foreach ($crit->param as $tri) {
761
-		$order = $fct = '';
762
-		// tris specifiés dynamiquement {par #ENV{tri}}
763
-		if ($tri[0]->type != 'texte') {
764
-			// calculer le order dynamique qui verifie les champs
765
-			$order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens);
766
-			// ajouter 'hasard' comme possibilité de tri dynamique
767
-			calculer_critere_par_hasard($idb, $boucles, $crit);
768
-		}
769
-		// tris textuels {par titre}
770
-		else {
771
-			$par = array_shift($tri);
772
-			$par = $par->texte;
773
-
774
-			// tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre}
775
-			if (preg_match(',^(\w+)[\s]+(.*)$,', $par, $m)) {
776
-				$expression = trim($m[1]);
777
-				$champ = trim($m[2]);
778
-				if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) {
779
-					$order = $f($idb, $boucles, $crit, $tri, $champ);
780
-				} else {
781
-					return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
782
-				}
783
-
784
-			// tris de la forme {par champ} ou {par FONCTION(champ)}
785
-			} elseif ($boucle->type_requete == 'DATA' or preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', $par, $match)) {
786
-				// {par FONCTION(champ)}
787
-				if (isset($match) and count($match) > 2) {
788
-					$par = substr($match[2], 1, -1);
789
-					$fct = $match[1];
790
-				}
791
-				// quelques cas spécifiques {par hasard}, {par date}
792
-				if ($par == 'hasard') {
793
-					$order = calculer_critere_par_hasard($idb, $boucles, $crit);
794
-				} elseif ($par == 'date' and !empty($boucle->show['date'])) {
795
-					$order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'";
796
-				} else {
797
-					// cas général {par champ}, {par table.champ}, ...
798
-					$order = calculer_critere_par_champ($idb, $boucles, $crit, $par);
799
-				}
800
-			}
801
-
802
-			// on ne sait pas traiter…
803
-			else {
804
-				return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
805
-			}
806
-
807
-			// En cas d'erreur de squelette retournée par une fonction
808
-			if (is_array($order)) {
809
-				return $order;
810
-			}
811
-		}
812
-
813
-		if (preg_match('/^\'([^"]*)\'$/', $order, $m)) {
814
-			$t = $m[1];
815
-			if (strpos($t, '.') and !in_array($t, $boucle->select)) {
816
-				$boucle->select[] = $t;
817
-			}
818
-		} else {
819
-			$sens = '';
820
-		}
821
-
822
-		if ($fct) {
823
-			if (preg_match("/^\s*'(.*)'\s*$/", $order, $r)) {
824
-				$order = "'$fct(" . $r[1] . ")'";
825
-			} else {
826
-				$order = "'$fct(' . $order . ')'";
827
-			}
828
-		}
829
-		$t = $order . $collecte . $sens;
830
-		if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
831
-			$t = $r[1] . $r[2];
832
-		}
833
-
834
-		$boucle->order[] = $t;
835
-	}
749
+    $boucle = &$boucles[$idb];
750
+
751
+    $sens = $collecte = '';
752
+    if ($crit->not) {
753
+        $sens = " . ' DESC'";
754
+    }
755
+    if (isset($boucle->modificateur['collate'])) {
756
+        $collecte = ' . ' . $boucle->modificateur['collate'];
757
+    }
758
+
759
+    // Pour chaque paramètre du critère
760
+    foreach ($crit->param as $tri) {
761
+        $order = $fct = '';
762
+        // tris specifiés dynamiquement {par #ENV{tri}}
763
+        if ($tri[0]->type != 'texte') {
764
+            // calculer le order dynamique qui verifie les champs
765
+            $order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens);
766
+            // ajouter 'hasard' comme possibilité de tri dynamique
767
+            calculer_critere_par_hasard($idb, $boucles, $crit);
768
+        }
769
+        // tris textuels {par titre}
770
+        else {
771
+            $par = array_shift($tri);
772
+            $par = $par->texte;
773
+
774
+            // tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre}
775
+            if (preg_match(',^(\w+)[\s]+(.*)$,', $par, $m)) {
776
+                $expression = trim($m[1]);
777
+                $champ = trim($m[2]);
778
+                if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) {
779
+                    $order = $f($idb, $boucles, $crit, $tri, $champ);
780
+                } else {
781
+                    return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
782
+                }
783
+
784
+            // tris de la forme {par champ} ou {par FONCTION(champ)}
785
+            } elseif ($boucle->type_requete == 'DATA' or preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', $par, $match)) {
786
+                // {par FONCTION(champ)}
787
+                if (isset($match) and count($match) > 2) {
788
+                    $par = substr($match[2], 1, -1);
789
+                    $fct = $match[1];
790
+                }
791
+                // quelques cas spécifiques {par hasard}, {par date}
792
+                if ($par == 'hasard') {
793
+                    $order = calculer_critere_par_hasard($idb, $boucles, $crit);
794
+                } elseif ($par == 'date' and !empty($boucle->show['date'])) {
795
+                    $order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'";
796
+                } else {
797
+                    // cas général {par champ}, {par table.champ}, ...
798
+                    $order = calculer_critere_par_champ($idb, $boucles, $crit, $par);
799
+                }
800
+            }
801
+
802
+            // on ne sait pas traiter…
803
+            else {
804
+                return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
805
+            }
806
+
807
+            // En cas d'erreur de squelette retournée par une fonction
808
+            if (is_array($order)) {
809
+                return $order;
810
+            }
811
+        }
812
+
813
+        if (preg_match('/^\'([^"]*)\'$/', $order, $m)) {
814
+            $t = $m[1];
815
+            if (strpos($t, '.') and !in_array($t, $boucle->select)) {
816
+                $boucle->select[] = $t;
817
+            }
818
+        } else {
819
+            $sens = '';
820
+        }
821
+
822
+        if ($fct) {
823
+            if (preg_match("/^\s*'(.*)'\s*$/", $order, $r)) {
824
+                $order = "'$fct(" . $r[1] . ")'";
825
+            } else {
826
+                $order = "'$fct(' . $order . ')'";
827
+            }
828
+        }
829
+        $t = $order . $collecte . $sens;
830
+        if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
831
+            $t = $r[1] . $r[2];
832
+        }
833
+
834
+        $boucle->order[] = $t;
835
+    }
836 836
 }
837 837
 
838 838
 /**
@@ -846,13 +846,13 @@  discard block
 block discarded – undo
846 846
  * @return string Clause pour le Order by
847 847
  */
848 848
 function calculer_critere_par_hasard($idb, &$boucles, $crit) {
849
-	$boucle = &$boucles[$idb];
850
-	// Si ce n'est fait, ajouter un champ 'hasard' dans le select
851
-	$parha = 'rand() AS hasard';
852
-	if (!in_array($parha, $boucle->select)) {
853
-		$boucle->select[] = $parha;
854
-	}
855
-	return "'hasard'";
849
+    $boucle = &$boucles[$idb];
850
+    // Si ce n'est fait, ajouter un champ 'hasard' dans le select
851
+    $parha = 'rand() AS hasard';
852
+    if (!in_array($parha, $boucle->select)) {
853
+        $boucle->select[] = $parha;
854
+    }
855
+    return "'hasard'";
856 856
 }
857 857
 
858 858
 /**
@@ -876,24 +876,24 @@  discard block
 block discarded – undo
876 876
  * @return string|array Clause pour le Order by (array si erreur)
877 877
  */
878 878
 function calculer_critere_par_expression_num($idb, &$boucles, $crit, $tri, $champ) {
879
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
880
-	if (is_array($_champ)) {
881
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]];
882
-	}
883
-	$boucle = &$boucles[$idb];
884
-	$texte = '0+' . $_champ;
885
-	$suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
886
-	if ($suite !== "''") {
887
-		$texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
888
-	}
889
-	$asnum = 'num' . ($boucle->order ? count($boucle->order) : '');
890
-	$boucle->select[] = $texte . " AS $asnum";
891
-
892
-	$orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ);
893
-	$orderassinum = trim($orderassinum, "'");
894
-
895
-	$order = "'$orderassinum, $asnum'";
896
-	return $order;
879
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
880
+    if (is_array($_champ)) {
881
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]];
882
+    }
883
+    $boucle = &$boucles[$idb];
884
+    $texte = '0+' . $_champ;
885
+    $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
886
+    if ($suite !== "''") {
887
+        $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
888
+    }
889
+    $asnum = 'num' . ($boucle->order ? count($boucle->order) : '');
890
+    $boucle->select[] = $texte . " AS $asnum";
891
+
892
+    $orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ);
893
+    $orderassinum = trim($orderassinum, "'");
894
+
895
+    $order = "'$orderassinum, $asnum'";
896
+    return $order;
897 897
 }
898 898
 
899 899
 /**
@@ -914,35 +914,35 @@  discard block
 block discarded – undo
914 914
  * @return string|array Clause pour le Order by (array si erreur)
915 915
  */
916 916
 function calculer_critere_par_expression_sinum($idb, &$boucles, $crit, $tri, $champ) {
917
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
918
-	if (is_array($_champ)) {
919
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]];
920
-	}
921
-	$boucle = &$boucles[$idb];
922
-	$texte = '0+' . $_champ;
923
-	$suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
924
-	if ($suite !== "''") {
925
-		$texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
926
-	}
927
-
928
-	$as = false;
929
-	$select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS ";
930
-	foreach ($boucle->select as $s) {
931
-		if (strpos($s, $select) === 0) {
932
-			$as = trim(substr($s, strlen($select)));
933
-			if (!preg_match(',\W,', $as)) {
934
-				break;
935
-			}
936
-			$as = false;
937
-		}
938
-	}
939
-
940
-	if (!$as) {
941
-		$as = 'sinum' . ($boucle->order ? count($boucle->order) : '');
942
-		$boucle->select[] = $select . $as;
943
-	}
944
-	$order = "'$as'";
945
-	return $order;
917
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
918
+    if (is_array($_champ)) {
919
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]];
920
+    }
921
+    $boucle = &$boucles[$idb];
922
+    $texte = '0+' . $_champ;
923
+    $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
924
+    if ($suite !== "''") {
925
+        $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
926
+    }
927
+
928
+    $as = false;
929
+    $select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS ";
930
+    foreach ($boucle->select as $s) {
931
+        if (strpos($s, $select) === 0) {
932
+            $as = trim(substr($s, strlen($select)));
933
+            if (!preg_match(',\W,', $as)) {
934
+                break;
935
+            }
936
+            $as = false;
937
+        }
938
+    }
939
+
940
+    if (!$as) {
941
+        $as = 'sinum' . ($boucle->order ? count($boucle->order) : '');
942
+        $boucle->select[] = $select . $as;
943
+    }
944
+    $order = "'$as'";
945
+    return $order;
946 946
 }
947 947
 
948 948
 
@@ -962,14 +962,14 @@  discard block
 block discarded – undo
962 962
  * @return string|array Clause pour le Order by (array si erreur)
963 963
  */
964 964
 function calculer_critere_par_expression_multi($idb, &$boucles, $crit, $tri, $champ) {
965
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
966
-	if (is_array($_champ)) {
967
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]];
968
-	}
969
-	$boucle = &$boucles[$idb];
970
-	$boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\"";
971
-	$order = "'multi'";
972
-	return $order;
965
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
966
+    if (is_array($_champ)) {
967
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]];
968
+    }
969
+    $boucle = &$boucles[$idb];
970
+    $boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\"";
971
+    $order = "'multi'";
972
+    return $order;
973 973
 }
974 974
 
975 975
 /**
@@ -988,56 +988,56 @@  discard block
 block discarded – undo
988 988
  * @return array|string
989 989
  */
990 990
 function calculer_critere_par_champ($idb, &$boucles, $crit, $par, $raw = false) {
991
-	$boucle = &$boucles[$idb];
992
-	$desc = $boucle->show;
993
-
994
-	// le champ existe dans la table, pas de souci (le plus commun)
995
-	if (isset($desc['field'][$par])) {
996
-		$par = $boucle->id_table . '.' . $par;
997
-	}
998
-	// le champ est peut être une jointure
999
-	else {
1000
-		$table = $table_alias = false; // toutes les tables de jointure possibles
1001
-		$champ = $par;
1002
-
1003
-		// le champ demandé est une exception de jointure {par titre_mot}
1004
-		if (isset($GLOBALS['exceptions_des_jointures'][$par])) {
1005
-			[$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par];
1006
-		} // la table de jointure est explicitement indiquée {par truc.muche}
1007
-		elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) {
1008
-			[, $table, $champ] = $r;
1009
-			$table_alias = $table; // c'est peut-être un alias de table {par L1.titre}
1010
-			$table = table_objet_sql($table);
1011
-		}
1012
-
1013
-		// Si on connait la table d'arrivée, on la demande donc explicitement
1014
-		// Sinon on cherche le champ dans les tables possibles de jointures
1015
-		// Si la table est déjà dans le from, on la réutilise.
1016
-		if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) {
1017
-			$par = $infos['alias'] . '.' . $champ;
1018
-		} elseif (
1019
-			$boucle->jointures_explicites
1020
-			and $alias = trouver_jointure_champ($champ, $boucle, explode(' ', $boucle->jointures_explicites), false, $table)
1021
-		) {
1022
-			$par = $alias . '.' . $champ;
1023
-		} elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) {
1024
-			$par = $alias . '.' . $champ;
1025
-		// en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même)
1026
-		} elseif (
1027
-			$table_alias
1028
-			and isset($boucle->from[$table_alias])
1029
-			and $infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias])
1030
-		) {
1031
-			$par = $infos['alias'] . '.' . $champ;
1032
-		} elseif ($table) {
1033
-			// On avait table + champ, mais on ne les a pas trouvés
1034
-			return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
1035
-		} else {
1036
-			// Sinon tant pis, ca doit etre un champ synthetise (cf points)
1037
-		}
1038
-	}
1039
-
1040
-	return $raw ? $par : "'$par'";
991
+    $boucle = &$boucles[$idb];
992
+    $desc = $boucle->show;
993
+
994
+    // le champ existe dans la table, pas de souci (le plus commun)
995
+    if (isset($desc['field'][$par])) {
996
+        $par = $boucle->id_table . '.' . $par;
997
+    }
998
+    // le champ est peut être une jointure
999
+    else {
1000
+        $table = $table_alias = false; // toutes les tables de jointure possibles
1001
+        $champ = $par;
1002
+
1003
+        // le champ demandé est une exception de jointure {par titre_mot}
1004
+        if (isset($GLOBALS['exceptions_des_jointures'][$par])) {
1005
+            [$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par];
1006
+        } // la table de jointure est explicitement indiquée {par truc.muche}
1007
+        elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) {
1008
+            [, $table, $champ] = $r;
1009
+            $table_alias = $table; // c'est peut-être un alias de table {par L1.titre}
1010
+            $table = table_objet_sql($table);
1011
+        }
1012
+
1013
+        // Si on connait la table d'arrivée, on la demande donc explicitement
1014
+        // Sinon on cherche le champ dans les tables possibles de jointures
1015
+        // Si la table est déjà dans le from, on la réutilise.
1016
+        if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) {
1017
+            $par = $infos['alias'] . '.' . $champ;
1018
+        } elseif (
1019
+            $boucle->jointures_explicites
1020
+            and $alias = trouver_jointure_champ($champ, $boucle, explode(' ', $boucle->jointures_explicites), false, $table)
1021
+        ) {
1022
+            $par = $alias . '.' . $champ;
1023
+        } elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) {
1024
+            $par = $alias . '.' . $champ;
1025
+        // en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même)
1026
+        } elseif (
1027
+            $table_alias
1028
+            and isset($boucle->from[$table_alias])
1029
+            and $infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias])
1030
+        ) {
1031
+            $par = $infos['alias'] . '.' . $champ;
1032
+        } elseif ($table) {
1033
+            // On avait table + champ, mais on ne les a pas trouvés
1034
+            return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
1035
+        } else {
1036
+            // Sinon tant pis, ca doit etre un champ synthetise (cf points)
1037
+        }
1038
+    }
1039
+
1040
+    return $raw ? $par : "'$par'";
1041 1041
 }
1042 1042
 
1043 1043
 /**
@@ -1051,11 +1051,11 @@  discard block
 block discarded – undo
1051 1051
  * @return string Champ pour le compilateur si trouvé, tel que "'alias.champ'", sinon vide.
1052 1052
  */
1053 1053
 function critere_par_joint($table, $champ, &$boucle) {
1054
-	$t = array_search($table, $boucle->from);
1055
-	if (!$t) {
1056
-		$t = trouver_jointure_champ($champ, $boucle);
1057
-	}
1058
-	return !$t ? '' : ("'" . $t . '.' . $champ . "'");
1054
+    $t = array_search($table, $boucle->from);
1055
+    if (!$t) {
1056
+        $t = trouver_jointure_champ($champ, $boucle);
1057
+    }
1058
+    return !$t ? '' : ("'" . $t . '.' . $champ . "'");
1059 1059
 }
1060 1060
 
1061 1061
 /**
@@ -1080,33 +1080,33 @@  discard block
 block discarded – undo
1080 1080
  */
1081 1081
 function critere_inverse_dist($idb, &$boucles, $crit) {
1082 1082
 
1083
-	$boucle = &$boucles[$idb];
1084
-	// Classement par ordre inverse
1085
-	if ($crit->not) {
1086
-		critere_parinverse($idb, $boucles, $crit);
1087
-	} else {
1088
-		$order = "' DESC'";
1089
-		// Classement par ordre inverse fonction eventuelle de #ENV{...}
1090
-		if (isset($crit->param[0])) {
1091
-			$critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
1092
-			$order = "(($critere)?' DESC':'')";
1093
-		}
1094
-
1095
-		$n = is_countable($boucle->order) ? count($boucle->order) : 0;
1096
-		if (!$n) {
1097
-			if (isset($boucle->default_order[0])) {
1098
-				$boucle->default_order[0] .= ' . " DESC"';
1099
-			} else {
1100
-				$boucle->default_order[] = ' DESC';
1101
-			}
1102
-		} else {
1103
-			$t = $boucle->order[$n - 1] . " . $order";
1104
-			if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
1105
-				$t = $r[1] . $r[2];
1106
-			}
1107
-			$boucle->order[$n - 1] = $t;
1108
-		}
1109
-	}
1083
+    $boucle = &$boucles[$idb];
1084
+    // Classement par ordre inverse
1085
+    if ($crit->not) {
1086
+        critere_parinverse($idb, $boucles, $crit);
1087
+    } else {
1088
+        $order = "' DESC'";
1089
+        // Classement par ordre inverse fonction eventuelle de #ENV{...}
1090
+        if (isset($crit->param[0])) {
1091
+            $critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
1092
+            $order = "(($critere)?' DESC':'')";
1093
+        }
1094
+
1095
+        $n = is_countable($boucle->order) ? count($boucle->order) : 0;
1096
+        if (!$n) {
1097
+            if (isset($boucle->default_order[0])) {
1098
+                $boucle->default_order[0] .= ' . " DESC"';
1099
+            } else {
1100
+                $boucle->default_order[] = ' DESC';
1101
+            }
1102
+        } else {
1103
+            $t = $boucle->order[$n - 1] . " . $order";
1104
+            if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
1105
+                $t = $r[1] . $r[2];
1106
+            }
1107
+            $boucle->order[$n - 1] = $t;
1108
+        }
1109
+    }
1110 1110
 }
1111 1111
 
1112 1112
 /**
@@ -1118,139 +1118,139 @@  discard block
 block discarded – undo
1118 1118
  * @return void|array
1119 1119
  */
1120 1120
 function critere_par_ordre_liste_dist($idb, &$boucles, $crit) {
1121
-	$boucle = &$boucles[$idb];
1121
+    $boucle = &$boucles[$idb];
1122 1122
 
1123
-	$sens = $collecte = '';
1124
-	if ($crit->not) {
1125
-		$sens = " . ' DESC'";
1126
-	}
1123
+    $sens = $collecte = '';
1124
+    if ($crit->not) {
1125
+        $sens = " . ' DESC'";
1126
+    }
1127 1127
 
1128
-	$crit2 = clone $crit;
1129
-	$crit2->not = false;
1130
-	$crit2->param = [reset($crit->param)];
1131
-	$res = critere_parinverse($idb, $boucles, $crit2);
1128
+    $crit2 = clone $crit;
1129
+    $crit2->not = false;
1130
+    $crit2->param = [reset($crit->param)];
1131
+    $res = critere_parinverse($idb, $boucles, $crit2);
1132 1132
 
1133
-	// erreur ?
1134
-	if (is_array($res)) {
1135
-		return $res;
1136
-	}
1133
+    // erreur ?
1134
+    if (is_array($res)) {
1135
+        return $res;
1136
+    }
1137 1137
 
1138
-	$_order = array_pop($boucle->order);
1138
+    $_order = array_pop($boucle->order);
1139 1139
 
1140
-	$_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent);
1140
+    $_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent);
1141 1141
 
1142
-	$order = "'-FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste(array_reverse($_liste),'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens";
1143
-	$boucle->order[] = $order;
1142
+    $order = "'-FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste(array_reverse($_liste),'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens";
1143
+    $boucle->order[] = $order;
1144 1144
 }
1145 1145
 
1146 1146
 
1147 1147
 function critere_agenda_dist($idb, &$boucles, $crit) {
1148
-	$params = $crit->param;
1149
-
1150
-	if ((is_countable($params) ? count($params) : 0) < 1) {
1151
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1152
-	}
1153
-
1154
-	$boucle = &$boucles[$idb];
1155
-	$parent = $boucle->id_parent;
1156
-	$fields = $boucle->show['field'];
1157
-
1158
-	$date = array_shift($params);
1159
-	$type = array_shift($params);
1160
-
1161
-	// la valeur $type doit etre connue a la compilation
1162
-	// donc etre forcement reduite a un litteral unique dans le source
1163
-	$type = is_object($type[0]) ? $type[0]->texte : null;
1164
-
1165
-	// La valeur date doit designer un champ de la table SQL.
1166
-	// Si c'est un litteral unique dans le source, verifier a la compil,
1167
-	// sinon synthetiser le test de verif pour execution ulterieure
1168
-	// On prendra arbitrairement le premier champ si test negatif.
1169
-	if (((is_countable($date) ? count($date) : 0) == 1) and ($date[0]->type == 'texte')) {
1170
-		$date = $date[0]->texte;
1171
-		if (!isset($fields[$date])) {
1172
-			return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]];
1173
-		}
1174
-	} else {
1175
-		$a = calculer_liste($date, $idb, $boucles, $parent);
1176
-		$noms = array_keys($fields);
1177
-		$defaut = $noms[0];
1178
-		$noms = join(' ', $noms);
1179
-		# bien laisser 2 espaces avant $nom pour que strpos<>0
1180
-		$cond = "(\$a=strval($a))AND\nstrpos(\"  $noms \",\" \$a \")";
1181
-		$date = "'.(($cond)\n?\$a:\"$defaut\").'";
1182
-	}
1183
-	$annee = $params ? array_shift($params) : '';
1184
-	$annee = "\n" . 'sprintf("%04d", ($x = ' .
1185
-		calculer_liste($annee, $idb, $boucles, $parent) .
1186
-		') ? $x : date("Y"))';
1187
-
1188
-	$mois = $params ? array_shift($params) : '';
1189
-	$mois = "\n" . 'sprintf("%02d", ($x = ' .
1190
-		calculer_liste($mois, $idb, $boucles, $parent) .
1191
-		') ? $x : date("m"))';
1192
-
1193
-	$jour = $params ? array_shift($params) : '';
1194
-	$jour = "\n" . 'sprintf("%02d", ($x = ' .
1195
-		calculer_liste($jour, $idb, $boucles, $parent) .
1196
-		') ? $x : date("d"))';
1197
-
1198
-	$annee2 = $params ? array_shift($params) : '';
1199
-	$annee2 = "\n" . 'sprintf("%04d", ($x = ' .
1200
-		calculer_liste($annee2, $idb, $boucles, $parent) .
1201
-		') ? $x : date("Y"))';
1202
-
1203
-	$mois2 = $params ? array_shift($params) : '';
1204
-	$mois2 = "\n" . 'sprintf("%02d", ($x = ' .
1205
-		calculer_liste($mois2, $idb, $boucles, $parent) .
1206
-		') ? $x : date("m"))';
1207
-
1208
-	$jour2 = $params ? array_shift($params) : '';
1209
-	$jour2 = "\n" . 'sprintf("%02d", ($x = ' .
1210
-		calculer_liste($jour2, $idb, $boucles, $parent) .
1211
-		') ? $x : date("d"))';
1212
-
1213
-	$date = $boucle->id_table . ".$date";
1214
-
1215
-	$quote_end = ",'" . $boucle->sql_serveur . "','text'";
1216
-	if ($type == 'jour') {
1217
-		$boucle->where[] = [
1218
-			"'='",
1219
-			"'DATE_FORMAT($date, \'%Y%m%d\')'",
1220
-			("sql_quote($annee . $mois . $jour$quote_end)")
1221
-		];
1222
-	} elseif ($type == 'mois') {
1223
-		$boucle->where[] = [
1224
-			"'='",
1225
-			"'DATE_FORMAT($date, \'%Y%m\')'",
1226
-			("sql_quote($annee . $mois$quote_end)")
1227
-		];
1228
-	} elseif ($type == 'semaine') {
1229
-		$boucle->where[] = [
1230
-			"'AND'",
1231
-			[
1232
-				"'>='",
1233
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1234
-				("date_debut_semaine($annee, $mois, $jour)")
1235
-			],
1236
-			[
1237
-				"'<='",
1238
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1239
-				("date_fin_semaine($annee, $mois, $jour)")
1240
-			]
1241
-		];
1242
-	} elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) {
1243
-		$boucle->where[] = [
1244
-			"'AND'",
1245
-			[
1246
-				"'>='",
1247
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1248
-				("sql_quote($annee . $mois . $jour$quote_end)")
1249
-			],
1250
-			["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")]
1251
-		];
1252
-	}
1253
-	// sinon on prend tout
1148
+    $params = $crit->param;
1149
+
1150
+    if ((is_countable($params) ? count($params) : 0) < 1) {
1151
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1152
+    }
1153
+
1154
+    $boucle = &$boucles[$idb];
1155
+    $parent = $boucle->id_parent;
1156
+    $fields = $boucle->show['field'];
1157
+
1158
+    $date = array_shift($params);
1159
+    $type = array_shift($params);
1160
+
1161
+    // la valeur $type doit etre connue a la compilation
1162
+    // donc etre forcement reduite a un litteral unique dans le source
1163
+    $type = is_object($type[0]) ? $type[0]->texte : null;
1164
+
1165
+    // La valeur date doit designer un champ de la table SQL.
1166
+    // Si c'est un litteral unique dans le source, verifier a la compil,
1167
+    // sinon synthetiser le test de verif pour execution ulterieure
1168
+    // On prendra arbitrairement le premier champ si test negatif.
1169
+    if (((is_countable($date) ? count($date) : 0) == 1) and ($date[0]->type == 'texte')) {
1170
+        $date = $date[0]->texte;
1171
+        if (!isset($fields[$date])) {
1172
+            return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]];
1173
+        }
1174
+    } else {
1175
+        $a = calculer_liste($date, $idb, $boucles, $parent);
1176
+        $noms = array_keys($fields);
1177
+        $defaut = $noms[0];
1178
+        $noms = join(' ', $noms);
1179
+        # bien laisser 2 espaces avant $nom pour que strpos<>0
1180
+        $cond = "(\$a=strval($a))AND\nstrpos(\"  $noms \",\" \$a \")";
1181
+        $date = "'.(($cond)\n?\$a:\"$defaut\").'";
1182
+    }
1183
+    $annee = $params ? array_shift($params) : '';
1184
+    $annee = "\n" . 'sprintf("%04d", ($x = ' .
1185
+        calculer_liste($annee, $idb, $boucles, $parent) .
1186
+        ') ? $x : date("Y"))';
1187
+
1188
+    $mois = $params ? array_shift($params) : '';
1189
+    $mois = "\n" . 'sprintf("%02d", ($x = ' .
1190
+        calculer_liste($mois, $idb, $boucles, $parent) .
1191
+        ') ? $x : date("m"))';
1192
+
1193
+    $jour = $params ? array_shift($params) : '';
1194
+    $jour = "\n" . 'sprintf("%02d", ($x = ' .
1195
+        calculer_liste($jour, $idb, $boucles, $parent) .
1196
+        ') ? $x : date("d"))';
1197
+
1198
+    $annee2 = $params ? array_shift($params) : '';
1199
+    $annee2 = "\n" . 'sprintf("%04d", ($x = ' .
1200
+        calculer_liste($annee2, $idb, $boucles, $parent) .
1201
+        ') ? $x : date("Y"))';
1202
+
1203
+    $mois2 = $params ? array_shift($params) : '';
1204
+    $mois2 = "\n" . 'sprintf("%02d", ($x = ' .
1205
+        calculer_liste($mois2, $idb, $boucles, $parent) .
1206
+        ') ? $x : date("m"))';
1207
+
1208
+    $jour2 = $params ? array_shift($params) : '';
1209
+    $jour2 = "\n" . 'sprintf("%02d", ($x = ' .
1210
+        calculer_liste($jour2, $idb, $boucles, $parent) .
1211
+        ') ? $x : date("d"))';
1212
+
1213
+    $date = $boucle->id_table . ".$date";
1214
+
1215
+    $quote_end = ",'" . $boucle->sql_serveur . "','text'";
1216
+    if ($type == 'jour') {
1217
+        $boucle->where[] = [
1218
+            "'='",
1219
+            "'DATE_FORMAT($date, \'%Y%m%d\')'",
1220
+            ("sql_quote($annee . $mois . $jour$quote_end)")
1221
+        ];
1222
+    } elseif ($type == 'mois') {
1223
+        $boucle->where[] = [
1224
+            "'='",
1225
+            "'DATE_FORMAT($date, \'%Y%m\')'",
1226
+            ("sql_quote($annee . $mois$quote_end)")
1227
+        ];
1228
+    } elseif ($type == 'semaine') {
1229
+        $boucle->where[] = [
1230
+            "'AND'",
1231
+            [
1232
+                "'>='",
1233
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1234
+                ("date_debut_semaine($annee, $mois, $jour)")
1235
+            ],
1236
+            [
1237
+                "'<='",
1238
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1239
+                ("date_fin_semaine($annee, $mois, $jour)")
1240
+            ]
1241
+        ];
1242
+    } elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) {
1243
+        $boucle->where[] = [
1244
+            "'AND'",
1245
+            [
1246
+                "'>='",
1247
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1248
+                ("sql_quote($annee . $mois . $jour$quote_end)")
1249
+            ],
1250
+            ["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")]
1251
+        ];
1252
+    }
1253
+    // sinon on prend tout
1254 1254
 }
1255 1255
 
1256 1256
 
@@ -1275,33 +1275,33 @@  discard block
 block discarded – undo
1275 1275
  * @return void
1276 1276
  **/
1277 1277
 function calculer_critere_parties($idb, &$boucles, $crit) {
1278
-	$boucle = &$boucles[$idb];
1279
-	$a1 = $crit->param[0];
1280
-	$a2 = $crit->param[1];
1281
-	$op = $crit->op;
1282
-
1283
-	[$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1);
1284
-	[$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2);
1285
-
1286
-	if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) {
1287
-		$boucle->limit = $a11 . ',' . $a21;
1288
-	} else {
1289
-		// 3 dans {1/3}, {2,3} ou {1,n-3}
1290
-		$boucle->total_parties = ($a21 != 'n') ? $a21 : $a22;
1291
-		// 2 dans {2/3}, {2,5}, {n-2,1}
1292
-		$partie = ($a11 != 'n') ? $a11 : $a12;
1293
-		$mode = (($op == '/') ? '/' :
1294
-			(($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+'));
1295
-		// cas simple {0,#ENV{truc}} compilons le en LIMIT :
1296
-		if ($a11 !== 'n' and $a21 !== 'n' and $mode == '++' and $op == ',') {
1297
-			$boucle->limit =
1298
-				(is_numeric($a11) ? "'$a11'" : $a11)
1299
-				. ".','."
1300
-				. (is_numeric($a21) ? "'$a21'" : $a21);
1301
-		} else {
1302
-			calculer_parties($boucles, $idb, $partie, $mode);
1303
-		}
1304
-	}
1278
+    $boucle = &$boucles[$idb];
1279
+    $a1 = $crit->param[0];
1280
+    $a2 = $crit->param[1];
1281
+    $op = $crit->op;
1282
+
1283
+    [$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1);
1284
+    [$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2);
1285
+
1286
+    if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) {
1287
+        $boucle->limit = $a11 . ',' . $a21;
1288
+    } else {
1289
+        // 3 dans {1/3}, {2,3} ou {1,n-3}
1290
+        $boucle->total_parties = ($a21 != 'n') ? $a21 : $a22;
1291
+        // 2 dans {2/3}, {2,5}, {n-2,1}
1292
+        $partie = ($a11 != 'n') ? $a11 : $a12;
1293
+        $mode = (($op == '/') ? '/' :
1294
+            (($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+'));
1295
+        // cas simple {0,#ENV{truc}} compilons le en LIMIT :
1296
+        if ($a11 !== 'n' and $a21 !== 'n' and $mode == '++' and $op == ',') {
1297
+            $boucle->limit =
1298
+                (is_numeric($a11) ? "'$a11'" : $a11)
1299
+                . ".','."
1300
+                . (is_numeric($a21) ? "'$a21'" : $a21);
1301
+        } else {
1302
+            calculer_parties($boucles, $idb, $partie, $mode);
1303
+        }
1304
+    }
1305 1305
 }
1306 1306
 
1307 1307
 /**
@@ -1329,63 +1329,63 @@  discard block
 block discarded – undo
1329 1329
  * @return void
1330 1330
  **/
1331 1331
 function calculer_parties(&$boucles, $id_boucle, $debut, $mode) {
1332
-	$total_parties = $boucles[$id_boucle]->total_parties;
1333
-
1334
-	preg_match(',([+-/p])([+-/])?,', $mode, $regs);
1335
-	[, $op1, $op2] = array_pad($regs, 3, null);
1336
-	$nombre_boucle = "\$Numrows['$id_boucle']['total']";
1337
-	// {1/3}
1338
-	if ($op1 == '/') {
1339
-		$pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)";
1340
-		$totpos = is_numeric($total_parties) ? ($total_parties) :
1341
-			"($total_parties ? $total_parties : 1)";
1342
-		$fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1";
1343
-		$debut = !$pmoins1 ? 0 : "ceil(($nombre_boucle * $pmoins1)/$totpos);";
1344
-	} else {
1345
-		// cas {n-1,x}
1346
-		if ($op1 == '-') {
1347
-			$debut = "$nombre_boucle - $debut;";
1348
-		}
1349
-
1350
-		// cas {x,n-1}
1351
-		if ($op2 == '-') {
1352
-			$fin = '$debut_boucle + ' . $nombre_boucle . ' - '
1353
-				. (is_numeric($total_parties) ? ($total_parties + 1) :
1354
-					($total_parties . ' - 1'));
1355
-		} else {
1356
-			// {x,1} ou {pagination}
1357
-			$fin = '$debut_boucle'
1358
-				. (is_numeric($total_parties) ?
1359
-					(($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) :
1360
-					('+' . $total_parties . ' - 1'));
1361
-		}
1362
-
1363
-		// {pagination}, gerer le debut_xx=-1 pour tout voir
1364
-		if ($op1 == 'p') {
1365
-			$debut .= ";\n	\$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))";
1366
-			$debut .= ";\n	\$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))";
1367
-			$fin = "(\$tout ? $nombre_boucle : $fin)";
1368
-		}
1369
-	}
1370
-
1371
-	// Notes :
1372
-	// $debut_boucle et $fin_boucle sont les indices SQL du premier
1373
-	// et du dernier demandes dans la boucle : 0 pour le premier,
1374
-	// n-1 pour le dernier ; donc total_boucle = 1 + debut - fin
1375
-	// Utiliser min pour rabattre $fin_boucle sur total_boucle.
1376
-
1377
-	$boucles[$id_boucle]->mode_partie = "\n\t"
1378
-		. '$debut_boucle = ' . $debut . ";\n	"
1379
-		. "\$debut_boucle = intval(\$debut_boucle);\n	"
1380
-		. '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n	"
1381
-		. '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n	"
1382
-		. '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);'
1383
-		. "\n\tif (\$debut_boucle>0"
1384
-		. " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']"
1385
-		. " AND \$iter->seek(\$debut_boucle,'continue'))"
1386
-		. "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t";
1387
-
1388
-	$boucles[$id_boucle]->partie = "
1332
+    $total_parties = $boucles[$id_boucle]->total_parties;
1333
+
1334
+    preg_match(',([+-/p])([+-/])?,', $mode, $regs);
1335
+    [, $op1, $op2] = array_pad($regs, 3, null);
1336
+    $nombre_boucle = "\$Numrows['$id_boucle']['total']";
1337
+    // {1/3}
1338
+    if ($op1 == '/') {
1339
+        $pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)";
1340
+        $totpos = is_numeric($total_parties) ? ($total_parties) :
1341
+            "($total_parties ? $total_parties : 1)";
1342
+        $fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1";
1343
+        $debut = !$pmoins1 ? 0 : "ceil(($nombre_boucle * $pmoins1)/$totpos);";
1344
+    } else {
1345
+        // cas {n-1,x}
1346
+        if ($op1 == '-') {
1347
+            $debut = "$nombre_boucle - $debut;";
1348
+        }
1349
+
1350
+        // cas {x,n-1}
1351
+        if ($op2 == '-') {
1352
+            $fin = '$debut_boucle + ' . $nombre_boucle . ' - '
1353
+                . (is_numeric($total_parties) ? ($total_parties + 1) :
1354
+                    ($total_parties . ' - 1'));
1355
+        } else {
1356
+            // {x,1} ou {pagination}
1357
+            $fin = '$debut_boucle'
1358
+                . (is_numeric($total_parties) ?
1359
+                    (($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) :
1360
+                    ('+' . $total_parties . ' - 1'));
1361
+        }
1362
+
1363
+        // {pagination}, gerer le debut_xx=-1 pour tout voir
1364
+        if ($op1 == 'p') {
1365
+            $debut .= ";\n	\$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))";
1366
+            $debut .= ";\n	\$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))";
1367
+            $fin = "(\$tout ? $nombre_boucle : $fin)";
1368
+        }
1369
+    }
1370
+
1371
+    // Notes :
1372
+    // $debut_boucle et $fin_boucle sont les indices SQL du premier
1373
+    // et du dernier demandes dans la boucle : 0 pour le premier,
1374
+    // n-1 pour le dernier ; donc total_boucle = 1 + debut - fin
1375
+    // Utiliser min pour rabattre $fin_boucle sur total_boucle.
1376
+
1377
+    $boucles[$id_boucle]->mode_partie = "\n\t"
1378
+        . '$debut_boucle = ' . $debut . ";\n	"
1379
+        . "\$debut_boucle = intval(\$debut_boucle);\n	"
1380
+        . '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n	"
1381
+        . '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n	"
1382
+        . '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);'
1383
+        . "\n\tif (\$debut_boucle>0"
1384
+        . " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']"
1385
+        . " AND \$iter->seek(\$debut_boucle,'continue'))"
1386
+        . "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t";
1387
+
1388
+    $boucles[$id_boucle]->partie = "
1389 1389
 		if (\$Numrows['$id_boucle']['compteur_boucle'] <= \$debut_boucle) continue;
1390 1390
 		if (\$Numrows['$id_boucle']['compteur_boucle']-1 > \$fin_boucle) break;";
1391 1391
 }
@@ -1402,26 +1402,26 @@  discard block
 block discarded – undo
1402 1402
  * @return array          Valeur de l'élément (peut être une expression PHP), Nombre soustrait
1403 1403
  **/
1404 1404
 function calculer_critere_parties_aux($idb, &$boucles, $param) {
1405
-	if ($param[0]->type != 'texte') {
1406
-		$a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent);
1407
-		if (isset($param[1]->texte)) {
1408
-			preg_match(',^\s*(-([0-9]+))?\s*$,', $param[1]->texte, $m);
1409
-
1410
-			return ["intval($a1)", ((isset($m[2]) and $m[2]) ? $m[2] : 0)];
1411
-		} else {
1412
-			return ["intval($a1)", 0];
1413
-		}
1414
-	} else {
1415
-		preg_match(',^\s*(([0-9]+)|n)\s*(-\s*([0-9]+)?\s*)?$,', $param[0]->texte, $m);
1416
-		$a1 = $m[1];
1417
-		if (empty($m[3])) {
1418
-			return [$a1, 0];
1419
-		} elseif (!empty($m[4])) {
1420
-			return [$a1, $m[4]];
1421
-		} else {
1422
-			return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)];
1423
-		}
1424
-	}
1405
+    if ($param[0]->type != 'texte') {
1406
+        $a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent);
1407
+        if (isset($param[1]->texte)) {
1408
+            preg_match(',^\s*(-([0-9]+))?\s*$,', $param[1]->texte, $m);
1409
+
1410
+            return ["intval($a1)", ((isset($m[2]) and $m[2]) ? $m[2] : 0)];
1411
+        } else {
1412
+            return ["intval($a1)", 0];
1413
+        }
1414
+    } else {
1415
+        preg_match(',^\s*(([0-9]+)|n)\s*(-\s*([0-9]+)?\s*)?$,', $param[0]->texte, $m);
1416
+        $a1 = $m[1];
1417
+        if (empty($m[3])) {
1418
+            return [$a1, 0];
1419
+        } elseif (!empty($m[4])) {
1420
+            return [$a1, $m[4]];
1421
+        } else {
1422
+            return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)];
1423
+        }
1424
+    }
1425 1425
 }
1426 1426
 
1427 1427
 
@@ -1448,47 +1448,47 @@  discard block
 block discarded – undo
1448 1448
  *     array : Erreur sur un des critères
1449 1449
  **/
1450 1450
 function calculer_criteres($idb, &$boucles) {
1451
-	$msg = '';
1452
-	$boucle = $boucles[$idb];
1453
-	$table = strtoupper($boucle->type_requete);
1454
-	$serveur = strtolower($boucle->sql_serveur);
1455
-
1456
-	$defaut = charger_fonction('DEFAUT', 'calculer_critere');
1457
-	// s'il y avait une erreur de syntaxe, propager cette info
1458
-	if (!is_array($boucle->criteres)) {
1459
-		return [];
1460
-	}
1461
-
1462
-	foreach ($boucle->criteres as $crit) {
1463
-		$critere = $crit->op;
1464
-		// critere personnalise ?
1465
-		if (
1466
-			(!$serveur or
1467
-				((!function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere))
1468
-					and (!function_exists($f = $f . '_dist'))
1469
-					and (!function_exists($f = 'critere_' . $serveur . '_' . $critere))
1470
-					and (!function_exists($f = $f . '_dist'))
1471
-				)
1472
-			)
1473
-			and (!function_exists($f = 'critere_' . $table . '_' . $critere))
1474
-			and (!function_exists($f = $f . '_dist'))
1475
-			and (!function_exists($f = 'critere_' . $critere))
1476
-			and (!function_exists($f = $f . '_dist'))
1477
-		) {
1478
-			// fonction critere standard
1479
-			$f = $defaut;
1480
-		}
1481
-		// compile le critere
1482
-		$res = $f($idb, $boucles, $crit);
1483
-
1484
-		// Gestion centralisee des erreurs pour pouvoir propager
1485
-		if (is_array($res)) {
1486
-			$msg = $res;
1487
-			erreur_squelette($msg, $boucle);
1488
-		}
1489
-	}
1490
-
1491
-	return $msg;
1451
+    $msg = '';
1452
+    $boucle = $boucles[$idb];
1453
+    $table = strtoupper($boucle->type_requete);
1454
+    $serveur = strtolower($boucle->sql_serveur);
1455
+
1456
+    $defaut = charger_fonction('DEFAUT', 'calculer_critere');
1457
+    // s'il y avait une erreur de syntaxe, propager cette info
1458
+    if (!is_array($boucle->criteres)) {
1459
+        return [];
1460
+    }
1461
+
1462
+    foreach ($boucle->criteres as $crit) {
1463
+        $critere = $crit->op;
1464
+        // critere personnalise ?
1465
+        if (
1466
+            (!$serveur or
1467
+                ((!function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere))
1468
+                    and (!function_exists($f = $f . '_dist'))
1469
+                    and (!function_exists($f = 'critere_' . $serveur . '_' . $critere))
1470
+                    and (!function_exists($f = $f . '_dist'))
1471
+                )
1472
+            )
1473
+            and (!function_exists($f = 'critere_' . $table . '_' . $critere))
1474
+            and (!function_exists($f = $f . '_dist'))
1475
+            and (!function_exists($f = 'critere_' . $critere))
1476
+            and (!function_exists($f = $f . '_dist'))
1477
+        ) {
1478
+            // fonction critere standard
1479
+            $f = $defaut;
1480
+        }
1481
+        // compile le critere
1482
+        $res = $f($idb, $boucles, $crit);
1483
+
1484
+        // Gestion centralisee des erreurs pour pouvoir propager
1485
+        if (is_array($res)) {
1486
+            $msg = $res;
1487
+            erreur_squelette($msg, $boucle);
1488
+        }
1489
+    }
1490
+
1491
+    return $msg;
1492 1492
 }
1493 1493
 
1494 1494
 /**
@@ -1503,11 +1503,11 @@  discard block
 block discarded – undo
1503 1503
  * @return string         Code compilé rééchappé
1504 1504
  */
1505 1505
 function kwote($lisp, $serveur = '', $type = '') {
1506
-	if (preg_match(_CODE_QUOTE, $lisp, $r)) {
1507
-		return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"';
1508
-	} else {
1509
-		return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')";
1510
-	}
1506
+    if (preg_match(_CODE_QUOTE, $lisp, $r)) {
1507
+        return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"';
1508
+    } else {
1509
+        return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')";
1510
+    }
1511 1511
 }
1512 1512
 
1513 1513
 
@@ -1526,81 +1526,81 @@  discard block
 block discarded – undo
1526 1526
  * @return void|array
1527 1527
  **/
1528 1528
 function critere_IN_dist($idb, &$boucles, $crit) {
1529
-	$r = calculer_critere_infixe($idb, $boucles, $crit);
1530
-	if (!$r) {
1531
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1532
-	}
1533
-	[$arg, $op, $val, $col, $where_complement] = $r;
1534
-
1535
-	$in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col);
1536
-
1537
-	//	inserer la condition; exemple: {id_mot ?IN (66, 62, 64)}
1538
-	$where = $in;
1539
-	if ($crit->cond) {
1540
-		$pred = calculer_argument_precedent($idb, $col, $boucles);
1541
-		$where = ["'?'", $pred, $where, "''"];
1542
-		if ($where_complement) { // condition annexe du type "AND (objet='article')"
1543
-		$where_complement = ["'?'", $pred, $where_complement, "''"];
1544
-		}
1545
-	}
1546
-	if ($crit->exclus) {
1547
-		if (!preg_match(',^L[0-9]+[.],', $arg)) {
1548
-			$where = ["'NOT'", $where];
1549
-		} else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1550
-			// c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1551
-		{
1552
-			$where = [
1553
-				"'NOT'",
1554
-				[
1555
-					"'IN'",
1556
-					"'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1557
-					["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1558
-				]
1559
-			];
1560
-		}
1561
-	}
1562
-
1563
-	$boucles[$idb]->where[] = $where;
1564
-	if ($where_complement) { // condition annexe du type "AND (objet='article')"
1565
-	$boucles[$idb]->where[] = $where_complement;
1566
-	}
1529
+    $r = calculer_critere_infixe($idb, $boucles, $crit);
1530
+    if (!$r) {
1531
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1532
+    }
1533
+    [$arg, $op, $val, $col, $where_complement] = $r;
1534
+
1535
+    $in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col);
1536
+
1537
+    //	inserer la condition; exemple: {id_mot ?IN (66, 62, 64)}
1538
+    $where = $in;
1539
+    if ($crit->cond) {
1540
+        $pred = calculer_argument_precedent($idb, $col, $boucles);
1541
+        $where = ["'?'", $pred, $where, "''"];
1542
+        if ($where_complement) { // condition annexe du type "AND (objet='article')"
1543
+        $where_complement = ["'?'", $pred, $where_complement, "''"];
1544
+        }
1545
+    }
1546
+    if ($crit->exclus) {
1547
+        if (!preg_match(',^L[0-9]+[.],', $arg)) {
1548
+            $where = ["'NOT'", $where];
1549
+        } else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1550
+            // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1551
+        {
1552
+            $where = [
1553
+                "'NOT'",
1554
+                [
1555
+                    "'IN'",
1556
+                    "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1557
+                    ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1558
+                ]
1559
+            ];
1560
+        }
1561
+    }
1562
+
1563
+    $boucles[$idb]->where[] = $where;
1564
+    if ($where_complement) { // condition annexe du type "AND (objet='article')"
1565
+    $boucles[$idb]->where[] = $where_complement;
1566
+    }
1567 1567
 }
1568 1568
 
1569 1569
 function critere_IN_cas($idb, &$boucles, $crit2, $arg, $op, $val, $col) {
1570
-	static $num = [];
1571
-	$descr = $boucles[$idb]->descr;
1572
-	$cpt = &$num[$descr['nom']][$descr['gram']][$idb];
1573
-
1574
-	$var = '$in' . $cpt++;
1575
-	$x = "\n\t$var = array();";
1576
-	foreach ($val as $k => $v) {
1577
-		if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) {
1578
-			// optimiser le traitement des constantes
1579
-			if (is_numeric($r[2])) {
1580
-				$x .= "\n\t$var" . "[]= $r[2];";
1581
-			} else {
1582
-				$x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';';
1583
-			}
1584
-		} else {
1585
-			// Pour permettre de passer des tableaux de valeurs
1586
-			// on repere l'utilisation brute de #ENV**{X},
1587
-			// c'est-a-dire sa  traduction en ($PILE[0][X]).
1588
-			// et on deballe mais en rajoutant l'anti XSS
1589
-			$x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);";
1590
-		}
1591
-	}
1592
-
1593
-	$boucles[$idb]->in .= $x;
1594
-
1595
-	// inserer le tri par defaut selon les ordres du IN ...
1596
-	// avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp)
1597
-	// et que l'on limite donc strictement aux cas necessaires :
1598
-	// si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle
1599
-	if (!$crit2) {
1600
-		$boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))";
1601
-	}
1602
-
1603
-	return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')';
1570
+    static $num = [];
1571
+    $descr = $boucles[$idb]->descr;
1572
+    $cpt = &$num[$descr['nom']][$descr['gram']][$idb];
1573
+
1574
+    $var = '$in' . $cpt++;
1575
+    $x = "\n\t$var = array();";
1576
+    foreach ($val as $k => $v) {
1577
+        if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) {
1578
+            // optimiser le traitement des constantes
1579
+            if (is_numeric($r[2])) {
1580
+                $x .= "\n\t$var" . "[]= $r[2];";
1581
+            } else {
1582
+                $x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';';
1583
+            }
1584
+        } else {
1585
+            // Pour permettre de passer des tableaux de valeurs
1586
+            // on repere l'utilisation brute de #ENV**{X},
1587
+            // c'est-a-dire sa  traduction en ($PILE[0][X]).
1588
+            // et on deballe mais en rajoutant l'anti XSS
1589
+            $x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);";
1590
+        }
1591
+    }
1592
+
1593
+    $boucles[$idb]->in .= $x;
1594
+
1595
+    // inserer le tri par defaut selon les ordres du IN ...
1596
+    // avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp)
1597
+    // et que l'on limite donc strictement aux cas necessaires :
1598
+    // si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle
1599
+    if (!$crit2) {
1600
+        $boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))";
1601
+    }
1602
+
1603
+    return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')';
1604 1604
 }
1605 1605
 
1606 1606
 /**
@@ -1616,22 +1616,22 @@  discard block
 block discarded – undo
1616 1616
  * @return void
1617 1617
  */
1618 1618
 function critere_where_dist($idb, &$boucles, $crit) {
1619
-	$boucle = &$boucles[$idb];
1620
-	if (isset($crit->param[0])) {
1621
-		$_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1622
-	} else {
1623
-		$_where = 'spip_sanitize_from_request(@$Pile[0]["where"],"where","vide")';
1624
-	}
1625
-
1626
-	if ($crit->cond) {
1627
-		$_where = "((\$zzw = $_where) ? \$zzw : '')";
1628
-	}
1629
-
1630
-	if ($crit->not) {
1631
-		$_where = "array('NOT',$_where)";
1632
-	}
1633
-
1634
-	$boucle->where[] = $_where;
1619
+    $boucle = &$boucles[$idb];
1620
+    if (isset($crit->param[0])) {
1621
+        $_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1622
+    } else {
1623
+        $_where = 'spip_sanitize_from_request(@$Pile[0]["where"],"where","vide")';
1624
+    }
1625
+
1626
+    if ($crit->cond) {
1627
+        $_where = "((\$zzw = $_where) ? \$zzw : '')";
1628
+    }
1629
+
1630
+    if ($crit->not) {
1631
+        $_where = "array('NOT',$_where)";
1632
+    }
1633
+
1634
+    $boucle->where[] = $_where;
1635 1635
 }
1636 1636
 
1637 1637
 /**
@@ -1659,31 +1659,31 @@  discard block
 block discarded – undo
1659 1659
  * @return void
1660 1660
  */
1661 1661
 function critere_id__dist($idb, &$boucles, $crit) {
1662
-	/** @var Boucle $boucle */
1663
-	$boucle = $boucles[$idb];
1664
-
1665
-	$champs = lister_champs_id_conditionnel(
1666
-		$boucle->show['table'],
1667
-		$boucle->show,
1668
-		$boucle->sql_serveur
1669
-	);
1670
-
1671
-	// ne pas tenir compte des critères identiques déjà présents.
1672
-	if (!empty($boucle->modificateur['criteres'])) {
1673
-		$champs = array_diff($champs, array_keys($boucle->modificateur['criteres']));
1674
-	}
1675
-	// nous aider en mode debug.
1676
-	$boucle->debug[] = 'id_ : ' . implode(', ', $champs);
1677
-	$boucle->modificateur['id_'] = $champs;
1678
-
1679
-	// créer un critère {id_xxx?} de chaque champ retenu
1680
-	foreach ($champs as $champ) {
1681
-		$critere_id_table = new Critere();
1682
-		$critere_id_table->op = $champ;
1683
-		$critere_id_table->cond = '?';
1684
-		$critere_id_table->ligne = $crit->ligne;
1685
-		calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table);
1686
-	}
1662
+    /** @var Boucle $boucle */
1663
+    $boucle = $boucles[$idb];
1664
+
1665
+    $champs = lister_champs_id_conditionnel(
1666
+        $boucle->show['table'],
1667
+        $boucle->show,
1668
+        $boucle->sql_serveur
1669
+    );
1670
+
1671
+    // ne pas tenir compte des critères identiques déjà présents.
1672
+    if (!empty($boucle->modificateur['criteres'])) {
1673
+        $champs = array_diff($champs, array_keys($boucle->modificateur['criteres']));
1674
+    }
1675
+    // nous aider en mode debug.
1676
+    $boucle->debug[] = 'id_ : ' . implode(', ', $champs);
1677
+    $boucle->modificateur['id_'] = $champs;
1678
+
1679
+    // créer un critère {id_xxx?} de chaque champ retenu
1680
+    foreach ($champs as $champ) {
1681
+        $critere_id_table = new Critere();
1682
+        $critere_id_table->op = $champ;
1683
+        $critere_id_table->cond = '?';
1684
+        $critere_id_table->ligne = $crit->ligne;
1685
+        calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table);
1686
+    }
1687 1687
 }
1688 1688
 
1689 1689
 /**
@@ -1703,75 +1703,75 @@  discard block
 block discarded – undo
1703 1703
  * @return array Liste de nom de champs (tel que id_article, id_mot, id_parent ...)
1704 1704
  */
1705 1705
 function lister_champs_id_conditionnel($table, $desc = null, $serveur = '') {
1706
-	// calculer la description de la table
1707
-	if (!is_array($desc)) {
1708
-		$desc = description_table($table, $serveur);
1709
-	}
1710
-	if (!$desc) {
1711
-		return [];
1712
-	}
1713
-
1714
-	// Les champs id_xx de la table demandée
1715
-	$champs = array_filter(
1716
-		array_keys($desc['field']),
1717
-		fn($champ) => strpos($champ, 'id_') === 0 or (in_array($champ, ['objet']))
1718
-	);
1719
-
1720
-	// Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute.
1721
-	if (
1722
-		in_array('id_rubrique', $champs)
1723
-		and !in_array('id_secteur', $champs)
1724
-	) {
1725
-		$champs[] = 'id_secteur';
1726
-	}
1727
-
1728
-	// On ne fera pas mieux pour les tables d’un autre serveur
1729
-	if ($serveur) {
1730
-		return $champs;
1731
-	}
1732
-
1733
-	$primary = false;
1734
-	$associable = false;
1735
-	include_spip('action/editer_liens');
1736
-
1737
-	if (isset($desc['type'])) {
1738
-		$primary = id_table_objet($desc['type']);
1739
-		$associable = objet_associable($desc['type']);
1740
-	}
1741
-	if (isset($desc['field']['id_objet']) and isset($desc['field']['objet'])) {
1742
-		$associable = true;
1743
-	}
1744
-
1745
-	// liste de toutes les tables principales, sauf la notre
1746
-	$tables = lister_tables_objets_sql();
1747
-	unset($tables[$table]);
1748
-
1749
-	foreach ($tables as $_table => $_desc) {
1750
-		if (
1751
-			$associable
1752
-			or ($primary and in_array($primary, array_keys($_desc['field'])))
1753
-			or objet_associable($_desc['type'])
1754
-		) {
1755
-			$champs[] = id_table_objet($_table);
1756
-		}
1757
-	}
1758
-	$champs = array_values(array_unique($champs));
1759
-
1760
-	// Exclusions de certains id
1761
-	$exclusions = pipeline(
1762
-		'exclure_id_conditionnel',
1763
-		[
1764
-			'args' => [
1765
-				'table' => $table,
1766
-				'id_table_objet' => $primary,
1767
-				'associable' => $associable,
1768
-			],
1769
-			'data' => [],
1770
-		]
1771
-	);
1772
-	$champs = array_diff($champs, $exclusions);
1773
-
1774
-	return $champs;
1706
+    // calculer la description de la table
1707
+    if (!is_array($desc)) {
1708
+        $desc = description_table($table, $serveur);
1709
+    }
1710
+    if (!$desc) {
1711
+        return [];
1712
+    }
1713
+
1714
+    // Les champs id_xx de la table demandée
1715
+    $champs = array_filter(
1716
+        array_keys($desc['field']),
1717
+        fn($champ) => strpos($champ, 'id_') === 0 or (in_array($champ, ['objet']))
1718
+    );
1719
+
1720
+    // Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute.
1721
+    if (
1722
+        in_array('id_rubrique', $champs)
1723
+        and !in_array('id_secteur', $champs)
1724
+    ) {
1725
+        $champs[] = 'id_secteur';
1726
+    }
1727
+
1728
+    // On ne fera pas mieux pour les tables d’un autre serveur
1729
+    if ($serveur) {
1730
+        return $champs;
1731
+    }
1732
+
1733
+    $primary = false;
1734
+    $associable = false;
1735
+    include_spip('action/editer_liens');
1736
+
1737
+    if (isset($desc['type'])) {
1738
+        $primary = id_table_objet($desc['type']);
1739
+        $associable = objet_associable($desc['type']);
1740
+    }
1741
+    if (isset($desc['field']['id_objet']) and isset($desc['field']['objet'])) {
1742
+        $associable = true;
1743
+    }
1744
+
1745
+    // liste de toutes les tables principales, sauf la notre
1746
+    $tables = lister_tables_objets_sql();
1747
+    unset($tables[$table]);
1748
+
1749
+    foreach ($tables as $_table => $_desc) {
1750
+        if (
1751
+            $associable
1752
+            or ($primary and in_array($primary, array_keys($_desc['field'])))
1753
+            or objet_associable($_desc['type'])
1754
+        ) {
1755
+            $champs[] = id_table_objet($_table);
1756
+        }
1757
+    }
1758
+    $champs = array_values(array_unique($champs));
1759
+
1760
+    // Exclusions de certains id
1761
+    $exclusions = pipeline(
1762
+        'exclure_id_conditionnel',
1763
+        [
1764
+            'args' => [
1765
+                'table' => $table,
1766
+                'id_table_objet' => $primary,
1767
+                'associable' => $associable,
1768
+            ],
1769
+            'data' => [],
1770
+        ]
1771
+    );
1772
+    $champs = array_diff($champs, $exclusions);
1773
+
1774
+    return $champs;
1775 1775
 }
1776 1776
 
1777 1777
 /**
@@ -1826,28 +1826,28 @@  discard block
 block discarded – undo
1826 1826
  * @return void
1827 1827
  */
1828 1828
 function critere_tri_dist($idb, &$boucles, $crit) {
1829
-	$boucle = &$boucles[$idb];
1830
-
1831
-	// definition du champ par defaut
1832
-	$_champ_defaut = !isset($crit->param[0][0]) ? "''"
1833
-		: calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent);
1834
-	$_liste_sens_defaut = !isset($crit->param[1][0]) ? '1'
1835
-		: calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
1836
-	$_variable = !isset($crit->param[2][0]) ? "'$idb'"
1837
-		: calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent);
1838
-
1839
-	$_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):'')";
1840
-
1841
-	$_sens_defaut = "(is_array(\$s=$_liste_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)";
1842
-	$_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)";
1843
-
1844
-	$boucle->modificateur['tri_champ'] = $_tri;
1845
-	$boucle->modificateur['tri_sens'] = $_sens;
1846
-	$boucle->modificateur['tri_liste_sens_defaut'] = $_liste_sens_defaut;
1847
-	$boucle->modificateur['tri_nom'] = $_variable;
1848
-	// faut il inserer un test sur l'existence de $tri parmi les champs de la table ?
1849
-	// evite des erreurs sql, mais peut empecher des tri sur jointure ...
1850
-	$boucle->hash .= "
1829
+    $boucle = &$boucles[$idb];
1830
+
1831
+    // definition du champ par defaut
1832
+    $_champ_defaut = !isset($crit->param[0][0]) ? "''"
1833
+        : calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent);
1834
+    $_liste_sens_defaut = !isset($crit->param[1][0]) ? '1'
1835
+        : calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
1836
+    $_variable = !isset($crit->param[2][0]) ? "'$idb'"
1837
+        : calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent);
1838
+
1839
+    $_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):'')";
1840
+
1841
+    $_sens_defaut = "(is_array(\$s=$_liste_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)";
1842
+    $_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)";
1843
+
1844
+    $boucle->modificateur['tri_champ'] = $_tri;
1845
+    $boucle->modificateur['tri_sens'] = $_sens;
1846
+    $boucle->modificateur['tri_liste_sens_defaut'] = $_liste_sens_defaut;
1847
+    $boucle->modificateur['tri_nom'] = $_variable;
1848
+    // faut il inserer un test sur l'existence de $tri parmi les champs de la table ?
1849
+    // evite des erreurs sql, mais peut empecher des tri sur jointure ...
1850
+    $boucle->hash .= "
1851 1851
 	\$senstri = '';
1852 1852
 	\$tri = $_tri;
1853 1853
 	if (\$tri){
@@ -1855,8 +1855,8 @@  discard block
 block discarded – undo
1855 1855
 		\$senstri = (\$senstri<0)?' DESC':'';
1856 1856
 	};
1857 1857
 	";
1858
-	$boucle->select[] = '".tri_champ_select($tri)."';
1859
-	$boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)";
1858
+    $boucle->select[] = '".tri_champ_select($tri)."';
1859
+    $boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)";
1860 1860
 }
1861 1861
 
1862 1862
 # criteres de comparaison
@@ -1873,20 +1873,20 @@  discard block
 block discarded – undo
1873 1873
  * @return void|array
1874 1874
  **/
1875 1875
 function calculer_critere_DEFAUT_dist($idb, &$boucles, $crit) {
1876
-	// double cas particulier {0,1} et {1/2} repere a l'analyse lexicale
1877
-	if (($crit->op == ',') or ($crit->op == '/')) {
1878
-		return calculer_critere_parties($idb, $boucles, $crit);
1879
-	}
1880
-
1881
-	$r = calculer_critere_infixe($idb, $boucles, $crit);
1882
-	if (!$r) {
1883
-		#	// on produit une erreur seulement si le critere n'a pas de '?'
1884
-		#	if (!$crit->cond) {
1885
-		return ['zbug_critere_inconnu', ['critere' => $crit->op]];
1886
-		#	}
1887
-	} else {
1888
-		calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r);
1889
-	}
1876
+    // double cas particulier {0,1} et {1/2} repere a l'analyse lexicale
1877
+    if (($crit->op == ',') or ($crit->op == '/')) {
1878
+        return calculer_critere_parties($idb, $boucles, $crit);
1879
+    }
1880
+
1881
+    $r = calculer_critere_infixe($idb, $boucles, $crit);
1882
+    if (!$r) {
1883
+        #	// on produit une erreur seulement si le critere n'a pas de '?'
1884
+        #	if (!$crit->cond) {
1885
+        return ['zbug_critere_inconnu', ['critere' => $crit->op]];
1886
+        #	}
1887
+    } else {
1888
+        calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r);
1889
+    }
1890 1890
 }
1891 1891
 
1892 1892
 
@@ -1906,62 +1906,62 @@  discard block
 block discarded – undo
1906 1906
  * @return void
1907 1907
  **/
1908 1908
 function calculer_critere_DEFAUT_args($idb, &$boucles, $crit, $args) {
1909
-	[$arg, $op, $val, $col, $where_complement] = $args;
1910
-
1911
-	$where = ["'$op'", "'$arg'", $val[0]];
1912
-
1913
-	// inserer la negation (cf !...)
1914
-
1915
-	if ($crit->not) {
1916
-		$where = ["'NOT'", $where];
1917
-	}
1918
-	if ($crit->exclus) {
1919
-		if (!preg_match(',^L[0-9]+[.],', $arg)) {
1920
-			$where = ["'NOT'", $where];
1921
-		} else {
1922
-			// un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1923
-			// c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1924
-			$where = [
1925
-				"'NOT'",
1926
-				[
1927
-					"'IN'",
1928
-					"'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1929
-					["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1930
-				]
1931
-			];
1932
-		}
1933
-	}
1934
-
1935
-	// inserer la condition (cf {lang?})
1936
-	// traiter a part la date, elle est mise d'office par SPIP,
1937
-	if ($crit->cond) {
1938
-		$pred = calculer_argument_precedent($idb, $col, $boucles);
1939
-		if ($col === 'date' or $col === 'date_redac') {
1940
-			if ($pred === "\$Pile[0]['" . $col . "']") {
1941
-				$pred = "(\$Pile[0]['{$col}_default']?'':$pred)";
1942
-			}
1943
-		}
1944
-
1945
-		if ($op === '=' and !$crit->not) {
1946
-			$where = [
1947
-				"'?'",
1948
-				"(is_array($pred))",
1949
-				critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col),
1950
-				$where
1951
-			];
1952
-		}
1953
-		$where = ["'?'", "!is_whereable($pred)", "''", $where];
1954
-		if ($where_complement) {
1955
-			// condition annexe du type "AND (objet='article')"
1956
-			$where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement];
1957
-		}
1958
-	}
1959
-
1960
-	$boucles[$idb]->where[] = $where;
1961
-	if ($where_complement) {
1962
-		// condition annexe du type "AND (objet='article')"
1963
-		$boucles[$idb]->where[] = $where_complement;
1964
-	}
1909
+    [$arg, $op, $val, $col, $where_complement] = $args;
1910
+
1911
+    $where = ["'$op'", "'$arg'", $val[0]];
1912
+
1913
+    // inserer la negation (cf !...)
1914
+
1915
+    if ($crit->not) {
1916
+        $where = ["'NOT'", $where];
1917
+    }
1918
+    if ($crit->exclus) {
1919
+        if (!preg_match(',^L[0-9]+[.],', $arg)) {
1920
+            $where = ["'NOT'", $where];
1921
+        } else {
1922
+            // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1923
+            // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1924
+            $where = [
1925
+                "'NOT'",
1926
+                [
1927
+                    "'IN'",
1928
+                    "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1929
+                    ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1930
+                ]
1931
+            ];
1932
+        }
1933
+    }
1934
+
1935
+    // inserer la condition (cf {lang?})
1936
+    // traiter a part la date, elle est mise d'office par SPIP,
1937
+    if ($crit->cond) {
1938
+        $pred = calculer_argument_precedent($idb, $col, $boucles);
1939
+        if ($col === 'date' or $col === 'date_redac') {
1940
+            if ($pred === "\$Pile[0]['" . $col . "']") {
1941
+                $pred = "(\$Pile[0]['{$col}_default']?'':$pred)";
1942
+            }
1943
+        }
1944
+
1945
+        if ($op === '=' and !$crit->not) {
1946
+            $where = [
1947
+                "'?'",
1948
+                "(is_array($pred))",
1949
+                critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col),
1950
+                $where
1951
+            ];
1952
+        }
1953
+        $where = ["'?'", "!is_whereable($pred)", "''", $where];
1954
+        if ($where_complement) {
1955
+            // condition annexe du type "AND (objet='article')"
1956
+            $where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement];
1957
+        }
1958
+    }
1959
+
1960
+    $boucles[$idb]->where[] = $where;
1961
+    if ($where_complement) {
1962
+        // condition annexe du type "AND (objet='article')"
1963
+        $boucles[$idb]->where[] = $where_complement;
1964
+    }
1965 1965
 }
1966 1966
 
1967 1967
 
@@ -2002,165 +2002,165 @@  discard block
 block discarded – undo
2002 2002
  **/
2003 2003
 function calculer_critere_infixe($idb, &$boucles, $crit) {
2004 2004
 
2005
-	$boucle = &$boucles[$idb];
2006
-	$type = $boucle->type_requete;
2007
-	$table = $boucle->id_table;
2008
-	$desc = $boucle->show;
2009
-	$col_vraie = null;
2010
-
2011
-	[$fct, $col, $op, $val, $args_sql] =
2012
-		calculer_critere_infixe_ops($idb, $boucles, $crit);
2013
-
2014
-	$col_alias = $col;
2015
-	$where_complement = false;
2016
-
2017
-	// Cas particulier : id_enfant => utiliser la colonne id_objet
2018
-	if ($col == 'id_enfant') {
2019
-		$col = $boucle->primary;
2020
-	}
2021
-
2022
-	// Cas particulier : id_parent => verifier les exceptions de tables
2023
-	if (
2024
-		(in_array($col, ['id_parent', 'id_secteur']) and isset($GLOBALS['exceptions_des_tables'][$table][$col]))
2025
-		or (isset($GLOBALS['exceptions_des_tables'][$table][$col]) and is_string($GLOBALS['exceptions_des_tables'][$table][$col]))
2026
-	) {
2027
-		$col = $GLOBALS['exceptions_des_tables'][$table][$col];
2028
-	} // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums)
2029
-	else {
2030
-		if (($col == 'id_secteur') and ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) {
2031
-			$table = $critere_secteur($idb, $boucles, $val, $crit);
2032
-		}
2033
-
2034
-		// cas id_article=xx qui se mappe en id_objet=xx AND objet=article
2035
-		// sauf si exception declaree : sauter cette etape
2036
-		else {
2037
-			if (
2038
-				!isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col])
2039
-				and !isset($GLOBALS['exceptions_des_jointures'][$col])
2040
-				and count(trouver_champs_decomposes($col, $desc)) > 1
2041
-			) {
2042
-				$e = decompose_champ_id_objet($col);
2043
-				$col = array_shift($e);
2044
-				$where_complement = primary_doublee($e, $table);
2045
-			} // Cas particulier : expressions de date
2046
-			else {
2047
-				if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) {
2048
-					[$col, $col_vraie] = $c;
2049
-					$table = '';
2050
-				} // table explicitée {mots.titre}
2051
-				else {
2052
-					if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2053
-						[, $table, $col] = $r;
2054
-						$col_alias = $col;
2055
-
2056
-						$trouver_table = charger_fonction('trouver_table', 'base');
2057
-						if (
2058
-							$desc = $trouver_table($table, $boucle->sql_serveur)
2059
-							and isset($desc['field'][$col])
2060
-							and $cle = array_search($desc['table'], $boucle->from)
2061
-						) {
2062
-							$table = $cle;
2063
-						} else {
2064
-							$table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond or $op != '='));
2065
-						}
2066
-						#$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true);
2067
-						if (!$table) {
2068
-							return '';
2069
-						}
2070
-					}
2071
-					// si le champ n'est pas trouvé dans la table,
2072
-					// on cherche si une jointure peut l'obtenir
2073
-					elseif (@!array_key_exists($col, $desc['field'])) {
2074
-						// Champ joker * des iterateurs DATA qui accepte tout
2075
-						if (@array_key_exists('*', $desc['field'])) {
2076
-							$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
2077
-						}
2078
-						else {
2079
-							$r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table);
2080
-							if (!$r) {
2081
-								return '';
2082
-							}
2083
-							[$col, $col_alias, $table, $where_complement, $desc] = $r;
2084
-						}
2085
-					}
2086
-				}
2087
-			}
2088
-		}
2089
-	}
2090
-
2091
-	$col_vraie = ($col_vraie ?: $col);
2092
-	// Dans tous les cas,
2093
-	// virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL)
2094
-	// et passer dans sql_quote avec le type si connu
2095
-	// et int sinon si la valeur est numerique
2096
-	// sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon)
2097
-	// Ne pas utiliser intval, PHP tronquant les Bigint de SQL
2098
-	if ($op == '=' or in_array($op, $GLOBALS['table_criteres_infixes'])) {
2099
-		$type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL');
2100
-		// defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon
2101
-		// prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut
2102
-		if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", $val[0], $r)) {
2103
-			$val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"';
2104
-		}
2105
-		// sinon expliciter les
2106
-		// sql_quote(truc) en sql_quote(truc,'',type)
2107
-		// sql_quote(truc,serveur) en sql_quote(truc,serveur,type)
2108
-		// sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type)
2109
-		// sans toucher aux
2110
-		// sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE')
2111
-		// sql_quote(truc,'','varchar')
2112
-		elseif (
2113
-			preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', $val[0], $r)
2114
-			// si pas deja un type
2115
-			and (!isset($r[3]) or !$r[3] or !trim($r[3], ", '"))
2116
-		) {
2117
-			$r = $r[1]
2118
-				. ((isset($r[2]) and $r[2]) ? $r[2] : ",''")
2119
-				. ",'" . addslashes($type_cast_quote) . "'";
2120
-			$val[0] = "sql_quote($r)";
2121
-		}
2122
-		elseif (
2123
-			strpos($val[0], '@@defaultcast@@') !== false
2124
-			and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2125
-		) {
2126
-			$val[0] = substr($val[0], 0, -strlen($r[0])) . "'" . addslashes($type_cast_quote) . "')";
2127
-		}
2128
-	}
2129
-
2130
-	if (
2131
-		strpos($val[0], '@@defaultcast@@') !== false
2132
-		and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2133
-	) {
2134
-		$val[0] = substr($val[0], 0, -strlen($r[0])) . "'char')";
2135
-	}
2136
-
2137
-	// Indicateur pour permettre aux fonctionx boucle_X de modifier
2138
-	// leurs requetes par defaut, notamment le champ statut
2139
-	// Ne pas confondre champs de la table principale et des jointures
2140
-	if ($table === $boucle->id_table) {
2141
-		$boucles[$idb]->modificateur['criteres'][$col_vraie] = true;
2142
-		if ($col_alias != $col_vraie) {
2143
-			$boucles[$idb]->modificateur['criteres'][$col_alias] = true;
2144
-		}
2145
-	}
2146
-
2147
-	// inserer le nom de la table SQL devant le nom du champ
2148
-	if ($table) {
2149
-		if ($col[0] == '`') {
2150
-			$arg = "$table." . substr($col, 1, -1);
2151
-		} else {
2152
-			$arg = "$table.$col";
2153
-		}
2154
-	} else {
2155
-		$arg = $col;
2156
-	}
2157
-
2158
-	// inserer la fonction SQL
2159
-	if ($fct) {
2160
-		$arg = "$fct($arg$args_sql)";
2161
-	}
2162
-
2163
-	return [$arg, $op, $val, $col_alias, $where_complement];
2005
+    $boucle = &$boucles[$idb];
2006
+    $type = $boucle->type_requete;
2007
+    $table = $boucle->id_table;
2008
+    $desc = $boucle->show;
2009
+    $col_vraie = null;
2010
+
2011
+    [$fct, $col, $op, $val, $args_sql] =
2012
+        calculer_critere_infixe_ops($idb, $boucles, $crit);
2013
+
2014
+    $col_alias = $col;
2015
+    $where_complement = false;
2016
+
2017
+    // Cas particulier : id_enfant => utiliser la colonne id_objet
2018
+    if ($col == 'id_enfant') {
2019
+        $col = $boucle->primary;
2020
+    }
2021
+
2022
+    // Cas particulier : id_parent => verifier les exceptions de tables
2023
+    if (
2024
+        (in_array($col, ['id_parent', 'id_secteur']) and isset($GLOBALS['exceptions_des_tables'][$table][$col]))
2025
+        or (isset($GLOBALS['exceptions_des_tables'][$table][$col]) and is_string($GLOBALS['exceptions_des_tables'][$table][$col]))
2026
+    ) {
2027
+        $col = $GLOBALS['exceptions_des_tables'][$table][$col];
2028
+    } // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums)
2029
+    else {
2030
+        if (($col == 'id_secteur') and ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) {
2031
+            $table = $critere_secteur($idb, $boucles, $val, $crit);
2032
+        }
2033
+
2034
+        // cas id_article=xx qui se mappe en id_objet=xx AND objet=article
2035
+        // sauf si exception declaree : sauter cette etape
2036
+        else {
2037
+            if (
2038
+                !isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col])
2039
+                and !isset($GLOBALS['exceptions_des_jointures'][$col])
2040
+                and count(trouver_champs_decomposes($col, $desc)) > 1
2041
+            ) {
2042
+                $e = decompose_champ_id_objet($col);
2043
+                $col = array_shift($e);
2044
+                $where_complement = primary_doublee($e, $table);
2045
+            } // Cas particulier : expressions de date
2046
+            else {
2047
+                if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) {
2048
+                    [$col, $col_vraie] = $c;
2049
+                    $table = '';
2050
+                } // table explicitée {mots.titre}
2051
+                else {
2052
+                    if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2053
+                        [, $table, $col] = $r;
2054
+                        $col_alias = $col;
2055
+
2056
+                        $trouver_table = charger_fonction('trouver_table', 'base');
2057
+                        if (
2058
+                            $desc = $trouver_table($table, $boucle->sql_serveur)
2059
+                            and isset($desc['field'][$col])
2060
+                            and $cle = array_search($desc['table'], $boucle->from)
2061
+                        ) {
2062
+                            $table = $cle;
2063
+                        } else {
2064
+                            $table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond or $op != '='));
2065
+                        }
2066
+                        #$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true);
2067
+                        if (!$table) {
2068
+                            return '';
2069
+                        }
2070
+                    }
2071
+                    // si le champ n'est pas trouvé dans la table,
2072
+                    // on cherche si une jointure peut l'obtenir
2073
+                    elseif (@!array_key_exists($col, $desc['field'])) {
2074
+                        // Champ joker * des iterateurs DATA qui accepte tout
2075
+                        if (@array_key_exists('*', $desc['field'])) {
2076
+                            $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
2077
+                        }
2078
+                        else {
2079
+                            $r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table);
2080
+                            if (!$r) {
2081
+                                return '';
2082
+                            }
2083
+                            [$col, $col_alias, $table, $where_complement, $desc] = $r;
2084
+                        }
2085
+                    }
2086
+                }
2087
+            }
2088
+        }
2089
+    }
2090
+
2091
+    $col_vraie = ($col_vraie ?: $col);
2092
+    // Dans tous les cas,
2093
+    // virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL)
2094
+    // et passer dans sql_quote avec le type si connu
2095
+    // et int sinon si la valeur est numerique
2096
+    // sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon)
2097
+    // Ne pas utiliser intval, PHP tronquant les Bigint de SQL
2098
+    if ($op == '=' or in_array($op, $GLOBALS['table_criteres_infixes'])) {
2099
+        $type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL');
2100
+        // defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon
2101
+        // prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut
2102
+        if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", $val[0], $r)) {
2103
+            $val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"';
2104
+        }
2105
+        // sinon expliciter les
2106
+        // sql_quote(truc) en sql_quote(truc,'',type)
2107
+        // sql_quote(truc,serveur) en sql_quote(truc,serveur,type)
2108
+        // sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type)
2109
+        // sans toucher aux
2110
+        // sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE')
2111
+        // sql_quote(truc,'','varchar')
2112
+        elseif (
2113
+            preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', $val[0], $r)
2114
+            // si pas deja un type
2115
+            and (!isset($r[3]) or !$r[3] or !trim($r[3], ", '"))
2116
+        ) {
2117
+            $r = $r[1]
2118
+                . ((isset($r[2]) and $r[2]) ? $r[2] : ",''")
2119
+                . ",'" . addslashes($type_cast_quote) . "'";
2120
+            $val[0] = "sql_quote($r)";
2121
+        }
2122
+        elseif (
2123
+            strpos($val[0], '@@defaultcast@@') !== false
2124
+            and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2125
+        ) {
2126
+            $val[0] = substr($val[0], 0, -strlen($r[0])) . "'" . addslashes($type_cast_quote) . "')";
2127
+        }
2128
+    }
2129
+
2130
+    if (
2131
+        strpos($val[0], '@@defaultcast@@') !== false
2132
+        and preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2133
+    ) {
2134
+        $val[0] = substr($val[0], 0, -strlen($r[0])) . "'char')";
2135
+    }
2136
+
2137
+    // Indicateur pour permettre aux fonctionx boucle_X de modifier
2138
+    // leurs requetes par defaut, notamment le champ statut
2139
+    // Ne pas confondre champs de la table principale et des jointures
2140
+    if ($table === $boucle->id_table) {
2141
+        $boucles[$idb]->modificateur['criteres'][$col_vraie] = true;
2142
+        if ($col_alias != $col_vraie) {
2143
+            $boucles[$idb]->modificateur['criteres'][$col_alias] = true;
2144
+        }
2145
+    }
2146
+
2147
+    // inserer le nom de la table SQL devant le nom du champ
2148
+    if ($table) {
2149
+        if ($col[0] == '`') {
2150
+            $arg = "$table." . substr($col, 1, -1);
2151
+        } else {
2152
+            $arg = "$table.$col";
2153
+        }
2154
+    } else {
2155
+        $arg = $col;
2156
+    }
2157
+
2158
+    // inserer la fonction SQL
2159
+    if ($fct) {
2160
+        $arg = "$fct($arg$args_sql)";
2161
+    }
2162
+
2163
+    return [$arg, $op, $val, $col_alias, $where_complement];
2164 2164
 }
2165 2165
 
2166 2166
 
@@ -2189,77 +2189,77 @@  discard block
 block discarded – undo
2189 2189
  **/
2190 2190
 function calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table) {
2191 2191
 
2192
-	$where = '';
2193
-
2194
-	$calculer_critere_externe = 'calculer_critere_externe_init';
2195
-	// gestion par les plugins des jointures tordues
2196
-	// pas automatiques mais necessaires
2197
-	$table_sql = table_objet_sql($table);
2198
-	if (
2199
-		isset($GLOBALS['exceptions_des_jointures'][$table_sql])
2200
-		and is_array($GLOBALS['exceptions_des_jointures'][$table_sql])
2201
-		and
2202
-		(
2203
-			isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col])
2204
-			or
2205
-			isset($GLOBALS['exceptions_des_jointures'][$table_sql][''])
2206
-		)
2207
-	) {
2208
-		$t = $GLOBALS['exceptions_des_jointures'][$table_sql];
2209
-		$index = $t[$col] ?? $t[''] ?? [];
2210
-
2211
-		if ((is_countable($index) ? count($index) : 0) == 3) {
2212
-			[$t, $col, $calculer_critere_externe] = $index;
2213
-		} elseif ((is_countable($index) ? count($index) : 0) == 2) {
2214
-			[$t, $col] = $t[$col];
2215
-		} elseif ((is_countable($index) ? count($index) : 0) == 1) {
2216
-			[$calculer_critere_externe] = $index;
2217
-			$t = $table;
2218
-		} else {
2219
-			$t = '';
2220
-		} // jointure non declaree. La trouver.
2221
-	} elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) {
2222
-		[$t, $col] = $GLOBALS['exceptions_des_jointures'][$col];
2223
-	} else {
2224
-		$t = '';
2225
-	} // jointure non declaree. La trouver.
2226
-
2227
-	// ici on construit le from pour fournir $col en piochant dans les jointures
2228
-
2229
-	// si des jointures explicites sont fournies, on cherche d'abord dans celles ci
2230
-	// permet de forcer une table de lien quand il y a ambiguite
2231
-	// <BOUCLE_(DOCUMENTS documents_liens){id_mot}>
2232
-	// alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}>
2233
-	$table = '';
2234
-	if ($boucle->jointures_explicites) {
2235
-		$jointures_explicites = explode(' ', $boucle->jointures_explicites);
2236
-		$table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond or $op != '='), $t);
2237
-	}
2238
-
2239
-	// et sinon on cherche parmi toutes les jointures declarees
2240
-	if (!$table) {
2241
-		$table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond or $op != '='), $t);
2242
-	}
2243
-
2244
-	if (!$table) {
2245
-		return '';
2246
-	}
2247
-
2248
-	// il ne reste plus qu'a trouver le champ dans les from
2249
-	[$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle);
2250
-
2251
-	if ((is_countable($cle) ? count($cle) : 0) > 1 or reset($cle) !== $col) {
2252
-		$col_alias = $col; // id_article devient juste le nom d'origine
2253
-		if ((is_countable($cle) ? count($cle) : 0) > 1 and reset($cle) == 'id_objet') {
2254
-			$e = decompose_champ_id_objet($col);
2255
-			$col = array_shift($e);
2256
-			$where = primary_doublee($e, $table);
2257
-		} else {
2258
-			$col = reset($cle);
2259
-		}
2260
-	}
2261
-
2262
-	return [$col, $col_alias, $table, $where, $desc];
2192
+    $where = '';
2193
+
2194
+    $calculer_critere_externe = 'calculer_critere_externe_init';
2195
+    // gestion par les plugins des jointures tordues
2196
+    // pas automatiques mais necessaires
2197
+    $table_sql = table_objet_sql($table);
2198
+    if (
2199
+        isset($GLOBALS['exceptions_des_jointures'][$table_sql])
2200
+        and is_array($GLOBALS['exceptions_des_jointures'][$table_sql])
2201
+        and
2202
+        (
2203
+            isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col])
2204
+            or
2205
+            isset($GLOBALS['exceptions_des_jointures'][$table_sql][''])
2206
+        )
2207
+    ) {
2208
+        $t = $GLOBALS['exceptions_des_jointures'][$table_sql];
2209
+        $index = $t[$col] ?? $t[''] ?? [];
2210
+
2211
+        if ((is_countable($index) ? count($index) : 0) == 3) {
2212
+            [$t, $col, $calculer_critere_externe] = $index;
2213
+        } elseif ((is_countable($index) ? count($index) : 0) == 2) {
2214
+            [$t, $col] = $t[$col];
2215
+        } elseif ((is_countable($index) ? count($index) : 0) == 1) {
2216
+            [$calculer_critere_externe] = $index;
2217
+            $t = $table;
2218
+        } else {
2219
+            $t = '';
2220
+        } // jointure non declaree. La trouver.
2221
+    } elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) {
2222
+        [$t, $col] = $GLOBALS['exceptions_des_jointures'][$col];
2223
+    } else {
2224
+        $t = '';
2225
+    } // jointure non declaree. La trouver.
2226
+
2227
+    // ici on construit le from pour fournir $col en piochant dans les jointures
2228
+
2229
+    // si des jointures explicites sont fournies, on cherche d'abord dans celles ci
2230
+    // permet de forcer une table de lien quand il y a ambiguite
2231
+    // <BOUCLE_(DOCUMENTS documents_liens){id_mot}>
2232
+    // alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}>
2233
+    $table = '';
2234
+    if ($boucle->jointures_explicites) {
2235
+        $jointures_explicites = explode(' ', $boucle->jointures_explicites);
2236
+        $table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond or $op != '='), $t);
2237
+    }
2238
+
2239
+    // et sinon on cherche parmi toutes les jointures declarees
2240
+    if (!$table) {
2241
+        $table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond or $op != '='), $t);
2242
+    }
2243
+
2244
+    if (!$table) {
2245
+        return '';
2246
+    }
2247
+
2248
+    // il ne reste plus qu'a trouver le champ dans les from
2249
+    [$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle);
2250
+
2251
+    if ((is_countable($cle) ? count($cle) : 0) > 1 or reset($cle) !== $col) {
2252
+        $col_alias = $col; // id_article devient juste le nom d'origine
2253
+        if ((is_countable($cle) ? count($cle) : 0) > 1 and reset($cle) == 'id_objet') {
2254
+            $e = decompose_champ_id_objet($col);
2255
+            $col = array_shift($e);
2256
+            $where = primary_doublee($e, $table);
2257
+        } else {
2258
+            $col = reset($cle);
2259
+        }
2260
+    }
2261
+
2262
+    return [$col, $col_alias, $table, $where, $desc];
2263 2263
 }
2264 2264
 
2265 2265
 
@@ -2280,10 +2280,10 @@  discard block
 block discarded – undo
2280 2280
  *     - valeur
2281 2281
  **/
2282 2282
 function primary_doublee($decompose, $table) {
2283
-	$e1 = reset($decompose);
2284
-	$e2 = "sql_quote('" . end($decompose) . "')";
2283
+    $e1 = reset($decompose);
2284
+    $e2 = "sql_quote('" . end($decompose) . "')";
2285 2285
 
2286
-	return ["'='", "'$table." . $e1 . "'", $e2];
2286
+    return ["'='", "'$table." . $e1 . "'", $e2];
2287 2287
 }
2288 2288
 
2289 2289
 /**
@@ -2314,57 +2314,57 @@  discard block
 block discarded – undo
2314 2314
  *     Vide sinon.
2315 2315
  */
2316 2316
 function calculer_critere_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) {
2317
-	// si on demande un truc du genre spip_mots
2318
-	// avec aussi spip_mots_liens dans les jointures dispo
2319
-	// et qu'on est la
2320
-	// il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots
2321
-	if (
2322
-		$checkarrivee
2323
-		and is_string($checkarrivee)
2324
-		and $a = table_objet($checkarrivee)
2325
-		and in_array($a . '_liens', $joints)
2326
-	) {
2327
-		if ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee)) {
2328
-			return $res;
2329
-		}
2330
-	}
2331
-	foreach ($joints as $joint) {
2332
-		if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) {
2333
-			// alias de table dans le from
2334
-			$t = array_search($arrivee[0], $boucle->from);
2335
-			// recuperer la cle id_xx eventuellement decomposee en (id_objet,objet)
2336
-			$cols = $arrivee[2];
2337
-			// mais on ignore la 3eme cle si presente qui correspond alors au point de depart
2338
-			if ((is_countable($cols) ? count($cols) : 0) > 2) {
2339
-				array_pop($cols);
2340
-			}
2341
-			if ($t) {
2342
-				// la table est déjà dans le FROM, on vérifie si le champ est utilisé.
2343
-				$joindre = false;
2344
-				foreach ($cols as $col) {
2345
-					$c = '/\b' . $t . ".$col" . '\b/';
2346
-					if (trouver_champ($c, $boucle->where)) {
2347
-						$joindre = true;
2348
-					} else {
2349
-						// mais ca peut etre dans le FIELD pour le Having
2350
-						$c = "/FIELD.$t" . ".$col,/";
2351
-						if (trouver_champ($c, $boucle->select)) {
2352
-							$joindre = true;
2353
-						}
2354
-					}
2355
-				}
2356
-				if (!$joindre) {
2357
-					return $t;
2358
-				}
2359
-			}
2360
-			array_pop($arrivee);
2361
-			if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) {
2362
-				return $res;
2363
-			}
2364
-		}
2365
-	}
2366
-
2367
-	return '';
2317
+    // si on demande un truc du genre spip_mots
2318
+    // avec aussi spip_mots_liens dans les jointures dispo
2319
+    // et qu'on est la
2320
+    // il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots
2321
+    if (
2322
+        $checkarrivee
2323
+        and is_string($checkarrivee)
2324
+        and $a = table_objet($checkarrivee)
2325
+        and in_array($a . '_liens', $joints)
2326
+    ) {
2327
+        if ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee)) {
2328
+            return $res;
2329
+        }
2330
+    }
2331
+    foreach ($joints as $joint) {
2332
+        if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) {
2333
+            // alias de table dans le from
2334
+            $t = array_search($arrivee[0], $boucle->from);
2335
+            // recuperer la cle id_xx eventuellement decomposee en (id_objet,objet)
2336
+            $cols = $arrivee[2];
2337
+            // mais on ignore la 3eme cle si presente qui correspond alors au point de depart
2338
+            if ((is_countable($cols) ? count($cols) : 0) > 2) {
2339
+                array_pop($cols);
2340
+            }
2341
+            if ($t) {
2342
+                // la table est déjà dans le FROM, on vérifie si le champ est utilisé.
2343
+                $joindre = false;
2344
+                foreach ($cols as $col) {
2345
+                    $c = '/\b' . $t . ".$col" . '\b/';
2346
+                    if (trouver_champ($c, $boucle->where)) {
2347
+                        $joindre = true;
2348
+                    } else {
2349
+                        // mais ca peut etre dans le FIELD pour le Having
2350
+                        $c = "/FIELD.$t" . ".$col,/";
2351
+                        if (trouver_champ($c, $boucle->select)) {
2352
+                            $joindre = true;
2353
+                        }
2354
+                    }
2355
+                }
2356
+                if (!$joindre) {
2357
+                    return $t;
2358
+                }
2359
+            }
2360
+            array_pop($arrivee);
2361
+            if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) {
2362
+                return $res;
2363
+            }
2364
+        }
2365
+    }
2366
+
2367
+    return '';
2368 2368
 }
2369 2369
 
2370 2370
 /**
@@ -2390,35 +2390,35 @@  discard block
 block discarded – undo
2390 2390
  *     Alias de la table de jointure (Lx)
2391 2391
  */
2392 2392
 function calculer_lien_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) {
2393
-	$primary_arrivee = id_table_objet($checkarrivee);
2394
-
2395
-	// [FIXME] $checkarrivee peut-il arriver avec false ????
2396
-	$intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens');
2397
-	$arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee);
2398
-
2399
-	if (!$intermediaire or !$arrivee) {
2400
-		return '';
2401
-	}
2402
-	array_pop($intermediaire); // enlever la cle en 3eme argument
2403
-	array_pop($arrivee); // enlever la cle en 3eme argument
2404
-
2405
-	$res = fabrique_jointures(
2406
-		$boucle,
2407
-		[
2408
-			[
2409
-				$boucle->id_table,
2410
-				$intermediaire,
2411
-				[id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']]
2412
-			],
2413
-			[reset($intermediaire), $arrivee, $primary_arrivee]
2414
-		],
2415
-		$cond,
2416
-		$desc,
2417
-		$boucle->id_table,
2418
-		[$col]
2419
-	);
2420
-
2421
-	return $res;
2393
+    $primary_arrivee = id_table_objet($checkarrivee);
2394
+
2395
+    // [FIXME] $checkarrivee peut-il arriver avec false ????
2396
+    $intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens');
2397
+    $arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee);
2398
+
2399
+    if (!$intermediaire or !$arrivee) {
2400
+        return '';
2401
+    }
2402
+    array_pop($intermediaire); // enlever la cle en 3eme argument
2403
+    array_pop($arrivee); // enlever la cle en 3eme argument
2404
+
2405
+    $res = fabrique_jointures(
2406
+        $boucle,
2407
+        [
2408
+            [
2409
+                $boucle->id_table,
2410
+                $intermediaire,
2411
+                [id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']]
2412
+            ],
2413
+            [reset($intermediaire), $arrivee, $primary_arrivee]
2414
+        ],
2415
+        $cond,
2416
+        $desc,
2417
+        $boucle->id_table,
2418
+        [$col]
2419
+    );
2420
+
2421
+    return $res;
2422 2422
 }
2423 2423
 
2424 2424
 
@@ -2435,17 +2435,17 @@  discard block
 block discarded – undo
2435 2435
  *     false sinon.
2436 2436
  **/
2437 2437
 function trouver_champ($champ, $where) {
2438
-	if (!is_array($where)) {
2439
-		return preg_match($champ, $where);
2440
-	} else {
2441
-		foreach ($where as $clause) {
2442
-			if (trouver_champ($champ, $clause)) {
2443
-				return true;
2444
-			}
2445
-		}
2446
-
2447
-		return false;
2448
-	}
2438
+    if (!is_array($where)) {
2439
+        return preg_match($champ, $where);
2440
+    } else {
2441
+        foreach ($where as $clause) {
2442
+            if (trouver_champ($champ, $clause)) {
2443
+                return true;
2444
+            }
2445
+        }
2446
+
2447
+        return false;
2448
+    }
2449 2449
 }
2450 2450
 
2451 2451
 
@@ -2471,129 +2471,129 @@  discard block
 block discarded – undo
2471 2471
  *     - string $args_sql  Suite des arguments du critère. ?
2472 2472
  **/
2473 2473
 function calculer_critere_infixe_ops($idb, &$boucles, $crit) {
2474
-	// cas d'une valeur comparee a elle-meme ou son referent
2475
-	if (count($crit->param) == 0) {
2476
-		$op = '=';
2477
-		$col = $val = $crit->op;
2478
-		if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2479
-			$val = $r[2];
2480
-		}
2481
-		// Cas special {lang} : aller chercher $GLOBALS['spip_lang']
2482
-		if ($val == 'lang') {
2483
-			$val = [kwote('$GLOBALS[\'spip_lang\']')];
2484
-		} else {
2485
-			$defaut = null;
2486
-			if ($val == 'id_parent') {
2487
-				// Si id_parent, comparer l'id_parent avec l'id_objet
2488
-				// de la boucle superieure.... faudrait verifier qu'il existe
2489
-				// pour eviter l'erreur SQL
2490
-				$val = $boucles[$idb]->primary;
2491
-				// mais si pas de boucle superieure, prendre id_parent dans l'env
2492
-				$defaut = "(\$Pile[0]['id_parent'] ?? null)";
2493
-			} elseif ($val == 'id_enfant') {
2494
-				// Si id_enfant, comparer l'id_objet avec l'id_parent
2495
-				// de la boucle superieure
2496
-				$val = 'id_parent';
2497
-			} elseif ($crit->cond and ($col == 'date' or $col == 'date_redac')) {
2498
-				// un critere conditionnel sur date est traite a part
2499
-				// car la date est mise d'office par SPIP,
2500
-				$defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])";
2501
-			}
2502
-
2503
-			$val = calculer_argument_precedent($idb, $val, $boucles, $defaut);
2504
-			$val = [kwote($val)];
2505
-		}
2506
-	} else {
2507
-		// comparaison explicite
2508
-		// le phraseur impose que le premier param soit du texte
2509
-		$params = $crit->param;
2510
-		$op = $crit->op;
2511
-		if ($op == '==') {
2512
-			$op = 'REGEXP';
2513
-		}
2514
-		$col = array_shift($params);
2515
-		$col = $col[0]->texte;
2516
-
2517
-		$val = [];
2518
-		$parent = $boucles[$idb]->id_parent;
2519
-
2520
-		// Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
2521
-		// celui ne sachant pas ce qu'est un critere infixe
2522
-		// et a fortiori son 2e operande qu'entoure " ou '
2523
-		if (
2524
-			count($params) == 1
2525
-			and (is_countable($params[0]) ? count($params[0]) : 0) == 3
2526
-			and $params[0][0]->type == 'texte'
2527
-			and $params[0][2]->type == 'texte'
2528
-			and ($p = $params[0][0]->texte) == $params[0][2]->texte
2529
-			and (($p == "'") or ($p == '"'))
2530
-			and $params[0][1]->type == 'champ'
2531
-		) {
2532
-			$val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p";
2533
-		} else {
2534
-			foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
2535
-				$a = calculer_liste($p, $idb, $boucles, $parent);
2536
-				if (strcasecmp($op, 'IN') == 0) {
2537
-					$val[] = $a;
2538
-				} else {
2539
-					$val[] = kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@');
2540
-				} // toujours quoter en char ici
2541
-			}
2542
-		}
2543
-	}
2544
-
2545
-	$fct = $args_sql = '';
2546
-	// fonction SQL ?
2547
-	// chercher FONCTION(champ) tel que CONCAT(titre,descriptif)
2548
-	if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) {
2549
-		$fct = $m[1];
2550
-		preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a);
2551
-		$col = $a[1];
2552
-		if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) {
2553
-			$col = $m[1];
2554
-			$args_sql = $m[2];
2555
-		}
2556
-		$args_sql .= $a[2];
2557
-	}
2558
-
2559
-	return [$fct, $col, $op, $val, $args_sql];
2474
+    // cas d'une valeur comparee a elle-meme ou son referent
2475
+    if (count($crit->param) == 0) {
2476
+        $op = '=';
2477
+        $col = $val = $crit->op;
2478
+        if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2479
+            $val = $r[2];
2480
+        }
2481
+        // Cas special {lang} : aller chercher $GLOBALS['spip_lang']
2482
+        if ($val == 'lang') {
2483
+            $val = [kwote('$GLOBALS[\'spip_lang\']')];
2484
+        } else {
2485
+            $defaut = null;
2486
+            if ($val == 'id_parent') {
2487
+                // Si id_parent, comparer l'id_parent avec l'id_objet
2488
+                // de la boucle superieure.... faudrait verifier qu'il existe
2489
+                // pour eviter l'erreur SQL
2490
+                $val = $boucles[$idb]->primary;
2491
+                // mais si pas de boucle superieure, prendre id_parent dans l'env
2492
+                $defaut = "(\$Pile[0]['id_parent'] ?? null)";
2493
+            } elseif ($val == 'id_enfant') {
2494
+                // Si id_enfant, comparer l'id_objet avec l'id_parent
2495
+                // de la boucle superieure
2496
+                $val = 'id_parent';
2497
+            } elseif ($crit->cond and ($col == 'date' or $col == 'date_redac')) {
2498
+                // un critere conditionnel sur date est traite a part
2499
+                // car la date est mise d'office par SPIP,
2500
+                $defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])";
2501
+            }
2502
+
2503
+            $val = calculer_argument_precedent($idb, $val, $boucles, $defaut);
2504
+            $val = [kwote($val)];
2505
+        }
2506
+    } else {
2507
+        // comparaison explicite
2508
+        // le phraseur impose que le premier param soit du texte
2509
+        $params = $crit->param;
2510
+        $op = $crit->op;
2511
+        if ($op == '==') {
2512
+            $op = 'REGEXP';
2513
+        }
2514
+        $col = array_shift($params);
2515
+        $col = $col[0]->texte;
2516
+
2517
+        $val = [];
2518
+        $parent = $boucles[$idb]->id_parent;
2519
+
2520
+        // Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
2521
+        // celui ne sachant pas ce qu'est un critere infixe
2522
+        // et a fortiori son 2e operande qu'entoure " ou '
2523
+        if (
2524
+            count($params) == 1
2525
+            and (is_countable($params[0]) ? count($params[0]) : 0) == 3
2526
+            and $params[0][0]->type == 'texte'
2527
+            and $params[0][2]->type == 'texte'
2528
+            and ($p = $params[0][0]->texte) == $params[0][2]->texte
2529
+            and (($p == "'") or ($p == '"'))
2530
+            and $params[0][1]->type == 'champ'
2531
+        ) {
2532
+            $val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p";
2533
+        } else {
2534
+            foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
2535
+                $a = calculer_liste($p, $idb, $boucles, $parent);
2536
+                if (strcasecmp($op, 'IN') == 0) {
2537
+                    $val[] = $a;
2538
+                } else {
2539
+                    $val[] = kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@');
2540
+                } // toujours quoter en char ici
2541
+            }
2542
+        }
2543
+    }
2544
+
2545
+    $fct = $args_sql = '';
2546
+    // fonction SQL ?
2547
+    // chercher FONCTION(champ) tel que CONCAT(titre,descriptif)
2548
+    if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) {
2549
+        $fct = $m[1];
2550
+        preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a);
2551
+        $col = $a[1];
2552
+        if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) {
2553
+            $col = $m[1];
2554
+            $args_sql = $m[2];
2555
+        }
2556
+        $args_sql .= $a[2];
2557
+    }
2558
+
2559
+    return [$fct, $col, $op, $val, $args_sql];
2560 2560
 }
2561 2561
 
2562 2562
 // compatibilite ancienne version
2563 2563
 
2564 2564
 function calculer_vieux_in($params) {
2565
-	$deb = $params[0][0];
2566
-	$k = (is_countable($params) ? count($params) : 0) - 1;
2567
-	$last = $params[$k];
2568
-	$j = (is_countable($last) ? count($last) : 0) - 1;
2569
-	$last = $last[$j];
2570
-	$n = isset($last->texte) ? strlen($last->texte) : 0;
2571
-
2572
-	if (
2573
-		!((isset($deb->texte[0]) and $deb->texte[0] == '(')
2574
-		&& (isset($last->texte[$n - 1]) and $last->texte[$n - 1] == ')'))
2575
-	) {
2576
-		return $params;
2577
-	}
2578
-	$params[0][0]->texte = substr($deb->texte, 1);
2579
-	// attention, on peut avoir k=0,j=0 ==> recalculer
2580
-	$last = $params[$k][$j];
2581
-	$n = strlen($last->texte);
2582
-	$params[$k][$j]->texte = substr($last->texte, 0, $n - 1);
2583
-	$newp = [];
2584
-	foreach ($params as $v) {
2585
-		if ($v[0]->type != 'texte') {
2586
-			$newp[] = $v;
2587
-		} else {
2588
-			foreach (explode(',', $v[0]->texte) as $x) {
2589
-				$t = new Texte();
2590
-				$t->texte = $x;
2591
-				$newp[] = [$t];
2592
-			}
2593
-		}
2594
-	}
2595
-
2596
-	return $newp;
2565
+    $deb = $params[0][0];
2566
+    $k = (is_countable($params) ? count($params) : 0) - 1;
2567
+    $last = $params[$k];
2568
+    $j = (is_countable($last) ? count($last) : 0) - 1;
2569
+    $last = $last[$j];
2570
+    $n = isset($last->texte) ? strlen($last->texte) : 0;
2571
+
2572
+    if (
2573
+        !((isset($deb->texte[0]) and $deb->texte[0] == '(')
2574
+        && (isset($last->texte[$n - 1]) and $last->texte[$n - 1] == ')'))
2575
+    ) {
2576
+        return $params;
2577
+    }
2578
+    $params[0][0]->texte = substr($deb->texte, 1);
2579
+    // attention, on peut avoir k=0,j=0 ==> recalculer
2580
+    $last = $params[$k][$j];
2581
+    $n = strlen($last->texte);
2582
+    $params[$k][$j]->texte = substr($last->texte, 0, $n - 1);
2583
+    $newp = [];
2584
+    foreach ($params as $v) {
2585
+        if ($v[0]->type != 'texte') {
2586
+            $newp[] = $v;
2587
+        } else {
2588
+            foreach (explode(',', $v[0]->texte) as $x) {
2589
+                $t = new Texte();
2590
+                $t->texte = $x;
2591
+                $newp[] = [$t];
2592
+            }
2593
+        }
2594
+    }
2595
+
2596
+    return $newp;
2597 2597
 }
2598 2598
 
2599 2599
 /**
@@ -2612,95 +2612,95 @@  discard block
 block discarded – undo
2612 2612
  *     - nom de la colonne de date (si le calcul n'est pas relatif)
2613 2613
  **/
2614 2614
 function calculer_critere_infixe_date($idb, &$boucles, $col) {
2615
-	if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) {
2616
-		return '';
2617
-	}
2618
-
2619
-	$boucle = $boucles[$idb];
2620
-	$table = $boucle->show;
2621
-
2622
-	// si c'est une colonne de la table, ne rien faire
2623
-	if (isset($table['field'][$col])) {
2624
-		return '';
2625
-	}
2626
-
2627
-	// Le type de critère à prendre en compte
2628
-	$col = $regs[1];
2629
-
2630
-	// Si on trouve un nom de champ date précis, on l'utilise, pas besoin de déclaration dans l'API objet
2631
-	if (isset($regs[3]) and $suite = $regs[3]) {
2632
-		# Recherche de l'existence du champ date_xxxx,
2633
-		# si oui choisir ce champ, sinon choisir xxxx
2634
-		if (isset($table['field']["date$suite"])) {
2635
-			$date_orig = 'date' . $suite;
2636
-		} else {
2637
-			$date_orig = substr($suite, 1);
2638
-		}
2639
-
2640
-		$pred = $date_orig;
2641
-	} else { // Sinon il FAUT avoir déclaré le champ date officiel dans l'API objet
2642
-		// Si aucune déclaration trouvée, on quitte
2643
-		if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) {
2644
-			return '';
2645
-		}
2646
-		// Par défaut, on prend le champ date déclaré dans l'API
2647
-		$pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date'];
2648
-
2649
-		// Si c'est pour du relatif
2650
-		if (isset($regs[2]) and $rel = $regs[2]) {
2651
-			$pred = 'date';
2652
-		}
2653
-	}
2654
-
2655
-	$date_compare = "\"' . normaliser_date(" .
2656
-		calculer_argument_precedent($idb, $pred, $boucles) .
2657
-		") . '\"";
2658
-
2659
-	$col_vraie = $date_orig;
2660
-	$date_orig = $boucle->id_table . '.' . $date_orig;
2661
-
2662
-	switch ($col) {
2663
-		case 'date':
2664
-			$col = $date_orig;
2665
-			break;
2666
-		case 'jour':
2667
-			$col = "DAYOFMONTH($date_orig)";
2668
-			break;
2669
-		case 'mois':
2670
-			$col = "MONTH($date_orig)";
2671
-			break;
2672
-		case 'annee':
2673
-			$col = "YEAR($date_orig)";
2674
-			break;
2675
-		case 'heure':
2676
-			$col = "DATE_FORMAT($date_orig, \\'%H:%i\\')";
2677
-			break;
2678
-		case 'age':
2679
-			$col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig);
2680
-			$col_vraie = '';// comparer a un int (par defaut)
2681
-			break;
2682
-		case 'age_relatif':
2683
-			$col = calculer_param_date($date_compare, $date_orig);
2684
-			$col_vraie = '';// comparer a un int (par defaut)
2685
-			break;
2686
-		case 'jour_relatif':
2687
-			$col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))';
2688
-			$col_vraie = '';// comparer a un int (par defaut)
2689
-			break;
2690
-		case 'mois_relatif':
2691
-			$col = 'MONTH(' . $date_compare . ')-MONTH(' .
2692
-				$date_orig . ')+12*(YEAR(' . $date_compare .
2693
-				')-YEAR(' . $date_orig . '))';
2694
-			$col_vraie = '';// comparer a un int (par defaut)
2695
-			break;
2696
-		case 'annee_relatif':
2697
-			$col = 'YEAR(' . $date_compare . ')-YEAR(' .
2698
-				$date_orig . ')';
2699
-			$col_vraie = '';// comparer a un int (par defaut)
2700
-			break;
2701
-	}
2702
-
2703
-	return [$col, $col_vraie];
2615
+    if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) {
2616
+        return '';
2617
+    }
2618
+
2619
+    $boucle = $boucles[$idb];
2620
+    $table = $boucle->show;
2621
+
2622
+    // si c'est une colonne de la table, ne rien faire
2623
+    if (isset($table['field'][$col])) {
2624
+        return '';
2625
+    }
2626
+
2627
+    // Le type de critère à prendre en compte
2628
+    $col = $regs[1];
2629
+
2630
+    // Si on trouve un nom de champ date précis, on l'utilise, pas besoin de déclaration dans l'API objet
2631
+    if (isset($regs[3]) and $suite = $regs[3]) {
2632
+        # Recherche de l'existence du champ date_xxxx,
2633
+        # si oui choisir ce champ, sinon choisir xxxx
2634
+        if (isset($table['field']["date$suite"])) {
2635
+            $date_orig = 'date' . $suite;
2636
+        } else {
2637
+            $date_orig = substr($suite, 1);
2638
+        }
2639
+
2640
+        $pred = $date_orig;
2641
+    } else { // Sinon il FAUT avoir déclaré le champ date officiel dans l'API objet
2642
+        // Si aucune déclaration trouvée, on quitte
2643
+        if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) {
2644
+            return '';
2645
+        }
2646
+        // Par défaut, on prend le champ date déclaré dans l'API
2647
+        $pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date'];
2648
+
2649
+        // Si c'est pour du relatif
2650
+        if (isset($regs[2]) and $rel = $regs[2]) {
2651
+            $pred = 'date';
2652
+        }
2653
+    }
2654
+
2655
+    $date_compare = "\"' . normaliser_date(" .
2656
+        calculer_argument_precedent($idb, $pred, $boucles) .
2657
+        ") . '\"";
2658
+
2659
+    $col_vraie = $date_orig;
2660
+    $date_orig = $boucle->id_table . '.' . $date_orig;
2661
+
2662
+    switch ($col) {
2663
+        case 'date':
2664
+            $col = $date_orig;
2665
+            break;
2666
+        case 'jour':
2667
+            $col = "DAYOFMONTH($date_orig)";
2668
+            break;
2669
+        case 'mois':
2670
+            $col = "MONTH($date_orig)";
2671
+            break;
2672
+        case 'annee':
2673
+            $col = "YEAR($date_orig)";
2674
+            break;
2675
+        case 'heure':
2676
+            $col = "DATE_FORMAT($date_orig, \\'%H:%i\\')";
2677
+            break;
2678
+        case 'age':
2679
+            $col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig);
2680
+            $col_vraie = '';// comparer a un int (par defaut)
2681
+            break;
2682
+        case 'age_relatif':
2683
+            $col = calculer_param_date($date_compare, $date_orig);
2684
+            $col_vraie = '';// comparer a un int (par defaut)
2685
+            break;
2686
+        case 'jour_relatif':
2687
+            $col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))';
2688
+            $col_vraie = '';// comparer a un int (par defaut)
2689
+            break;
2690
+        case 'mois_relatif':
2691
+            $col = 'MONTH(' . $date_compare . ')-MONTH(' .
2692
+                $date_orig . ')+12*(YEAR(' . $date_compare .
2693
+                ')-YEAR(' . $date_orig . '))';
2694
+            $col_vraie = '';// comparer a un int (par defaut)
2695
+            break;
2696
+        case 'annee_relatif':
2697
+            $col = 'YEAR(' . $date_compare . ')-YEAR(' .
2698
+                $date_orig . ')';
2699
+            $col_vraie = '';// comparer a un int (par defaut)
2700
+            break;
2701
+    }
2702
+
2703
+    return [$col, $col_vraie];
2704 2704
 }
2705 2705
 
2706 2706
 /**
@@ -2719,16 +2719,16 @@  discard block
 block discarded – undo
2719 2719
  *     de colonne SQL et une date.
2720 2720
  **/
2721 2721
 function calculer_param_date($date_compare, $date_orig) {
2722
-	if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) {
2723
-		$init = "'\" . (\$x = $r[1]) . \"'";
2724
-		$date_compare = '\'$x\'';
2725
-	} else {
2726
-		$init = $date_compare;
2727
-	}
2728
-
2729
-	return
2730
-		// optimisation : mais prevoir le support SQLite avant
2731
-		"TIMESTAMPDIFF(HOUR,$date_orig,$init)/24";
2722
+    if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) {
2723
+        $init = "'\" . (\$x = $r[1]) . \"'";
2724
+        $date_compare = '\'$x\'';
2725
+    } else {
2726
+        $init = $date_compare;
2727
+    }
2728
+
2729
+    return
2730
+        // optimisation : mais prevoir le support SQLite avant
2731
+        "TIMESTAMPDIFF(HOUR,$date_orig,$init)/24";
2732 2732
 }
2733 2733
 
2734 2734
 /**
@@ -2746,20 +2746,20 @@  discard block
 block discarded – undo
2746 2746
  * @param Critere $crit Paramètres du critère dans cette boucle
2747 2747
  */
2748 2748
 function critere_DATA_source_dist($idb, &$boucles, $crit) {
2749
-	$boucle = &$boucles[$idb];
2750
-
2751
-	$args = [];
2752
-	foreach ($crit->param as &$param) {
2753
-		array_push(
2754
-			$args,
2755
-			calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent)
2756
-		);
2757
-	}
2749
+    $boucle = &$boucles[$idb];
2758 2750
 
2759
-	$boucle->hash .= '
2751
+    $args = [];
2752
+    foreach ($crit->param as &$param) {
2753
+        array_push(
2754
+            $args,
2755
+            calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent)
2756
+        );
2757
+    }
2758
+
2759
+    $boucle->hash .= '
2760 2760
 	$command[\'sourcemode\'] = ' . array_shift($args) . ";\n";
2761 2761
 
2762
-	$boucle->hash .= '
2762
+    $boucle->hash .= '
2763 2763
 	$command[\'source\'] = array(' . join(', ', $args) . ");\n";
2764 2764
 }
2765 2765
 
@@ -2777,8 +2777,8 @@  discard block
 block discarded – undo
2777 2777
  * @param Critere $crit Paramètres du critère dans cette boucle
2778 2778
  */
2779 2779
 function critere_DATA_datacache_dist($idb, &$boucles, $crit) {
2780
-	$boucle = &$boucles[$idb];
2781
-	$boucle->hash .= '
2780
+    $boucle = &$boucles[$idb];
2781
+    $boucle->hash .= '
2782 2782
 	$command[\'datacache\'] = ' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2783 2783
 }
2784 2784
 
@@ -2794,12 +2794,12 @@  discard block
 block discarded – undo
2794 2794
  * @param Critere $crit Paramètres du critère dans cette boucle
2795 2795
  */
2796 2796
 function critere_php_args_dist($idb, &$boucles, $crit) {
2797
-	$boucle = &$boucles[$idb];
2798
-	$boucle->hash .= '$command[\'args\']=array();';
2799
-	foreach ($crit->param as $param) {
2800
-		$boucle->hash .= '
2797
+    $boucle = &$boucles[$idb];
2798
+    $boucle->hash .= '$command[\'args\']=array();';
2799
+    foreach ($crit->param as $param) {
2800
+        $boucle->hash .= '
2801 2801
 			$command[\'args\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2802
-	}
2802
+    }
2803 2803
 }
2804 2804
 
2805 2805
 /**
@@ -2816,16 +2816,16 @@  discard block
 block discarded – undo
2816 2816
  * @param Critere $crit Paramètres du critère dans cette boucle
2817 2817
  */
2818 2818
 function critere_DATA_liste_dist($idb, &$boucles, $crit) {
2819
-	$boucle = &$boucles[$idb];
2820
-	$boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n";
2821
-	foreach ($crit->param as $param) {
2822
-		$boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste(
2823
-			$param,
2824
-			$idb,
2825
-			$boucles,
2826
-			$boucles[$idb]->id_parent
2827
-		) . ";\n";
2828
-	}
2819
+    $boucle = &$boucles[$idb];
2820
+    $boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n";
2821
+    foreach ($crit->param as $param) {
2822
+        $boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste(
2823
+            $param,
2824
+            $idb,
2825
+            $boucles,
2826
+            $boucles[$idb]->id_parent
2827
+        ) . ";\n";
2828
+    }
2829 2829
 }
2830 2830
 
2831 2831
 /**
@@ -2850,16 +2850,16 @@  discard block
 block discarded – undo
2850 2850
  * @param Critere $crit Paramètres du critère dans cette boucle
2851 2851
  */
2852 2852
 function critere_DATA_enum_dist($idb, &$boucles, $crit) {
2853
-	$boucle = &$boucles[$idb];
2854
-	$boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n";
2855
-	foreach ($crit->param as $param) {
2856
-		$boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste(
2857
-			$param,
2858
-			$idb,
2859
-			$boucles,
2860
-			$boucles[$idb]->id_parent
2861
-		) . ";\n";
2862
-	}
2853
+    $boucle = &$boucles[$idb];
2854
+    $boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n";
2855
+    foreach ($crit->param as $param) {
2856
+        $boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste(
2857
+            $param,
2858
+            $idb,
2859
+            $boucles,
2860
+            $boucles[$idb]->id_parent
2861
+        ) . ";\n";
2862
+    }
2863 2863
 }
2864 2864
 
2865 2865
 /**
@@ -2874,11 +2874,11 @@  discard block
 block discarded – undo
2874 2874
  * @param Critere $crit Paramètres du critère dans cette boucle
2875 2875
  */
2876 2876
 function critere_DATA_datapath_dist($idb, &$boucles, $crit) {
2877
-	$boucle = &$boucles[$idb];
2878
-	foreach ($crit->param as $param) {
2879
-		$boucle->hash .= '
2877
+    $boucle = &$boucles[$idb];
2878
+    foreach ($crit->param as $param) {
2879
+        $boucle->hash .= '
2880 2880
 			$command[\'datapath\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2881
-	}
2881
+    }
2882 2882
 }
2883 2883
 
2884 2884
 
@@ -2910,20 +2910,20 @@  discard block
 block discarded – undo
2910 2910
  * @param Critere $crit Paramètres du critère dans cette boucle
2911 2911
  */
2912 2912
 function critere_si_dist($idb, &$boucles, $crit) {
2913
-	$boucle = &$boucles[$idb];
2914
-	// il faut initialiser 1 fois le tableau a chaque appel de la boucle
2915
-	// (par exemple lorsque notre boucle est appelee dans une autre boucle)
2916
-	// mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle !
2917
-	$boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
2918
-	if ($crit->param) {
2919
-		foreach ($crit->param as $param) {
2920
-			$boucle->hash .= "\t\$command['si'][] = "
2921
-				. calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n";
2922
-		}
2923
-		// interdire {si 0} aussi !
2924
-	} else {
2925
-		$boucle->hash .= '$command[\'si\'][] = 0;';
2926
-	}
2913
+    $boucle = &$boucles[$idb];
2914
+    // il faut initialiser 1 fois le tableau a chaque appel de la boucle
2915
+    // (par exemple lorsque notre boucle est appelee dans une autre boucle)
2916
+    // mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle !
2917
+    $boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
2918
+    if ($crit->param) {
2919
+        foreach ($crit->param as $param) {
2920
+            $boucle->hash .= "\t\$command['si'][] = "
2921
+                . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n";
2922
+        }
2923
+        // interdire {si 0} aussi !
2924
+    } else {
2925
+        $boucle->hash .= '$command[\'si\'][] = 0;';
2926
+    }
2927 2927
 }
2928 2928
 
2929 2929
 /**
@@ -2940,8 +2940,8 @@  discard block
 block discarded – undo
2940 2940
  * @param Critere $crit Paramètres du critère dans cette boucle
2941 2941
  */
2942 2942
 function critere_POUR_tableau_dist($idb, &$boucles, $crit) {
2943
-	$boucle = &$boucles[$idb];
2944
-	$boucle->hash .= '
2943
+    $boucle = &$boucles[$idb];
2944
+    $boucle->hash .= '
2945 2945
 	$command[\'source\'] = array(' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent) . ');
2946 2946
 	$command[\'sourcemode\'] = \'table\';';
2947 2947
 }
@@ -2962,27 +2962,27 @@  discard block
 block discarded – undo
2962 2962
  */
2963 2963
 function critere_noeud_dist($idb, &$boucles, $crit) {
2964 2964
 
2965
-	$not = $crit->not;
2966
-	$boucle = &$boucles[$idb];
2967
-	$primary = $boucle->primary;
2965
+    $not = $crit->not;
2966
+    $boucle = &$boucles[$idb];
2967
+    $primary = $boucle->primary;
2968 2968
 
2969
-	if (!$primary or strpos($primary, ',')) {
2970
-		erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle);
2969
+    if (!$primary or strpos($primary, ',')) {
2970
+        erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle);
2971 2971
 
2972
-		return;
2973
-	}
2974
-	$table = $boucle->type_requete;
2975
-	$table_sql = table_objet_sql(objet_type($table));
2972
+        return;
2973
+    }
2974
+    $table = $boucle->type_requete;
2975
+    $table_sql = table_objet_sql(objet_type($table));
2976 2976
 
2977
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
2977
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
2978 2978
 
2979
-	$in = 'IN';
2980
-	$where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"];
2981
-	if ($not) {
2982
-		$where = ["'NOT'", $where];
2983
-	}
2979
+    $in = 'IN';
2980
+    $where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"];
2981
+    if ($not) {
2982
+        $where = ["'NOT'", $where];
2983
+    }
2984 2984
 
2985
-	$boucle->where[] = $where;
2985
+    $boucle->where[] = $where;
2986 2986
 }
2987 2987
 
2988 2988
 /**
@@ -2998,8 +2998,8 @@  discard block
 block discarded – undo
2998 2998
  * @param Critere $crit Paramètres du critère dans cette boucle
2999 2999
  */
3000 3000
 function critere_feuille_dist($idb, &$boucles, $crit) {
3001
-	$not = $crit->not;
3002
-	$crit->not = $not ? false : true;
3003
-	critere_noeud_dist($idb, $boucles, $crit);
3004
-	$crit->not = $not;
3001
+    $not = $crit->not;
3002
+    $crit->not = $not ? false : true;
3003
+    critere_noeud_dist($idb, $boucles, $crit);
3004
+    $crit->not = $not;
3005 3005
 }
Please login to merge, or discard this patch.
ecrire/inc_version.php 2 patches
Indentation   +213 added lines, -213 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
 /**
@@ -39,15 +39,15 @@  discard block
 block discarded – undo
39 39
 define('_PHP_MAX', '8.2.99');
40 40
 
41 41
 if (!defined('_DIR_RESTREINT_ABS')) {
42
-	/** le nom du repertoire ecrire/ */
43
-	define('_DIR_RESTREINT_ABS', 'ecrire/');
42
+    /** le nom du repertoire ecrire/ */
43
+    define('_DIR_RESTREINT_ABS', 'ecrire/');
44 44
 }
45 45
 
46 46
 /** Chemin relatif pour aller dans ecrire
47 47
  *  vide si on est dans ecrire, 'ecrire/' sinon */
48 48
 define(
49
-	'_DIR_RESTREINT',
50
-	(!is_dir(_DIR_RESTREINT_ABS) ? '' : _DIR_RESTREINT_ABS)
49
+    '_DIR_RESTREINT',
50
+    (!is_dir(_DIR_RESTREINT_ABS) ? '' : _DIR_RESTREINT_ABS)
51 51
 );
52 52
 
53 53
 /** Chemin relatif pour aller à la racine */
@@ -62,8 +62,8 @@  discard block
 block discarded – undo
62 62
 
63 63
 // Icones
64 64
 if (!defined('_NOM_IMG_PACK')) {
65
-	/** Nom du dossier images */
66
-	define('_NOM_IMG_PACK', 'images/');
65
+    /** Nom du dossier images */
66
+    define('_NOM_IMG_PACK', 'images/');
67 67
 }
68 68
 /** le chemin http (relatif) vers les images standard */
69 69
 define('_DIR_IMG_PACK', (_DIR_RACINE . 'prive/' . _NOM_IMG_PACK));
@@ -72,8 +72,8 @@  discard block
 block discarded – undo
72 72
 define('_ROOT_IMG_PACK', dirname(__DIR__) . '/prive/' . _NOM_IMG_PACK);
73 73
 
74 74
 if (!defined('_JAVASCRIPT')) {
75
-	/** Nom du repertoire des  bibliotheques JavaScript */
76
-	define('_JAVASCRIPT', 'javascript/');
75
+    /** Nom du repertoire des  bibliotheques JavaScript */
76
+    define('_JAVASCRIPT', 'javascript/');
77 77
 } // utilisable avec #CHEMIN et find_in_path
78 78
 /** le nom du repertoire des  bibliotheques JavaScript du prive */
79 79
 define('_DIR_JAVASCRIPT', (_DIR_RACINE . 'prive/' . _JAVASCRIPT));
@@ -83,47 +83,47 @@  discard block
 block discarded – undo
83 83
 # mais on peut les mettre ailleurs et changer completement les noms
84 84
 
85 85
 if (!defined('_NOM_TEMPORAIRES_INACCESSIBLES')) {
86
-	/** Nom du repertoire des fichiers Temporaires Inaccessibles par http:// */
87
-	define('_NOM_TEMPORAIRES_INACCESSIBLES', 'tmp/');
86
+    /** Nom du repertoire des fichiers Temporaires Inaccessibles par http:// */
87
+    define('_NOM_TEMPORAIRES_INACCESSIBLES', 'tmp/');
88 88
 }
89 89
 if (!defined('_NOM_TEMPORAIRES_ACCESSIBLES')) {
90
-	/** Nom du repertoire des fichiers Temporaires Accessibles par http:// */
91
-	define('_NOM_TEMPORAIRES_ACCESSIBLES', 'local/');
90
+    /** Nom du repertoire des fichiers Temporaires Accessibles par http:// */
91
+    define('_NOM_TEMPORAIRES_ACCESSIBLES', 'local/');
92 92
 }
93 93
 if (!defined('_NOM_PERMANENTS_INACCESSIBLES')) {
94
-	/** Nom du repertoire des fichiers Permanents Inaccessibles par http:// */
95
-	define('_NOM_PERMANENTS_INACCESSIBLES', 'config/');
94
+    /** Nom du repertoire des fichiers Permanents Inaccessibles par http:// */
95
+    define('_NOM_PERMANENTS_INACCESSIBLES', 'config/');
96 96
 }
97 97
 if (!defined('_NOM_PERMANENTS_ACCESSIBLES')) {
98
-	/** Nom du repertoire des fichiers Permanents Accessibles par http:// */
99
-	define('_NOM_PERMANENTS_ACCESSIBLES', 'IMG/');
98
+    /** Nom du repertoire des fichiers Permanents Accessibles par http:// */
99
+    define('_NOM_PERMANENTS_ACCESSIBLES', 'IMG/');
100 100
 }
101 101
 
102 102
 
103 103
 /** Le nom du fichier de personnalisation */
104 104
 if (!defined('_NOM_CONFIG')) {
105
-	define('_NOM_CONFIG', 'mes_options');
105
+    define('_NOM_CONFIG', 'mes_options');
106 106
 }
107 107
 
108 108
 // Son emplacement absolu si on le trouve
109 109
 if (
110
-	@file_exists($f = _ROOT_RACINE . _NOM_PERMANENTS_INACCESSIBLES . _NOM_CONFIG . '.php')
111
-	or (@file_exists($f = _ROOT_RESTREINT . _NOM_CONFIG . '.php'))
110
+    @file_exists($f = _ROOT_RACINE . _NOM_PERMANENTS_INACCESSIBLES . _NOM_CONFIG . '.php')
111
+    or (@file_exists($f = _ROOT_RESTREINT . _NOM_CONFIG . '.php'))
112 112
 ) {
113
-	/** Emplacement absolu du fichier d'option */
114
-	define('_FILE_OPTIONS', $f);
113
+    /** Emplacement absolu du fichier d'option */
114
+    define('_FILE_OPTIONS', $f);
115 115
 } else {
116
-	define('_FILE_OPTIONS', '');
116
+    define('_FILE_OPTIONS', '');
117 117
 }
118 118
 
119 119
 if (!defined('MODULES_IDIOMES')) {
120
-	/**
121
-	 * Modules par défaut pour la traduction.
122
-	 *
123
-	 * Constante utilisée par le compilateur et le décompilateur
124
-	 * sa valeur etant traitée par inc_traduire_dist
125
-	 */
126
-	define('MODULES_IDIOMES', 'public|spip|ecrire');
120
+    /**
121
+     * Modules par défaut pour la traduction.
122
+     *
123
+     * Constante utilisée par le compilateur et le décompilateur
124
+     * sa valeur etant traitée par inc_traduire_dist
125
+     */
126
+    define('MODULES_IDIOMES', 'public|spip|ecrire');
127 127
 }
128 128
 
129 129
 // *** Fin des define *** //
@@ -131,10 +131,10 @@  discard block
 block discarded – undo
131 131
 
132 132
 // inclure l'ecran de securite
133 133
 if (
134
-	!defined('_ECRAN_SECURITE')
135
-	and @file_exists($f = _ROOT_RACINE . _NOM_PERMANENTS_INACCESSIBLES . 'ecran_securite.php')
134
+    !defined('_ECRAN_SECURITE')
135
+    and @file_exists($f = _ROOT_RACINE . _NOM_PERMANENTS_INACCESSIBLES . 'ecran_securite.php')
136 136
 ) {
137
-	include $f;
137
+    include $f;
138 138
 }
139 139
 
140 140
 
@@ -142,30 +142,30 @@  discard block
 block discarded – undo
142 142
  * Détecteur de robot d'indexation
143 143
  */
144 144
 if (!defined('_IS_BOT')) {
145
-	define(
146
-		'_IS_BOT',
147
-		isset($_SERVER['HTTP_USER_AGENT'])
148
-		and preg_match(
149
-			// mots generiques
150
-			',bot|slurp|crawler|spider|webvac|yandex|'
151
-			// MSIE 6.0 est un botnet 99,9% du temps, on traite donc ce USER_AGENT comme un bot
152
-			. 'MSIE 6\.0|'
153
-			// UA plus cibles
154
-			. '80legs|accoona|AltaVista|ASPSeek|Baidu|Charlotte|EC2LinkFinder|eStyle|facebook|flipboard|hootsuite|FunWebProducts|Google|Genieo|INA dlweb|InfegyAtlas|Java VM|LiteFinder|Lycos|MetaURI|Moreover|Rambler|Scooter|ScrubbyBloglines|Yahoo|Yeti'
155
-			. ',i',
156
-			(string)$_SERVER['HTTP_USER_AGENT']
157
-		)
158
-	);
145
+    define(
146
+        '_IS_BOT',
147
+        isset($_SERVER['HTTP_USER_AGENT'])
148
+        and preg_match(
149
+            // mots generiques
150
+            ',bot|slurp|crawler|spider|webvac|yandex|'
151
+            // MSIE 6.0 est un botnet 99,9% du temps, on traite donc ce USER_AGENT comme un bot
152
+            . 'MSIE 6\.0|'
153
+            // UA plus cibles
154
+            . '80legs|accoona|AltaVista|ASPSeek|Baidu|Charlotte|EC2LinkFinder|eStyle|facebook|flipboard|hootsuite|FunWebProducts|Google|Genieo|INA dlweb|InfegyAtlas|Java VM|LiteFinder|Lycos|MetaURI|Moreover|Rambler|Scooter|ScrubbyBloglines|Yahoo|Yeti'
155
+            . ',i',
156
+            (string)$_SERVER['HTTP_USER_AGENT']
157
+        )
158
+    );
159 159
 }
160 160
 
161 161
 if (!defined('_IS_CLI')) {
162
-	define(
163
-		'_IS_CLI',
164
-		!isset($_SERVER['HTTP_HOST'])
165
-		and !strlen($_SERVER['DOCUMENT_ROOT'])
166
-		and !empty($_SERVER['argv'])
167
-		and empty($_SERVER['REQUEST_METHOD'])
168
-	);
162
+    define(
163
+        '_IS_CLI',
164
+        !isset($_SERVER['HTTP_HOST'])
165
+        and !strlen($_SERVER['DOCUMENT_ROOT'])
166
+        and !empty($_SERVER['argv'])
167
+        and empty($_SERVER['REQUEST_METHOD'])
168
+    );
169 169
 }
170 170
 
171 171
 // *** Parametrage par defaut de SPIP ***
@@ -177,61 +177,61 @@  discard block
 block discarded – undo
177 177
 // Ne pas les rendre indefinies.
178 178
 
179 179
 global
180
-	$nombre_de_logs,
181
-	$taille_des_logs,
182
-	$table_prefix,
183
-	$cookie_prefix,
184
-	$dossier_squelettes,
185
-	$filtrer_javascript,
186
-	$type_urls,
187
-	$debut_date_publication,
188
-	$ip,
189
-	$mysql_rappel_connexion,
190
-	$mysql_rappel_nom_base,
191
-	$test_i18n,
192
-	$ignore_auth_http,
193
-	$ignore_remote_user,
194
-	$derniere_modif_invalide,
195
-	$home_server,
196
-	$help_server,
197
-	$url_glossaire_externe,
198
-	$tex_server,
199
-	$traiter_math,
200
-	$xhtml,
201
-	$xml_indent,
202
-	$source_vignettes,
203
-	$formats_logos,
204
-	$controler_dates_rss,
205
-	$spip_pipeline,
206
-	$spip_matrice,
207
-	$plugins,
208
-	$surcharges,
209
-	$exceptions_des_tables,
210
-	$tables_principales,
211
-	$table_des_tables,
212
-	$tables_auxiliaires,
213
-	$table_primary,
214
-	$table_date,
215
-	$table_titre,
216
-	$tables_jointures,
217
-	$liste_des_statuts,
218
-	$liste_des_etats,
219
-	$liste_des_authentifications,
220
-	$spip_version_branche,
221
-	$spip_version_code,
222
-	$spip_version_base,
223
-	$spip_sql_version,
224
-	$spip_version_affichee,
225
-	$visiteur_session,
226
-	$auteur_session,
227
-	$connect_statut,
228
-	$connect_toutes_rubriques,
229
-	$hash_recherche,
230
-	$hash_recherche_strict,
231
-	$ldap_present,
232
-	$meta,
233
-	$connect_id_rubrique,
234
-	$puce;
180
+    $nombre_de_logs,
181
+    $taille_des_logs,
182
+    $table_prefix,
183
+    $cookie_prefix,
184
+    $dossier_squelettes,
185
+    $filtrer_javascript,
186
+    $type_urls,
187
+    $debut_date_publication,
188
+    $ip,
189
+    $mysql_rappel_connexion,
190
+    $mysql_rappel_nom_base,
191
+    $test_i18n,
192
+    $ignore_auth_http,
193
+    $ignore_remote_user,
194
+    $derniere_modif_invalide,
195
+    $home_server,
196
+    $help_server,
197
+    $url_glossaire_externe,
198
+    $tex_server,
199
+    $traiter_math,
200
+    $xhtml,
201
+    $xml_indent,
202
+    $source_vignettes,
203
+    $formats_logos,
204
+    $controler_dates_rss,
205
+    $spip_pipeline,
206
+    $spip_matrice,
207
+    $plugins,
208
+    $surcharges,
209
+    $exceptions_des_tables,
210
+    $tables_principales,
211
+    $table_des_tables,
212
+    $tables_auxiliaires,
213
+    $table_primary,
214
+    $table_date,
215
+    $table_titre,
216
+    $tables_jointures,
217
+    $liste_des_statuts,
218
+    $liste_des_etats,
219
+    $liste_des_authentifications,
220
+    $spip_version_branche,
221
+    $spip_version_code,
222
+    $spip_version_base,
223
+    $spip_sql_version,
224
+    $spip_version_affichee,
225
+    $visiteur_session,
226
+    $auteur_session,
227
+    $connect_statut,
228
+    $connect_toutes_rubriques,
229
+    $hash_recherche,
230
+    $hash_recherche_strict,
231
+    $ldap_present,
232
+    $meta,
233
+    $connect_id_rubrique,
234
+    $puce;
235 235
 
236 236
 # comment on logge, defaut 4 tmp/spip.log de 100k, 0 ou 0 suppriment le log
237 237
 $nombre_de_logs = 4;
@@ -286,48 +286,48 @@  discard block
 block discarded – undo
286 286
 // Prendre en compte les entetes HTTP_X_FORWARDED_XX
287 287
 //
288 288
 if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
289
-	if (empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
290
-		$_SERVER['HTTP_X_FORWARDED_HOST'] = $_SERVER['HTTP_HOST'];
291
-	}
292
-	if (empty($_SERVER['HTTP_X_FORWARDED_PORT'])) {
293
-		$_SERVER['HTTP_X_FORWARDED_PORT'] = 443;
294
-	}
289
+    if (empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
290
+        $_SERVER['HTTP_X_FORWARDED_HOST'] = $_SERVER['HTTP_HOST'];
291
+    }
292
+    if (empty($_SERVER['HTTP_X_FORWARDED_PORT'])) {
293
+        $_SERVER['HTTP_X_FORWARDED_PORT'] = 443;
294
+    }
295 295
 }
296 296
 if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
297
-	if (isset($_SERVER['HTTP_X_FORWARDED_PORT']) and is_numeric($_SERVER['HTTP_X_FORWARDED_PORT'])) {
298
-		$_SERVER['SERVER_PORT'] = $_SERVER['HTTP_X_FORWARDED_PORT'];
299
-		if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
300
-			$_SERVER['HTTPS'] = 'on';
301
-			if (isset($_SERVER['REQUEST_SCHEME'])) {
302
-				$_SERVER['REQUEST_SCHEME'] = 'https';
303
-			}
304
-		}
305
-	}
306
-	$host = $_SERVER['HTTP_X_FORWARDED_HOST'];
307
-	if (strpos($host, ',') !== false) {
308
-		$h = explode(',', $host);
309
-		$host = trim(reset($h));
310
-	}
311
-	// securite sur le contenu de l'entete
312
-	$host = strtr($host, "<>?\"\{\}\$'` \r\n", '____________');
313
-	$_SERVER['HTTP_HOST'] = $host;
297
+    if (isset($_SERVER['HTTP_X_FORWARDED_PORT']) and is_numeric($_SERVER['HTTP_X_FORWARDED_PORT'])) {
298
+        $_SERVER['SERVER_PORT'] = $_SERVER['HTTP_X_FORWARDED_PORT'];
299
+        if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
300
+            $_SERVER['HTTPS'] = 'on';
301
+            if (isset($_SERVER['REQUEST_SCHEME'])) {
302
+                $_SERVER['REQUEST_SCHEME'] = 'https';
303
+            }
304
+        }
305
+    }
306
+    $host = $_SERVER['HTTP_X_FORWARDED_HOST'];
307
+    if (strpos($host, ',') !== false) {
308
+        $h = explode(',', $host);
309
+        $host = trim(reset($h));
310
+    }
311
+    // securite sur le contenu de l'entete
312
+    $host = strtr($host, "<>?\"\{\}\$'` \r\n", '____________');
313
+    $_SERVER['HTTP_HOST'] = $host;
314 314
 }
315 315
 //
316 316
 // On note le numero IP du client dans la variable $ip
317 317
 //
318 318
 if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
319
-	$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
320
-	if (strpos($ip, ',') !== false) {
321
-		$ip = explode(',', $ip);
322
-		$ip = reset($ip);
323
-	}
324
-	// ecraser $_SERVER['REMOTE_ADDR'] si elle est en localhost
325
-	if (isset($_SERVER['REMOTE_ADDR']) and $_SERVER['REMOTE_ADDR'] === '127.0.0.1') {
326
-		$_SERVER['REMOTE_ADDR'] = $ip;
327
-	}
319
+    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
320
+    if (strpos($ip, ',') !== false) {
321
+        $ip = explode(',', $ip);
322
+        $ip = reset($ip);
323
+    }
324
+    // ecraser $_SERVER['REMOTE_ADDR'] si elle est en localhost
325
+    if (isset($_SERVER['REMOTE_ADDR']) and $_SERVER['REMOTE_ADDR'] === '127.0.0.1') {
326
+        $_SERVER['REMOTE_ADDR'] = $ip;
327
+    }
328 328
 }
329 329
 if (isset($_SERVER['REMOTE_ADDR'])) {
330
-	$ip = $_SERVER['REMOTE_ADDR'];
330
+    $ip = $_SERVER['REMOTE_ADDR'];
331 331
 }
332 332
 
333 333
 // Pour renforcer la privacy, decommentez la ligne ci-dessous (ou recopiez-la
@@ -412,24 +412,24 @@  discard block
 block discarded – undo
412 412
 
413 413
 // Liste des statuts.
414 414
 $liste_des_statuts = [
415
-	'info_administrateurs' => '0minirezo',
416
-	'info_redacteurs' => '1comite',
417
-	'info_visiteurs' => '6forum',
418
-	'texte_statut_poubelle' => '5poubelle'
415
+    'info_administrateurs' => '0minirezo',
416
+    'info_redacteurs' => '1comite',
417
+    'info_visiteurs' => '6forum',
418
+    'texte_statut_poubelle' => '5poubelle'
419 419
 ];
420 420
 
421 421
 $liste_des_etats = [
422
-	'texte_statut_en_cours_redaction' => 'prepa',
423
-	'texte_statut_propose_evaluation' => 'prop',
424
-	'texte_statut_publie' => 'publie',
425
-	'texte_statut_poubelle' => 'poubelle',
426
-	'texte_statut_refuse' => 'refuse'
422
+    'texte_statut_en_cours_redaction' => 'prepa',
423
+    'texte_statut_propose_evaluation' => 'prop',
424
+    'texte_statut_publie' => 'publie',
425
+    'texte_statut_poubelle' => 'poubelle',
426
+    'texte_statut_refuse' => 'refuse'
427 427
 ];
428 428
 
429 429
 // liste des methodes d'authentifications
430 430
 $liste_des_authentifications = [
431
-	'spip' => 'spip',
432
-	'ldap' => 'ldap'
431
+    'spip' => 'spip',
432
+    'ldap' => 'ldap'
433 433
 ];
434 434
 
435 435
 // Experimental : pour supprimer systematiquement l'affichage des numeros
@@ -479,12 +479,12 @@  discard block
 block discarded – undo
479 479
 // Definition personnelles eventuelles
480 480
 
481 481
 if (_FILE_OPTIONS) {
482
-	include_once _FILE_OPTIONS;
482
+    include_once _FILE_OPTIONS;
483 483
 }
484 484
 
485 485
 if (!defined('SPIP_ERREUR_REPORT')) {
486
-	/** Masquer les warning */
487
-	define('SPIP_ERREUR_REPORT', E_ALL ^ E_NOTICE ^ E_DEPRECATED);
486
+    /** Masquer les warning */
487
+    define('SPIP_ERREUR_REPORT', E_ALL ^ E_NOTICE ^ E_DEPRECATED);
488 488
 }
489 489
 error_reporting(SPIP_ERREUR_REPORT);
490 490
 
@@ -497,10 +497,10 @@  discard block
 block discarded – undo
497 497
 // ===> on execute en neutralisant les messages d'erreur
498 498
 
499 499
 spip_initialisation_core(
500
-	(_DIR_RACINE . _NOM_PERMANENTS_INACCESSIBLES),
501
-	(_DIR_RACINE . _NOM_PERMANENTS_ACCESSIBLES),
502
-	(_DIR_RACINE . _NOM_TEMPORAIRES_INACCESSIBLES),
503
-	(_DIR_RACINE . _NOM_TEMPORAIRES_ACCESSIBLES)
500
+    (_DIR_RACINE . _NOM_PERMANENTS_INACCESSIBLES),
501
+    (_DIR_RACINE . _NOM_PERMANENTS_ACCESSIBLES),
502
+    (_DIR_RACINE . _NOM_TEMPORAIRES_INACCESSIBLES),
503
+    (_DIR_RACINE . _NOM_TEMPORAIRES_ACCESSIBLES)
504 504
 );
505 505
 
506 506
 
@@ -510,70 +510,70 @@  discard block
 block discarded – undo
510 510
 // donc il faut avoir tout fini ici avant de charger les plugins
511 511
 
512 512
 if (@is_readable(_CACHE_PLUGINS_OPT) and @is_readable(_CACHE_PLUGINS_PATH)) {
513
-	// chargement optimise precompile
514
-	include_once(_CACHE_PLUGINS_OPT);
513
+    // chargement optimise precompile
514
+    include_once(_CACHE_PLUGINS_OPT);
515 515
 } else {
516
-	spip_initialisation_suite();
517
-	include_spip('inc/plugin');
518
-	// generer les fichiers php precompiles
519
-	// de chargement des plugins et des pipelines
520
-	actualise_plugins_actifs();
516
+    spip_initialisation_suite();
517
+    include_spip('inc/plugin');
518
+    // generer les fichiers php precompiles
519
+    // de chargement des plugins et des pipelines
520
+    actualise_plugins_actifs();
521 521
 }
522 522
 
523 523
 // Initialisations non critiques surchargeables par les plugins
524 524
 spip_initialisation_suite();
525 525
 
526 526
 if (!defined('_LOG_FILTRE_GRAVITE')) {
527
-	/** niveau maxi d'enregistrement des logs */
528
-	define('_LOG_FILTRE_GRAVITE', _LOG_INFO_IMPORTANTE);
527
+    /** niveau maxi d'enregistrement des logs */
528
+    define('_LOG_FILTRE_GRAVITE', _LOG_INFO_IMPORTANTE);
529 529
 }
530 530
 
531 531
 if (!defined('_OUTILS_DEVELOPPEURS')) {
532
-	/** Activer des outils pour développeurs ? */
533
-	define('_OUTILS_DEVELOPPEURS', false);
532
+    /** Activer des outils pour développeurs ? */
533
+    define('_OUTILS_DEVELOPPEURS', false);
534 534
 }
535 535
 
536 536
 // charger systematiquement inc/autoriser dans l'espace restreint
537 537
 if (test_espace_prive()) {
538
-	include_spip('inc/autoriser');
538
+    include_spip('inc/autoriser');
539 539
 }
540 540
 //
541 541
 // Installer Spip si pas installe... sauf si justement on est en train
542 542
 //
543 543
 if (
544
-	!(_FILE_CONNECT
545
-	or autoriser_sans_cookie(_request('exec'))
546
-	or _request('action') == 'cookie'
547
-	or _request('action') == 'converser'
548
-	or _request('action') == 'test_dirs')
544
+    !(_FILE_CONNECT
545
+    or autoriser_sans_cookie(_request('exec'))
546
+    or _request('action') == 'cookie'
547
+    or _request('action') == 'converser'
548
+    or _request('action') == 'test_dirs')
549 549
 ) {
550
-	// Si on peut installer, on lance illico
551
-	if (test_espace_prive()) {
552
-		include_spip('inc/headers');
553
-		redirige_url_ecrire('install');
554
-	} else {
555
-		// Si on est dans le site public, dire que qq s'en occupe
556
-		include_spip('inc/minipres');
557
-		utiliser_langue_visiteur();
558
-		echo minipres(_T('info_travaux_titre'), "<p style='text-align: center;'>" . _T('info_travaux_texte') . '</p>', ['status' => 503]);
559
-		exit;
560
-	}
561
-	// autrement c'est une install ad hoc (spikini...), on sait pas faire
550
+    // Si on peut installer, on lance illico
551
+    if (test_espace_prive()) {
552
+        include_spip('inc/headers');
553
+        redirige_url_ecrire('install');
554
+    } else {
555
+        // Si on est dans le site public, dire que qq s'en occupe
556
+        include_spip('inc/minipres');
557
+        utiliser_langue_visiteur();
558
+        echo minipres(_T('info_travaux_titre'), "<p style='text-align: center;'>" . _T('info_travaux_texte') . '</p>', ['status' => 503]);
559
+        exit;
560
+    }
561
+    // autrement c'est une install ad hoc (spikini...), on sait pas faire
562 562
 }
563 563
 
564 564
 // memoriser un tri sessionne eventuel
565 565
 if (
566
-	isset($_REQUEST['var_memotri'])
567
-	and $t = $_REQUEST['var_memotri']
568
-	and (strncmp($t, 'trisession', 10) == 0 or strncmp($t, 'senssession', 11) == 0)
566
+    isset($_REQUEST['var_memotri'])
567
+    and $t = $_REQUEST['var_memotri']
568
+    and (strncmp($t, 'trisession', 10) == 0 or strncmp($t, 'senssession', 11) == 0)
569 569
 ) {
570
-	if (!function_exists('session_set')) {
571
-		include_spip('inc/session');
572
-	}
573
-	$t = preg_replace(',\W,', '_', $t);
574
-	if ($v = _request($t)) {
575
-		session_set($t, $v);
576
-	}
570
+    if (!function_exists('session_set')) {
571
+        include_spip('inc/session');
572
+    }
573
+    $t = preg_replace(',\W,', '_', $t);
574
+    if ($v = _request($t)) {
575
+        session_set($t, $v);
576
+    }
577 577
 }
578 578
 
579 579
 /**
@@ -583,22 +583,22 @@  discard block
 block discarded – undo
583 583
  * La globale $spip_header_silencieux permet de rendre le header minimal pour raisons de securite
584 584
  */
585 585
 if (!defined('_HEADER_COMPOSED_BY')) {
586
-	define('_HEADER_COMPOSED_BY', 'Composed-By: SPIP');
586
+    define('_HEADER_COMPOSED_BY', 'Composed-By: SPIP');
587 587
 }
588 588
 if (!headers_sent() and _HEADER_COMPOSED_BY) {
589
-	if (!defined('_HEADER_VARY')) {
590
-		define('_HEADER_VARY', 'Vary: Cookie, Accept-Encoding');
591
-	}
592
-	if (_HEADER_VARY) {
593
-		header(_HEADER_VARY);
594
-	}
595
-	if (!isset($GLOBALS['spip_header_silencieux']) or !$GLOBALS['spip_header_silencieux']) {
596
-		include_spip('inc/filtres_mini');
597
-		header(_HEADER_COMPOSED_BY . " $spip_version_affichee @ www.spip.net + " . url_absolue(_DIR_VAR . 'config.txt'));
598
-	} else {
599
-		// header minimal
600
-		header(_HEADER_COMPOSED_BY . ' @ www.spip.net');
601
-	}
589
+    if (!defined('_HEADER_VARY')) {
590
+        define('_HEADER_VARY', 'Vary: Cookie, Accept-Encoding');
591
+    }
592
+    if (_HEADER_VARY) {
593
+        header(_HEADER_VARY);
594
+    }
595
+    if (!isset($GLOBALS['spip_header_silencieux']) or !$GLOBALS['spip_header_silencieux']) {
596
+        include_spip('inc/filtres_mini');
597
+        header(_HEADER_COMPOSED_BY . " $spip_version_affichee @ www.spip.net + " . url_absolue(_DIR_VAR . 'config.txt'));
598
+    } else {
599
+        // header minimal
600
+        header(_HEADER_COMPOSED_BY . ' @ www.spip.net');
601
+    }
602 602
 }
603 603
 
604 604
 $methode = ($_SERVER['REQUEST_METHOD'] ?? ((php_sapi_name() == 'cli') ? 'cli' : ''));
Please login to merge, or discard this patch.
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -10,7 +10,7 @@  discard block
 block discarded – undo
10 10
  *  Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne.   *
11 11
 \***************************************************************************/
12 12
 
13
-require_once __DIR__ . '/../vendor/autoload.php';
13
+require_once __DIR__.'/../vendor/autoload.php';
14 14
 
15 15
 /**
16 16
  * Initialisation de SPIP
@@ -54,11 +54,11 @@  discard block
 block discarded – undo
54 54
 define('_DIR_RACINE', _DIR_RESTREINT ? '' : '../');
55 55
 
56 56
 /** chemin absolu vers la racine */
57
-define('_ROOT_RACINE', dirname(__DIR__) . '/');
57
+define('_ROOT_RACINE', dirname(__DIR__).'/');
58 58
 /** chemin absolu vers le repertoire de travail */
59
-define('_ROOT_CWD', getcwd() . '/');
59
+define('_ROOT_CWD', getcwd().'/');
60 60
 /** chemin absolu vers ecrire */
61
-define('_ROOT_RESTREINT', _ROOT_CWD . _DIR_RESTREINT);
61
+define('_ROOT_RESTREINT', _ROOT_CWD._DIR_RESTREINT);
62 62
 
63 63
 // Icones
64 64
 if (!defined('_NOM_IMG_PACK')) {
@@ -66,17 +66,17 @@  discard block
 block discarded – undo
66 66
 	define('_NOM_IMG_PACK', 'images/');
67 67
 }
68 68
 /** le chemin http (relatif) vers les images standard */
69
-define('_DIR_IMG_PACK', (_DIR_RACINE . 'prive/' . _NOM_IMG_PACK));
69
+define('_DIR_IMG_PACK', (_DIR_RACINE.'prive/'._NOM_IMG_PACK));
70 70
 
71 71
 /** le chemin php (absolu) vers les images standard (pour hebergement centralise) */
72
-define('_ROOT_IMG_PACK', dirname(__DIR__) . '/prive/' . _NOM_IMG_PACK);
72
+define('_ROOT_IMG_PACK', dirname(__DIR__).'/prive/'._NOM_IMG_PACK);
73 73
 
74 74
 if (!defined('_JAVASCRIPT')) {
75 75
 	/** Nom du repertoire des  bibliotheques JavaScript */
76 76
 	define('_JAVASCRIPT', 'javascript/');
77 77
 } // utilisable avec #CHEMIN et find_in_path
78 78
 /** le nom du repertoire des  bibliotheques JavaScript du prive */
79
-define('_DIR_JAVASCRIPT', (_DIR_RACINE . 'prive/' . _JAVASCRIPT));
79
+define('_DIR_JAVASCRIPT', (_DIR_RACINE.'prive/'._JAVASCRIPT));
80 80
 
81 81
 # Le nom des 4 repertoires modifiables par les scripts lances par httpd
82 82
 # Par defaut ces 4 noms seront suffixes par _DIR_RACINE (cf plus bas)
@@ -107,8 +107,8 @@  discard block
 block discarded – undo
107 107
 
108 108
 // Son emplacement absolu si on le trouve
109 109
 if (
110
-	@file_exists($f = _ROOT_RACINE . _NOM_PERMANENTS_INACCESSIBLES . _NOM_CONFIG . '.php')
111
-	or (@file_exists($f = _ROOT_RESTREINT . _NOM_CONFIG . '.php'))
110
+	@file_exists($f = _ROOT_RACINE._NOM_PERMANENTS_INACCESSIBLES._NOM_CONFIG.'.php')
111
+	or (@file_exists($f = _ROOT_RESTREINT._NOM_CONFIG.'.php'))
112 112
 ) {
113 113
 	/** Emplacement absolu du fichier d'option */
114 114
 	define('_FILE_OPTIONS', $f);
@@ -132,7 +132,7 @@  discard block
 block discarded – undo
132 132
 // inclure l'ecran de securite
133 133
 if (
134 134
 	!defined('_ECRAN_SECURITE')
135
-	and @file_exists($f = _ROOT_RACINE . _NOM_PERMANENTS_INACCESSIBLES . 'ecran_securite.php')
135
+	and @file_exists($f = _ROOT_RACINE._NOM_PERMANENTS_INACCESSIBLES.'ecran_securite.php')
136 136
 ) {
137 137
 	include $f;
138 138
 }
@@ -153,7 +153,7 @@  discard block
 block discarded – undo
153 153
 			// UA plus cibles
154 154
 			. '80legs|accoona|AltaVista|ASPSeek|Baidu|Charlotte|EC2LinkFinder|eStyle|facebook|flipboard|hootsuite|FunWebProducts|Google|Genieo|INA dlweb|InfegyAtlas|Java VM|LiteFinder|Lycos|MetaURI|Moreover|Rambler|Scooter|ScrubbyBloglines|Yahoo|Yeti'
155 155
 			. ',i',
156
-			(string)$_SERVER['HTTP_USER_AGENT']
156
+			(string) $_SERVER['HTTP_USER_AGENT']
157 157
 		)
158 158
 	);
159 159
 }
@@ -395,7 +395,7 @@  discard block
 block discarded – undo
395 395
 # la matrice standard (fichiers definissant les fonctions a inclure)
396 396
 $spip_matrice = [];
397 397
 # les plugins a activer
398
-$plugins = [];  // voir le contenu du repertoire /plugins/
398
+$plugins = []; // voir le contenu du repertoire /plugins/
399 399
 # les surcharges de include_spip()
400 400
 $surcharges = []; // format 'inc_truc' => '/plugins/chose/inc_truc2.php'
401 401
 
@@ -473,8 +473,8 @@  discard block
 block discarded – undo
473 473
 //
474 474
 // Charger les fonctions liees aux serveurs Http et Sql.
475 475
 //
476
-require_once _ROOT_RESTREINT . 'inc/utils.php';
477
-require_once _ROOT_RESTREINT . 'base/connect_sql.php';
476
+require_once _ROOT_RESTREINT.'inc/utils.php';
477
+require_once _ROOT_RESTREINT.'base/connect_sql.php';
478 478
 
479 479
 // Definition personnelles eventuelles
480 480
 
@@ -497,10 +497,10 @@  discard block
 block discarded – undo
497 497
 // ===> on execute en neutralisant les messages d'erreur
498 498
 
499 499
 spip_initialisation_core(
500
-	(_DIR_RACINE . _NOM_PERMANENTS_INACCESSIBLES),
501
-	(_DIR_RACINE . _NOM_PERMANENTS_ACCESSIBLES),
502
-	(_DIR_RACINE . _NOM_TEMPORAIRES_INACCESSIBLES),
503
-	(_DIR_RACINE . _NOM_TEMPORAIRES_ACCESSIBLES)
500
+	(_DIR_RACINE._NOM_PERMANENTS_INACCESSIBLES),
501
+	(_DIR_RACINE._NOM_PERMANENTS_ACCESSIBLES),
502
+	(_DIR_RACINE._NOM_TEMPORAIRES_INACCESSIBLES),
503
+	(_DIR_RACINE._NOM_TEMPORAIRES_ACCESSIBLES)
504 504
 );
505 505
 
506 506
 
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
 		// Si on est dans le site public, dire que qq s'en occupe
556 556
 		include_spip('inc/minipres');
557 557
 		utiliser_langue_visiteur();
558
-		echo minipres(_T('info_travaux_titre'), "<p style='text-align: center;'>" . _T('info_travaux_texte') . '</p>', ['status' => 503]);
558
+		echo minipres(_T('info_travaux_titre'), "<p style='text-align: center;'>"._T('info_travaux_texte').'</p>', ['status' => 503]);
559 559
 		exit;
560 560
 	}
561 561
 	// autrement c'est une install ad hoc (spikini...), on sait pas faire
@@ -594,12 +594,12 @@  discard block
 block discarded – undo
594 594
 	}
595 595
 	if (!isset($GLOBALS['spip_header_silencieux']) or !$GLOBALS['spip_header_silencieux']) {
596 596
 		include_spip('inc/filtres_mini');
597
-		header(_HEADER_COMPOSED_BY . " $spip_version_affichee @ www.spip.net + " . url_absolue(_DIR_VAR . 'config.txt'));
597
+		header(_HEADER_COMPOSED_BY." $spip_version_affichee @ www.spip.net + ".url_absolue(_DIR_VAR.'config.txt'));
598 598
 	} else {
599 599
 		// header minimal
600
-		header(_HEADER_COMPOSED_BY . ' @ www.spip.net');
600
+		header(_HEADER_COMPOSED_BY.' @ www.spip.net');
601 601
 	}
602 602
 }
603 603
 
604 604
 $methode = ($_SERVER['REQUEST_METHOD'] ?? ((php_sapi_name() == 'cli') ? 'cli' : ''));
605
-spip_log($methode . ' ' . self() . ' - ' . _FILE_CONNECT, _LOG_DEBUG);
605
+spip_log($methode.' '.self().' - '._FILE_CONNECT, _LOG_DEBUG);
Please login to merge, or discard this patch.
ecrire/genie/maintenance.php 1 patch
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  */
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 /**
@@ -35,19 +35,19 @@  discard block
 block discarded – undo
35 35
  */
36 36
 function genie_maintenance_dist($t) {
37 37
 
38
-	// (re)mettre .htaccess avec deny from all
39
-	// dans les deux repertoires dits inaccessibles par http
40
-	include_spip('inc/acces');
41
-	verifier_htaccess(_DIR_ETC);
42
-	verifier_htaccess(_DIR_TMP);
43
-	verifier_htaccess(_DIR_VENDOR);
38
+    // (re)mettre .htaccess avec deny from all
39
+    // dans les deux repertoires dits inaccessibles par http
40
+    include_spip('inc/acces');
41
+    verifier_htaccess(_DIR_ETC);
42
+    verifier_htaccess(_DIR_TMP);
43
+    verifier_htaccess(_DIR_VENDOR);
44 44
 
45
-	// Verifier qu'aucune table n'est crashee
46
-	if (!_request('reinstall')) {
47
-		verifier_crash_tables();
48
-	}
45
+    // Verifier qu'aucune table n'est crashee
46
+    if (!_request('reinstall')) {
47
+        verifier_crash_tables();
48
+    }
49 49
 
50
-	return 1;
50
+    return 1;
51 51
 }
52 52
 
53 53
 
@@ -64,33 +64,33 @@  discard block
 block discarded – undo
64 64
  *     des tables qui ont crashé.
65 65
  */
66 66
 function verifier_crash_tables() {
67
-	if (spip_connect()) {
68
-		include_spip('base/serial');
69
-		include_spip('base/auxiliaires');
70
-		$crash = [];
71
-		foreach (['tables_principales', 'tables_auxiliaires'] as $com) {
72
-			foreach ($GLOBALS[$com] as $table => $desc) {
73
-				if (
74
-					!sql_select('*', $table, '', '', '', 1)
75
-					and !defined('spip_interdire_cache')
76
-				) { # cas "LOST CONNECTION"
77
-				$crash[] = $table;
78
-				}
79
-			}
80
-		}
81
-		#$crash[] = 'test';
82
-		if ($crash) {
83
-			ecrire_meta('message_crash_tables', serialize($crash));
84
-			spip_log('crash des tables', 'err');
85
-			spip_log($crash, 'err');
86
-		} else {
87
-			effacer_meta('message_crash_tables');
88
-		}
67
+    if (spip_connect()) {
68
+        include_spip('base/serial');
69
+        include_spip('base/auxiliaires');
70
+        $crash = [];
71
+        foreach (['tables_principales', 'tables_auxiliaires'] as $com) {
72
+            foreach ($GLOBALS[$com] as $table => $desc) {
73
+                if (
74
+                    !sql_select('*', $table, '', '', '', 1)
75
+                    and !defined('spip_interdire_cache')
76
+                ) { # cas "LOST CONNECTION"
77
+                $crash[] = $table;
78
+                }
79
+            }
80
+        }
81
+        #$crash[] = 'test';
82
+        if ($crash) {
83
+            ecrire_meta('message_crash_tables', serialize($crash));
84
+            spip_log('crash des tables', 'err');
85
+            spip_log($crash, 'err');
86
+        } else {
87
+            effacer_meta('message_crash_tables');
88
+        }
89 89
 
90
-		return $crash;
91
-	}
90
+        return $crash;
91
+    }
92 92
 
93
-	return false;
93
+    return false;
94 94
 }
95 95
 
96 96
 /**
@@ -106,16 +106,16 @@  discard block
 block discarded – undo
106 106
  * @return string
107 107
  */
108 108
 function message_crash_tables() {
109
-	if ($crash = verifier_crash_tables()) {
110
-		return
111
-			'<strong>' . _T('texte_recuperer_base') . '</strong><br />'
112
-			. ' <tt>' . join(', ', $crash) . '</tt><br />'
113
-			. generer_form_ecrire(
114
-				'base_repair',
115
-				_T('texte_crash_base'),
116
-				'',
117
-				_T('bouton_tenter_recuperation')
118
-			);
119
-	}
120
-	return '';
109
+    if ($crash = verifier_crash_tables()) {
110
+        return
111
+            '<strong>' . _T('texte_recuperer_base') . '</strong><br />'
112
+            . ' <tt>' . join(', ', $crash) . '</tt><br />'
113
+            . generer_form_ecrire(
114
+                'base_repair',
115
+                _T('texte_crash_base'),
116
+                '',
117
+                _T('bouton_tenter_recuperation')
118
+            );
119
+    }
120
+    return '';
121 121
 }
Please login to merge, or discard this patch.
ecrire/auth/spip.php 1 patch
Indentation   +409 added lines, -409 removed lines patch added patch discarded remove patch
@@ -19,7 +19,7 @@  discard block
 block discarded – undo
19 19
 use Spip\Chiffrer\SpipCles;
20 20
 
21 21
 if (!defined('_ECRIRE_INC_VERSION')) {
22
-	return;
22
+    return;
23 23
 }
24 24
 
25 25
 /**
@@ -34,169 +34,169 @@  discard block
 block discarded – undo
34 34
  */
35 35
 function auth_spip_dist($login, $pass, $serveur = '', $phpauth = false) {
36 36
 
37
-	// retrouver le login
38
-	$login = auth_spip_retrouver_login($login);
39
-	// login inconnu, n'allons pas plus loin
40
-	if (!$login) {
41
-		return [];
42
-	}
43
-
44
-	$md5pass = '';
45
-	$shapass = $shanext = '';
46
-	$auteur_peut_sauver_cles = false;
47
-
48
-	if ($pass) {
49
-		$row = sql_fetsel(
50
-			'*',
51
-			'spip_auteurs',
52
-			'login=' . sql_quote($login, $serveur, 'text') . " AND statut<>'5poubelle'",
53
-			'',
54
-			'',
55
-			'',
56
-			'',
57
-			$serveur
58
-		);
59
-
60
-		// lever un flag si cet auteur peut sauver les cles
61
-		if ($row['statut'] === '0minirezo' and $row['webmestre'] === 'oui' and isset($row['backup_cles'])) {
62
-			$auteur_peut_sauver_cles = true;
63
-		}
64
-	}
65
-
66
-	// login inexistant ou mot de passe vide
67
-	if (!$pass or !$row) {
68
-		return [];
69
-	}
70
-
71
-	$cles = SpipCles::instance();
72
-	$secret = $cles->getSecretAuth();
73
-
74
-	$hash = null;
75
-	switch (strlen($row['pass'])) {
76
-		// legacy = md5 ou sha256
77
-		case 32:
78
-			// tres anciens mots de passe encodes en md5(alea.pass)
79
-			$hash = md5($row['alea_actuel'] . $pass);
80
-			$methode = 'md5';
81
-		case 64:
82
-			if (empty($hash)) {
83
-				// anciens mots de passe encodes en sha256(alea.pass)
84
-				include_spip('auth/sha256.inc');
85
-				$hash = spip_sha256($row['alea_actuel'] . $pass);
86
-				$methode = 'sha256';
87
-			}
88
-			if ($row['pass'] === $hash) {
89
-				spip_log("validation du mot de passe pour l'auteur #" . $row['id_auteur'] . " $login via $methode", 'auth' . _LOG_DEBUG);
90
-				// ce n'est pas cense arriver, mais si jamais c'est un backup inutilisable, il faut le nettoyer pour ne pas bloquer la creation d'une nouvelle cle d'auth
91
-				if (!empty($row['backup_cles'])) {
92
-					sql_updateq('spip_auteurs', ['backup_cles' => ''], 'id_auteur=' . intval($row['id_auteur']));
93
-				}
94
-				break;
95
-			}
96
-
97
-		// on teste la methode par defaut, au cas ou ce serait un pass moderne qui a la malchance d'etre en 64char de long
98
-
99
-		case 60:
100
-		case 98:
101
-		default:
102
-			// doit-on restaurer un backup des cles ?
103
-			// si on a le bon pass on peut decoder le backup, retrouver la cle, et du coup valider le pass
104
-			if (
105
-				!$secret
106
-				and $auteur_peut_sauver_cles
107
-				and !empty($row['backup_cles'])
108
-			) {
109
-				if ($cles->restore($row['backup_cles'], $pass, $row['pass'], $row['id_auteur'])) {
110
-					spip_log('Les cles secretes ont ete restaurées avec le backup du webmestre #' . $row['id_auteur'], 'auth' . _LOG_INFO_IMPORTANTE);
111
-					if ($cles->save()) {
112
-						$secret = $cles->getSecretAuth();
113
-					}
114
-					else {
115
-						spip_log("Echec restauration des cles : verifier les droits d'ecriture ?", 'auth' . _LOG_ERREUR);
116
-						// et on echoue car on ne veut pas que la situation reste telle quelle
117
-						raler_fichier(_DIR_ETC . 'cles.php');
118
-					}
119
-				}
120
-				else {
121
-					spip_log('Pas de cle secrete disponible (fichier config/cle.php absent ?) mais le backup du webmestre #' . $row['id_auteur'] . " n'est pas valide", 'auth' . _LOG_ERREUR);
122
-					sql_updateq('spip_auteurs', ['backup_cles' => ''], 'id_auteur=' . intval($row['id_auteur']));
123
-				}
124
-			}
125
-
126
-			if (!$secret or !Password::verifier($pass, $row['pass'], $secret)) {
127
-				unset($row);
128
-			}
129
-			else {
130
-				spip_log("validation du mot de passe pour l'auteur #" . $row['id_auteur'] . " $login via Password::verifier", 'auth' . _LOG_DEBUG);
131
-			}
132
-			break;
133
-	}
134
-
135
-	// Migration depuis ancienne version : si on a pas encore de cle
136
-	// ET si c'est le login d'un auteur qui peut sauver la cle
137
-	// créer la clé (en s'assurant bien que personne n'a de backup d'un precedent fichier cle.php)
138
-	// si c'est un auteur normal, on ne fait rien, il garde son ancien pass hashé en sha256 en attendant le login d'un webmestre
139
-	if (!$secret and $auteur_peut_sauver_cles) {
140
-		if (auth_spip_initialiser_secret()) {
141
-			$secret = $cles->getSecretAuth();
142
-		}
143
-	}
144
-
145
-	// login/mot de passe incorrect
146
-	if (empty($row)) {
147
-		return [];
148
-	}
149
-
150
-	// fait tourner le codage du pass dans la base
151
-	// sauf si phpauth : cela reviendrait a changer l'alea a chaque hit, et aucune action verifiable par securiser_action()
152
-	if (!$phpauth and $secret) {
153
-		include_spip('inc/acces'); // pour creer_uniqid et verifier_htaccess
154
-		$pass_hash_next = Password::hacher($pass, $secret);
155
-		if ($pass_hash_next) {
156
-			$set = [
157
-				'alea_actuel' => 'alea_futur', // @deprecated 4.1
158
-				'alea_futur' => sql_quote(creer_uniqid(), $serveur, 'text'), // @deprecated 4.1
159
-				'pass' => sql_quote($pass_hash_next, $serveur, 'text'),
160
-			];
161
-
162
-			// regenerer un htpass si on a active/desactive le plugin htpasswd
163
-			// et/ou que l'algo a change - pour etre certain de toujours utiliser le bon algo
164
-			$htpass = generer_htpass($pass);
165
-			if (strlen($htpass) !== strlen($row['htpass'])) {
166
-				$set['htpass'] = sql_quote($htpass, $serveur, 'text');
167
-			}
168
-
169
-			// a chaque login de webmestre : sauvegarde chiffree des clés du site (avec les pass du webmestre)
170
-			if ($auteur_peut_sauver_cles) {
171
-				$set['backup_cles'] = sql_quote($cles->backup($pass), $serveur, 'text');
172
-			}
173
-
174
-			@sql_update(
175
-				'spip_auteurs',
176
-				$set,
177
-				'id_auteur=' . intval($row['id_auteur']) . ' AND pass=' . sql_quote(
178
-					$row['pass'],
179
-					$serveur,
180
-					'text'
181
-				),
182
-				[],
183
-				$serveur
184
-			);
185
-
186
-			// si on a change le htpass car changement d'algo, regenerer les fichiers htpasswd
187
-			if (isset($set['htpass'])) {
188
-				ecrire_acces();
189
-			}
190
-		}
191
-
192
-		// En profiter pour verifier la securite de tmp/
193
-		// Si elle ne fonctionne pas a l'installation, prevenir
194
-		if (!verifier_htaccess(_DIR_TMP) and defined('_ECRIRE_INSTALL')) {
195
-			return false;
196
-		}
197
-	}
198
-
199
-	return $row;
37
+    // retrouver le login
38
+    $login = auth_spip_retrouver_login($login);
39
+    // login inconnu, n'allons pas plus loin
40
+    if (!$login) {
41
+        return [];
42
+    }
43
+
44
+    $md5pass = '';
45
+    $shapass = $shanext = '';
46
+    $auteur_peut_sauver_cles = false;
47
+
48
+    if ($pass) {
49
+        $row = sql_fetsel(
50
+            '*',
51
+            'spip_auteurs',
52
+            'login=' . sql_quote($login, $serveur, 'text') . " AND statut<>'5poubelle'",
53
+            '',
54
+            '',
55
+            '',
56
+            '',
57
+            $serveur
58
+        );
59
+
60
+        // lever un flag si cet auteur peut sauver les cles
61
+        if ($row['statut'] === '0minirezo' and $row['webmestre'] === 'oui' and isset($row['backup_cles'])) {
62
+            $auteur_peut_sauver_cles = true;
63
+        }
64
+    }
65
+
66
+    // login inexistant ou mot de passe vide
67
+    if (!$pass or !$row) {
68
+        return [];
69
+    }
70
+
71
+    $cles = SpipCles::instance();
72
+    $secret = $cles->getSecretAuth();
73
+
74
+    $hash = null;
75
+    switch (strlen($row['pass'])) {
76
+        // legacy = md5 ou sha256
77
+        case 32:
78
+            // tres anciens mots de passe encodes en md5(alea.pass)
79
+            $hash = md5($row['alea_actuel'] . $pass);
80
+            $methode = 'md5';
81
+        case 64:
82
+            if (empty($hash)) {
83
+                // anciens mots de passe encodes en sha256(alea.pass)
84
+                include_spip('auth/sha256.inc');
85
+                $hash = spip_sha256($row['alea_actuel'] . $pass);
86
+                $methode = 'sha256';
87
+            }
88
+            if ($row['pass'] === $hash) {
89
+                spip_log("validation du mot de passe pour l'auteur #" . $row['id_auteur'] . " $login via $methode", 'auth' . _LOG_DEBUG);
90
+                // ce n'est pas cense arriver, mais si jamais c'est un backup inutilisable, il faut le nettoyer pour ne pas bloquer la creation d'une nouvelle cle d'auth
91
+                if (!empty($row['backup_cles'])) {
92
+                    sql_updateq('spip_auteurs', ['backup_cles' => ''], 'id_auteur=' . intval($row['id_auteur']));
93
+                }
94
+                break;
95
+            }
96
+
97
+        // on teste la methode par defaut, au cas ou ce serait un pass moderne qui a la malchance d'etre en 64char de long
98
+
99
+        case 60:
100
+        case 98:
101
+        default:
102
+            // doit-on restaurer un backup des cles ?
103
+            // si on a le bon pass on peut decoder le backup, retrouver la cle, et du coup valider le pass
104
+            if (
105
+                !$secret
106
+                and $auteur_peut_sauver_cles
107
+                and !empty($row['backup_cles'])
108
+            ) {
109
+                if ($cles->restore($row['backup_cles'], $pass, $row['pass'], $row['id_auteur'])) {
110
+                    spip_log('Les cles secretes ont ete restaurées avec le backup du webmestre #' . $row['id_auteur'], 'auth' . _LOG_INFO_IMPORTANTE);
111
+                    if ($cles->save()) {
112
+                        $secret = $cles->getSecretAuth();
113
+                    }
114
+                    else {
115
+                        spip_log("Echec restauration des cles : verifier les droits d'ecriture ?", 'auth' . _LOG_ERREUR);
116
+                        // et on echoue car on ne veut pas que la situation reste telle quelle
117
+                        raler_fichier(_DIR_ETC . 'cles.php');
118
+                    }
119
+                }
120
+                else {
121
+                    spip_log('Pas de cle secrete disponible (fichier config/cle.php absent ?) mais le backup du webmestre #' . $row['id_auteur'] . " n'est pas valide", 'auth' . _LOG_ERREUR);
122
+                    sql_updateq('spip_auteurs', ['backup_cles' => ''], 'id_auteur=' . intval($row['id_auteur']));
123
+                }
124
+            }
125
+
126
+            if (!$secret or !Password::verifier($pass, $row['pass'], $secret)) {
127
+                unset($row);
128
+            }
129
+            else {
130
+                spip_log("validation du mot de passe pour l'auteur #" . $row['id_auteur'] . " $login via Password::verifier", 'auth' . _LOG_DEBUG);
131
+            }
132
+            break;
133
+    }
134
+
135
+    // Migration depuis ancienne version : si on a pas encore de cle
136
+    // ET si c'est le login d'un auteur qui peut sauver la cle
137
+    // créer la clé (en s'assurant bien que personne n'a de backup d'un precedent fichier cle.php)
138
+    // si c'est un auteur normal, on ne fait rien, il garde son ancien pass hashé en sha256 en attendant le login d'un webmestre
139
+    if (!$secret and $auteur_peut_sauver_cles) {
140
+        if (auth_spip_initialiser_secret()) {
141
+            $secret = $cles->getSecretAuth();
142
+        }
143
+    }
144
+
145
+    // login/mot de passe incorrect
146
+    if (empty($row)) {
147
+        return [];
148
+    }
149
+
150
+    // fait tourner le codage du pass dans la base
151
+    // sauf si phpauth : cela reviendrait a changer l'alea a chaque hit, et aucune action verifiable par securiser_action()
152
+    if (!$phpauth and $secret) {
153
+        include_spip('inc/acces'); // pour creer_uniqid et verifier_htaccess
154
+        $pass_hash_next = Password::hacher($pass, $secret);
155
+        if ($pass_hash_next) {
156
+            $set = [
157
+                'alea_actuel' => 'alea_futur', // @deprecated 4.1
158
+                'alea_futur' => sql_quote(creer_uniqid(), $serveur, 'text'), // @deprecated 4.1
159
+                'pass' => sql_quote($pass_hash_next, $serveur, 'text'),
160
+            ];
161
+
162
+            // regenerer un htpass si on a active/desactive le plugin htpasswd
163
+            // et/ou que l'algo a change - pour etre certain de toujours utiliser le bon algo
164
+            $htpass = generer_htpass($pass);
165
+            if (strlen($htpass) !== strlen($row['htpass'])) {
166
+                $set['htpass'] = sql_quote($htpass, $serveur, 'text');
167
+            }
168
+
169
+            // a chaque login de webmestre : sauvegarde chiffree des clés du site (avec les pass du webmestre)
170
+            if ($auteur_peut_sauver_cles) {
171
+                $set['backup_cles'] = sql_quote($cles->backup($pass), $serveur, 'text');
172
+            }
173
+
174
+            @sql_update(
175
+                'spip_auteurs',
176
+                $set,
177
+                'id_auteur=' . intval($row['id_auteur']) . ' AND pass=' . sql_quote(
178
+                    $row['pass'],
179
+                    $serveur,
180
+                    'text'
181
+                ),
182
+                [],
183
+                $serveur
184
+            );
185
+
186
+            // si on a change le htpass car changement d'algo, regenerer les fichiers htpasswd
187
+            if (isset($set['htpass'])) {
188
+                ecrire_acces();
189
+            }
190
+        }
191
+
192
+        // En profiter pour verifier la securite de tmp/
193
+        // Si elle ne fonctionne pas a l'installation, prevenir
194
+        if (!verifier_htaccess(_DIR_TMP) and defined('_ECRIRE_INSTALL')) {
195
+            return false;
196
+        }
197
+    }
198
+
199
+    return $row;
200 200
 }
201 201
 
202 202
 /**
@@ -211,36 +211,36 @@  discard block
 block discarded – undo
211 211
  * @return bool
212 212
  */
213 213
 function auth_spip_initialiser_secret(bool $force = false): bool {
214
-	$cles = SpipCles::instance();
215
-	$secret = $cles->getSecretAuth();
216
-
217
-	// on ne fait rien si on a un secret dispo
218
-	if ($secret) {
219
-		return false;
220
-	}
221
-
222
-	// si force, on ne verifie pas la presence d'un backup chez un webmestre
223
-	if ($force) {
224
-		spip_log('Pas de cle secrete disponible, on regenere une nouvelle cle forcee - tous les mots de passe sont invalides', 'auth' . _LOG_INFO_IMPORTANTE);
225
-		$secret = $cles->getSecretAuth(true);
226
-		return true;
227
-	}
228
-
229
-	$has_backup = sql_allfetsel('id_auteur', 'spip_auteurs', 'statut=' . sql_quote('0minirezo') . ' AND webmestre=' . sql_quote('oui') . " AND backup_cles!=''");
230
-	$has_backup = array_column($has_backup, 'id_auteur');
231
-	if (empty($has_backup)) {
232
-		spip_log("Pas de cle secrete disponible, et aucun webmestre n'a de backup, on regenere une nouvelle cle - tous les mots de passe sont invalides", 'auth' . _LOG_INFO_IMPORTANTE);
233
-		if ($secret = $cles->getSecretAuth(true)) {
234
-			return true;
235
-		}
236
-		spip_log("Echec generation d'une nouvelle cle : verifier les droits d'ecriture ?", 'auth' . _LOG_ERREUR);
237
-		// et on echoue car on ne veut pas que la situation reste telle quelle
238
-		raler_fichier(_DIR_ETC . 'cles.php');
239
-	}
240
-	else {
241
-		spip_log('Pas de cle secrete disponible (fichier config/cle.php absent ?) un des webmestres #' . implode(', #', $has_backup) . ' doit se connecter pour restaurer son backup des cles', 'auth' . _LOG_ERREUR);
242
-	}
243
-	return false;
214
+    $cles = SpipCles::instance();
215
+    $secret = $cles->getSecretAuth();
216
+
217
+    // on ne fait rien si on a un secret dispo
218
+    if ($secret) {
219
+        return false;
220
+    }
221
+
222
+    // si force, on ne verifie pas la presence d'un backup chez un webmestre
223
+    if ($force) {
224
+        spip_log('Pas de cle secrete disponible, on regenere une nouvelle cle forcee - tous les mots de passe sont invalides', 'auth' . _LOG_INFO_IMPORTANTE);
225
+        $secret = $cles->getSecretAuth(true);
226
+        return true;
227
+    }
228
+
229
+    $has_backup = sql_allfetsel('id_auteur', 'spip_auteurs', 'statut=' . sql_quote('0minirezo') . ' AND webmestre=' . sql_quote('oui') . " AND backup_cles!=''");
230
+    $has_backup = array_column($has_backup, 'id_auteur');
231
+    if (empty($has_backup)) {
232
+        spip_log("Pas de cle secrete disponible, et aucun webmestre n'a de backup, on regenere une nouvelle cle - tous les mots de passe sont invalides", 'auth' . _LOG_INFO_IMPORTANTE);
233
+        if ($secret = $cles->getSecretAuth(true)) {
234
+            return true;
235
+        }
236
+        spip_log("Echec generation d'une nouvelle cle : verifier les droits d'ecriture ?", 'auth' . _LOG_ERREUR);
237
+        // et on echoue car on ne veut pas que la situation reste telle quelle
238
+        raler_fichier(_DIR_ETC . 'cles.php');
239
+    }
240
+    else {
241
+        spip_log('Pas de cle secrete disponible (fichier config/cle.php absent ?) un des webmestres #' . implode(', #', $has_backup) . ' doit se connecter pour restaurer son backup des cles', 'auth' . _LOG_ERREUR);
242
+    }
243
+    return false;
244 244
 }
245 245
 
246 246
 /**
@@ -250,19 +250,19 @@  discard block
 block discarded – undo
250 250
  * @return array
251 251
  */
252 252
 function auth_spip_formulaire_login($flux) {
253
-	// javascript qui gere la securite du login en evitant de faire circuler le pass en clair
254
-	$js = file_get_contents(find_in_path('prive/javascript/login.js'));
255
-	$flux['data'] .=
256
-		  '<script type="text/javascript">/*<![CDATA[*/'
257
-		. "$js\n"
258
-		. "var login_info={'login':'" . $flux['args']['contexte']['var_login'] . "',"
259
-		. "'page_auteur': '" . generer_url_public('informer_auteur') . "',"
260
-		. "'informe_auteur_en_cours':false,"
261
-		. "'attente_informe':0};"
262
-		. "jQuery(function(){jQuery('#var_login').change(actualise_auteur);});"
263
-		. '/*]]>*/</script>';
264
-
265
-	return $flux;
253
+    // javascript qui gere la securite du login en evitant de faire circuler le pass en clair
254
+    $js = file_get_contents(find_in_path('prive/javascript/login.js'));
255
+    $flux['data'] .=
256
+            '<script type="text/javascript">/*<![CDATA[*/'
257
+        . "$js\n"
258
+        . "var login_info={'login':'" . $flux['args']['contexte']['var_login'] . "',"
259
+        . "'page_auteur': '" . generer_url_public('informer_auteur') . "',"
260
+        . "'informe_auteur_en_cours':false,"
261
+        . "'attente_informe':0};"
262
+        . "jQuery(function(){jQuery('#var_login').change(actualise_auteur);});"
263
+        . '/*]]>*/</script>';
264
+
265
+    return $flux;
266 266
 }
267 267
 
268 268
 
@@ -274,11 +274,11 @@  discard block
 block discarded – undo
274 274
  *   toujours true pour un auteur cree dans SPIP
275 275
  */
276 276
 function auth_spip_autoriser_modifier_login(string $serveur = ''): bool {
277
-	// les fonctions d'ecriture sur base distante sont encore incompletes
278
-	if (strlen($serveur)) {
279
-		return false;
280
-	}
281
-	return true;
277
+    // les fonctions d'ecriture sur base distante sont encore incompletes
278
+    if (strlen($serveur)) {
279
+        return false;
280
+    }
281
+    return true;
282 282
 }
283 283
 
284 284
 /**
@@ -292,25 +292,25 @@  discard block
 block discarded – undo
292 292
  *  message d'erreur si login non valide, chaine vide sinon
293 293
  */
294 294
 function auth_spip_verifier_login($new_login, $id_auteur = 0, $serveur = '') {
295
-	// login et mot de passe
296
-	if (strlen($new_login)) {
297
-		if (strlen($new_login) < _LOGIN_TROP_COURT) {
298
-			return _T('info_login_trop_court_car_pluriel', ['nb' => _LOGIN_TROP_COURT]);
299
-		} else {
300
-			$n = sql_countsel(
301
-				'spip_auteurs',
302
-				'login=' . sql_quote($new_login) . ' AND id_auteur!=' . intval($id_auteur) . " AND statut!='5poubelle'",
303
-				'',
304
-				'',
305
-				$serveur
306
-			);
307
-			if ($n) {
308
-				return _T('info_login_existant');
309
-			}
310
-		}
311
-	}
312
-
313
-	return '';
295
+    // login et mot de passe
296
+    if (strlen($new_login)) {
297
+        if (strlen($new_login) < _LOGIN_TROP_COURT) {
298
+            return _T('info_login_trop_court_car_pluriel', ['nb' => _LOGIN_TROP_COURT]);
299
+        } else {
300
+            $n = sql_countsel(
301
+                'spip_auteurs',
302
+                'login=' . sql_quote($new_login) . ' AND id_auteur!=' . intval($id_auteur) . " AND statut!='5poubelle'",
303
+                '',
304
+                '',
305
+                $serveur
306
+            );
307
+            if ($n) {
308
+                return _T('info_login_existant');
309
+            }
310
+        }
311
+    }
312
+
313
+    return '';
314 314
 }
315 315
 
316 316
 /**
@@ -322,41 +322,41 @@  discard block
 block discarded – undo
322 322
  * @return bool
323 323
  */
324 324
 function auth_spip_modifier_login($new_login, $id_auteur, $serveur = '') {
325
-	if (is_null($new_login) or auth_spip_verifier_login($new_login, $id_auteur, $serveur) != '') {
326
-		return false;
327
-	}
328
-	if (
329
-		!$id_auteur = intval($id_auteur)
330
-		or !$auteur = sql_fetsel('login', 'spip_auteurs', 'id_auteur=' . intval($id_auteur), '', '', '', '', $serveur)
331
-	) {
332
-		return false;
333
-	}
334
-	if ($new_login == $auteur['login']) {
335
-		return true;
336
-	} // on a rien fait mais c'est bon !
337
-
338
-	include_spip('action/editer_auteur');
339
-
340
-	// vider le login des auteurs a la poubelle qui avaient ce meme login
341
-	if (strlen($new_login)) {
342
-		$anciens = sql_allfetsel(
343
-			'id_auteur',
344
-			'spip_auteurs',
345
-			'login=' . sql_quote($new_login, $serveur, 'text') . " AND statut='5poubelle'",
346
-			'',
347
-			'',
348
-			'',
349
-			'',
350
-			$serveur
351
-		);
352
-		while ($row = array_pop($anciens)) {
353
-			auteur_modifier($row['id_auteur'], ['login' => ''], true); // manque la gestion de $serveur
354
-		}
355
-	}
356
-
357
-	auteur_modifier($id_auteur, ['login' => $new_login], true); // manque la gestion de $serveur
358
-
359
-	return true;
325
+    if (is_null($new_login) or auth_spip_verifier_login($new_login, $id_auteur, $serveur) != '') {
326
+        return false;
327
+    }
328
+    if (
329
+        !$id_auteur = intval($id_auteur)
330
+        or !$auteur = sql_fetsel('login', 'spip_auteurs', 'id_auteur=' . intval($id_auteur), '', '', '', '', $serveur)
331
+    ) {
332
+        return false;
333
+    }
334
+    if ($new_login == $auteur['login']) {
335
+        return true;
336
+    } // on a rien fait mais c'est bon !
337
+
338
+    include_spip('action/editer_auteur');
339
+
340
+    // vider le login des auteurs a la poubelle qui avaient ce meme login
341
+    if (strlen($new_login)) {
342
+        $anciens = sql_allfetsel(
343
+            'id_auteur',
344
+            'spip_auteurs',
345
+            'login=' . sql_quote($new_login, $serveur, 'text') . " AND statut='5poubelle'",
346
+            '',
347
+            '',
348
+            '',
349
+            '',
350
+            $serveur
351
+        );
352
+        while ($row = array_pop($anciens)) {
353
+            auteur_modifier($row['id_auteur'], ['login' => ''], true); // manque la gestion de $serveur
354
+        }
355
+    }
356
+
357
+    auteur_modifier($id_auteur, ['login' => $new_login], true); // manque la gestion de $serveur
358
+
359
+    return true;
360 360
 }
361 361
 
362 362
 /**
@@ -368,44 +368,44 @@  discard block
 block discarded – undo
368 368
  * @return string
369 369
  */
370 370
 function auth_spip_retrouver_login($login, $serveur = '') {
371
-	if (!strlen($login)) {
372
-		return null;
373
-	} // pas la peine de requeter
374
-	$l = sql_quote($login, $serveur, 'text');
375
-	if (
376
-		$r = sql_getfetsel(
377
-			'login',
378
-			'spip_auteurs',
379
-			"statut<>'5poubelle'" .
380
-			' AND (length(pass)>0)' .
381
-			" AND (login=$l)",
382
-			'',
383
-			'',
384
-			'',
385
-			'',
386
-			$serveur
387
-		)
388
-	) {
389
-		return $r;
390
-	}
391
-	// Si pas d'auteur avec ce login
392
-	// regarder s'il a saisi son nom ou son mail.
393
-	// Ne pas fusionner avec la requete precedente
394
-	// car un nom peut etre homonyme d'un autre login
395
-	else {
396
-		return sql_getfetsel(
397
-			'login',
398
-			'spip_auteurs',
399
-			"statut<>'5poubelle'" .
400
-			' AND (length(pass)>0)' .
401
-			" AND (login<>'' AND (nom=$l OR email=$l))",
402
-			'',
403
-			'',
404
-			'',
405
-			'',
406
-			$serveur
407
-		);
408
-	}
371
+    if (!strlen($login)) {
372
+        return null;
373
+    } // pas la peine de requeter
374
+    $l = sql_quote($login, $serveur, 'text');
375
+    if (
376
+        $r = sql_getfetsel(
377
+            'login',
378
+            'spip_auteurs',
379
+            "statut<>'5poubelle'" .
380
+            ' AND (length(pass)>0)' .
381
+            " AND (login=$l)",
382
+            '',
383
+            '',
384
+            '',
385
+            '',
386
+            $serveur
387
+        )
388
+    ) {
389
+        return $r;
390
+    }
391
+    // Si pas d'auteur avec ce login
392
+    // regarder s'il a saisi son nom ou son mail.
393
+    // Ne pas fusionner avec la requete precedente
394
+    // car un nom peut etre homonyme d'un autre login
395
+    else {
396
+        return sql_getfetsel(
397
+            'login',
398
+            'spip_auteurs',
399
+            "statut<>'5poubelle'" .
400
+            ' AND (length(pass)>0)' .
401
+            " AND (login<>'' AND (nom=$l OR email=$l))",
402
+            '',
403
+            '',
404
+            '',
405
+            '',
406
+            $serveur
407
+        );
408
+    }
409 409
 }
410 410
 
411 411
 /**
@@ -416,11 +416,11 @@  discard block
 block discarded – undo
416 416
  *  toujours true pour un auteur cree dans SPIP
417 417
  */
418 418
 function auth_spip_autoriser_modifier_pass(string $serveur = ''): bool {
419
-	// les fonctions d'ecriture sur base distante sont encore incompletes
420
-	if (strlen($serveur)) {
421
-		return false;
422
-	}
423
-	return true;
419
+    // les fonctions d'ecriture sur base distante sont encore incompletes
420
+    if (strlen($serveur)) {
421
+        return false;
422
+    }
423
+    return true;
424 424
 }
425 425
 
426 426
 
@@ -441,12 +441,12 @@  discard block
 block discarded – undo
441 441
  *  message d'erreur si login non valide, chaine vide sinon
442 442
  */
443 443
 function auth_spip_verifier_pass($login, $new_pass, $id_auteur = 0, $serveur = '') {
444
-	// login et mot de passe
445
-	if (strlen($new_pass) < _PASS_LONGUEUR_MINI) {
446
-		return _T('info_passe_trop_court_car_pluriel', ['nb' => _PASS_LONGUEUR_MINI]);
447
-	}
444
+    // login et mot de passe
445
+    if (strlen($new_pass) < _PASS_LONGUEUR_MINI) {
446
+        return _T('info_passe_trop_court_car_pluriel', ['nb' => _PASS_LONGUEUR_MINI]);
447
+    }
448 448
 
449
-	return '';
449
+    return '';
450 450
 }
451 451
 
452 452
 /**
@@ -460,47 +460,47 @@  discard block
 block discarded – undo
460 460
  * @return bool
461 461
  */
462 462
 function auth_spip_modifier_pass($login, $new_pass, $id_auteur, $serveur = '') {
463
-	if (is_null($new_pass) or auth_spip_verifier_pass($login, $new_pass, $id_auteur, $serveur) != '') {
464
-		return false;
465
-	}
466
-
467
-	if (
468
-		!$id_auteur = intval($id_auteur)
469
-		or !$auteur = sql_fetsel('login, statut, webmestre', 'spip_auteurs', 'id_auteur=' . intval($id_auteur), '', '', '', '', $serveur)
470
-	) {
471
-		return false;
472
-	}
473
-
474
-	$cles = SpipCles::instance();
475
-	$secret = $cles->getSecretAuth();
476
-	if (!$secret) {
477
-		if (auth_spip_initialiser_secret()) {
478
-			$secret = $cles->getSecretAuth();
479
-		}
480
-		else {
481
-			return false;
482
-		}
483
-	}
484
-
485
-
486
-	include_spip('inc/acces');
487
-	$set = [
488
-		'pass' => Password::hacher($new_pass, $secret),
489
-		'htpass' => generer_htpass($new_pass),
490
-		'alea_actuel' => creer_uniqid(), // @deprecated 4.1
491
-		'alea_futur' => creer_uniqid(), // @deprecated 4.1
492
-		'low_sec' => '',
493
-	];
494
-
495
-	// si c'est un webmestre, on met a jour son backup des cles
496
-	if ($auteur['statut'] === '0minirezo' and $auteur['webmestre'] === 'oui') {
497
-		$set['backup_cles'] = $cles->backup($new_pass);
498
-	}
499
-
500
-	include_spip('action/editer_auteur');
501
-	auteur_modifier($id_auteur, $set, true); // manque la gestion de $serveur
502
-
503
-	return true; // on a bien modifie le pass
463
+    if (is_null($new_pass) or auth_spip_verifier_pass($login, $new_pass, $id_auteur, $serveur) != '') {
464
+        return false;
465
+    }
466
+
467
+    if (
468
+        !$id_auteur = intval($id_auteur)
469
+        or !$auteur = sql_fetsel('login, statut, webmestre', 'spip_auteurs', 'id_auteur=' . intval($id_auteur), '', '', '', '', $serveur)
470
+    ) {
471
+        return false;
472
+    }
473
+
474
+    $cles = SpipCles::instance();
475
+    $secret = $cles->getSecretAuth();
476
+    if (!$secret) {
477
+        if (auth_spip_initialiser_secret()) {
478
+            $secret = $cles->getSecretAuth();
479
+        }
480
+        else {
481
+            return false;
482
+        }
483
+    }
484
+
485
+
486
+    include_spip('inc/acces');
487
+    $set = [
488
+        'pass' => Password::hacher($new_pass, $secret),
489
+        'htpass' => generer_htpass($new_pass),
490
+        'alea_actuel' => creer_uniqid(), // @deprecated 4.1
491
+        'alea_futur' => creer_uniqid(), // @deprecated 4.1
492
+        'low_sec' => '',
493
+    ];
494
+
495
+    // si c'est un webmestre, on met a jour son backup des cles
496
+    if ($auteur['statut'] === '0minirezo' and $auteur['webmestre'] === 'oui') {
497
+        $set['backup_cles'] = $cles->backup($new_pass);
498
+    }
499
+
500
+    include_spip('action/editer_auteur');
501
+    auteur_modifier($id_auteur, $set, true); // manque la gestion de $serveur
502
+
503
+    return true; // on a bien modifie le pass
504 504
 }
505 505
 
506 506
 /**
@@ -514,58 +514,58 @@  discard block
 block discarded – undo
514 514
  * @return void
515 515
  */
516 516
 function auth_spip_synchroniser_distant($id_auteur, $champs, $options = [], string $serveur = ''): void {
517
-	// ne rien faire pour une base distante : on ne sait pas regenerer les htaccess
518
-	if (strlen($serveur)) {
519
-		return;
520
-	}
521
-	// si un login, pass ou statut a ete modifie
522
-	// regenerer les fichier htpass
523
-	if (
524
-		isset($champs['login'])
525
-		or isset($champs['pass'])
526
-		or isset($champs['statut'])
527
-		or (isset($options['all']) and $options['all'])
528
-	) {
529
-		$htaccess = _DIR_RESTREINT . _ACCESS_FILE_NAME;
530
-		$htpasswd = _DIR_TMP . _AUTH_USER_FILE;
531
-
532
-		// Cette variable de configuration peut etre posee par un plugin
533
-		// par exemple acces_restreint ;
534
-		// si .htaccess existe, outrepasser spip_meta
535
-		if (
536
-			(!isset($GLOBALS['meta']['creer_htpasswd']) or ($GLOBALS['meta']['creer_htpasswd'] != 'oui'))
537
-			and !@file_exists($htaccess)
538
-		) {
539
-			spip_unlink($htpasswd);
540
-			spip_unlink($htpasswd . '-admin');
541
-
542
-			return;
543
-		}
544
-
545
-		# remarque : ici on laisse passer les "nouveau" de maniere a leur permettre
546
-		# de devenir redacteur le cas echeant (auth http)... a nettoyer
547
-		// attention, il faut au prealable se connecter a la base (necessaire car utilise par install)
548
-
549
-		$p1 = ''; // login:htpass pour tous
550
-		$p2 = ''; // login:htpass pour les admins
551
-		$s = sql_select(
552
-			'login, htpass, statut',
553
-			'spip_auteurs',
554
-			sql_in('statut', ['1comite', '0minirezo', 'nouveau'])
555
-		);
556
-		while ($t = sql_fetch($s)) {
557
-			if (strlen($t['login']) and strlen($t['htpass'])) {
558
-				$p1 .= $t['login'] . ':' . $t['htpass'] . "\n";
559
-				if ($t['statut'] == '0minirezo') {
560
-					$p2 .= $t['login'] . ':' . $t['htpass'] . "\n";
561
-				}
562
-			}
563
-		}
564
-		sql_free($s);
565
-		if ($p1) {
566
-			ecrire_fichier($htpasswd, $p1);
567
-			ecrire_fichier($htpasswd . '-admin', $p2);
568
-			spip_log("Ecriture de $htpasswd et $htpasswd-admin");
569
-		}
570
-	}
517
+    // ne rien faire pour une base distante : on ne sait pas regenerer les htaccess
518
+    if (strlen($serveur)) {
519
+        return;
520
+    }
521
+    // si un login, pass ou statut a ete modifie
522
+    // regenerer les fichier htpass
523
+    if (
524
+        isset($champs['login'])
525
+        or isset($champs['pass'])
526
+        or isset($champs['statut'])
527
+        or (isset($options['all']) and $options['all'])
528
+    ) {
529
+        $htaccess = _DIR_RESTREINT . _ACCESS_FILE_NAME;
530
+        $htpasswd = _DIR_TMP . _AUTH_USER_FILE;
531
+
532
+        // Cette variable de configuration peut etre posee par un plugin
533
+        // par exemple acces_restreint ;
534
+        // si .htaccess existe, outrepasser spip_meta
535
+        if (
536
+            (!isset($GLOBALS['meta']['creer_htpasswd']) or ($GLOBALS['meta']['creer_htpasswd'] != 'oui'))
537
+            and !@file_exists($htaccess)
538
+        ) {
539
+            spip_unlink($htpasswd);
540
+            spip_unlink($htpasswd . '-admin');
541
+
542
+            return;
543
+        }
544
+
545
+        # remarque : ici on laisse passer les "nouveau" de maniere a leur permettre
546
+        # de devenir redacteur le cas echeant (auth http)... a nettoyer
547
+        // attention, il faut au prealable se connecter a la base (necessaire car utilise par install)
548
+
549
+        $p1 = ''; // login:htpass pour tous
550
+        $p2 = ''; // login:htpass pour les admins
551
+        $s = sql_select(
552
+            'login, htpass, statut',
553
+            'spip_auteurs',
554
+            sql_in('statut', ['1comite', '0minirezo', 'nouveau'])
555
+        );
556
+        while ($t = sql_fetch($s)) {
557
+            if (strlen($t['login']) and strlen($t['htpass'])) {
558
+                $p1 .= $t['login'] . ':' . $t['htpass'] . "\n";
559
+                if ($t['statut'] == '0minirezo') {
560
+                    $p2 .= $t['login'] . ':' . $t['htpass'] . "\n";
561
+                }
562
+            }
563
+        }
564
+        sql_free($s);
565
+        if ($p1) {
566
+            ecrire_fichier($htpasswd, $p1);
567
+            ecrire_fichier($htpasswd . '-admin', $p2);
568
+            spip_log("Ecriture de $htpasswd et $htpasswd-admin");
569
+        }
570
+    }
571 571
 }
Please login to merge, or discard this patch.
ecrire/iterateur/data.php 2 patches
Indentation   +128 added lines, -128 removed lines patch added patch discarded remove patch
@@ -19,11 +19,11 @@  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
 if (!defined('_DATA_SOURCE_MAX_SIZE')) {
26
-	define('_DATA_SOURCE_MAX_SIZE', 2 * 1_048_576);
26
+    define('_DATA_SOURCE_MAX_SIZE', 2 * 1_048_576);
27 27
 }
28 28
 
29 29
 
@@ -44,17 +44,17 @@  discard block
 block discarded – undo
44 44
  *     Description de la boucle complétée des champs
45 45
  */
46 46
 function iterateur_DATA_dist($b) {
47
-	$b->iterateur = 'DATA'; # designe la classe d'iterateur
48
-	$b->show = [
49
-		'field' => [
50
-			'cle' => 'STRING',
51
-			'valeur' => 'STRING',
52
-			'*' => 'ALL' // Champ joker *
53
-		]
54
-	];
55
-	$b->select[] = '.valeur';
56
-
57
-	return $b;
47
+    $b->iterateur = 'DATA'; # designe la classe d'iterateur
48
+    $b->show = [
49
+        'field' => [
50
+            'cle' => 'STRING',
51
+            'valeur' => 'STRING',
52
+            '*' => 'ALL' // Champ joker *
53
+        ]
54
+    ];
55
+    $b->select[] = '.valeur';
56
+
57
+    return $b;
58 58
 }
59 59
 
60 60
 
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
  * @return array
70 70
  */
71 71
 function inc_file_to_array_dist($data) {
72
-	return preg_split('/\r?\n/', $data);
72
+    return preg_split('/\r?\n/', $data);
73 73
 }
74 74
 
75 75
 /**
@@ -78,9 +78,9 @@  discard block
 block discarded – undo
78 78
  * @return array
79 79
  */
80 80
 function inc_plugins_to_array_dist() {
81
-	include_spip('inc/plugin');
81
+    include_spip('inc/plugin');
82 82
 
83
-	return liste_chemin_plugin_actifs();
83
+    return liste_chemin_plugin_actifs();
84 84
 }
85 85
 
86 86
 /**
@@ -90,7 +90,7 @@  discard block
 block discarded – undo
90 90
  * @return array
91 91
  */
92 92
 function inc_xml_to_array_dist($data) {
93
-	return @XMLObjectToArray(new SimpleXmlIterator($data));
93
+    return @XMLObjectToArray(new SimpleXmlIterator($data));
94 94
 }
95 95
 
96 96
 /**
@@ -102,14 +102,14 @@  discard block
 block discarded – undo
102 102
  *
103 103
  */
104 104
 function inc_object_to_array($object) {
105
-	if (!is_object($object) && !is_array($object)) {
106
-		return $object;
107
-	}
108
-	if (is_object($object)) {
109
-		$object = get_object_vars($object);
110
-	}
111
-
112
-	return array_map('inc_object_to_array', $object);
105
+    if (!is_object($object) && !is_array($object)) {
106
+        return $object;
107
+    }
108
+    if (is_object($object)) {
109
+        $object = get_object_vars($object);
110
+    }
111
+
112
+    return array_map('inc_object_to_array', $object);
113 113
 }
114 114
 
115 115
 /**
@@ -119,20 +119,20 @@  discard block
 block discarded – undo
119 119
  * @return array|bool
120 120
  */
121 121
 function inc_sql_to_array_dist($data) {
122
-	# sortir le connecteur de $data
123
-	preg_match(',^(?:(\w+):)?(.*)$,Sm', $data, $v);
124
-	$serveur = (string)$v[1];
125
-	$req = trim($v[2]);
126
-	if ($s = sql_query($req, $serveur)) {
127
-		$r = [];
128
-		while ($t = sql_fetch($s)) {
129
-			$r[] = $t;
130
-		}
131
-
132
-		return $r;
133
-	}
134
-
135
-	return false;
122
+    # sortir le connecteur de $data
123
+    preg_match(',^(?:(\w+):)?(.*)$,Sm', $data, $v);
124
+    $serveur = (string)$v[1];
125
+    $req = trim($v[2]);
126
+    if ($s = sql_query($req, $serveur)) {
127
+        $r = [];
128
+        while ($t = sql_fetch($s)) {
129
+            $r[] = $t;
130
+        }
131
+
132
+        return $r;
133
+    }
134
+
135
+    return false;
136 136
 }
137 137
 
138 138
 /**
@@ -142,13 +142,13 @@  discard block
 block discarded – undo
142 142
  * @return array|bool
143 143
  */
144 144
 function inc_json_to_array_dist($data) {
145
-	try {
146
-		$json = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
147
-	} catch (JsonException $e) {
148
-		$json = null;
149
-		spip_log('Failed to parse Json data : ' . $e->getMessage(), _LOG_INFO);
150
-	}
151
-	return is_array($json) ? (array) $json : [];
145
+    try {
146
+        $json = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
147
+    } catch (JsonException $e) {
148
+        $json = null;
149
+        spip_log('Failed to parse Json data : ' . $e->getMessage(), _LOG_INFO);
150
+    }
151
+    return is_array($json) ? (array) $json : [];
152 152
 }
153 153
 
154 154
 /**
@@ -158,30 +158,30 @@  discard block
 block discarded – undo
158 158
  * @return array|bool
159 159
  */
160 160
 function inc_csv_to_array_dist($data) {
161
-	include_spip('inc/csv');
162
-	[$entete, $csv] = analyse_csv($data);
163
-	array_unshift($csv, $entete);
164
-
165
-	include_spip('inc/charsets');
166
-	$i = 1;
167
-	foreach ($entete as $k => $v) {
168
-		if (trim($v) == '') {
169
-			$v = 'col' . $i;
170
-		} // reperer des eventuelles cases vides
171
-		if (is_numeric($v) and $v < 0) {
172
-			$v = '__' . $v;
173
-		} // ne pas risquer d'ecraser une cle numerique
174
-		if (is_numeric($v)) {
175
-			$v = '_' . $v;
176
-		} // ne pas risquer d'ecraser une cle numerique
177
-		$v = strtolower(preg_replace(',\W+,', '_', translitteration($v)));
178
-		foreach ($csv as &$item) {
179
-			$item[$v] = &$item[$k];
180
-		}
181
-		$i++;
182
-	}
183
-
184
-	return $csv;
161
+    include_spip('inc/csv');
162
+    [$entete, $csv] = analyse_csv($data);
163
+    array_unshift($csv, $entete);
164
+
165
+    include_spip('inc/charsets');
166
+    $i = 1;
167
+    foreach ($entete as $k => $v) {
168
+        if (trim($v) == '') {
169
+            $v = 'col' . $i;
170
+        } // reperer des eventuelles cases vides
171
+        if (is_numeric($v) and $v < 0) {
172
+            $v = '__' . $v;
173
+        } // ne pas risquer d'ecraser une cle numerique
174
+        if (is_numeric($v)) {
175
+            $v = '_' . $v;
176
+        } // ne pas risquer d'ecraser une cle numerique
177
+        $v = strtolower(preg_replace(',\W+,', '_', translitteration($v)));
178
+        foreach ($csv as &$item) {
179
+            $item[$v] = &$item[$k];
180
+        }
181
+        $i++;
182
+    }
183
+
184
+    return $csv;
185 185
 }
186 186
 
187 187
 /**
@@ -191,13 +191,13 @@  discard block
 block discarded – undo
191 191
  * @return array|bool
192 192
  */
193 193
 function inc_rss_to_array_dist($data) {
194
-	$tableau = null;
195
-	include_spip('inc/syndic');
196
-	if (is_array($rss = analyser_backend($data))) {
197
-		$tableau = $rss;
198
-	}
194
+    $tableau = null;
195
+    include_spip('inc/syndic');
196
+    if (is_array($rss = analyser_backend($data))) {
197
+        $tableau = $rss;
198
+    }
199 199
 
200
-	return $tableau;
200
+    return $tableau;
201 201
 }
202 202
 
203 203
 /**
@@ -207,9 +207,9 @@  discard block
 block discarded – undo
207 207
  * @return array|bool
208 208
  */
209 209
 function inc_atom_to_array_dist($data) {
210
-	$rss_to_array = charger_fonction('rss_to_array', 'inc');
210
+    $rss_to_array = charger_fonction('rss_to_array', 'inc');
211 211
 
212
-	return $rss_to_array($data);
212
+    return $rss_to_array($data);
213 213
 }
214 214
 
215 215
 /**
@@ -220,12 +220,12 @@  discard block
 block discarded – undo
220 220
  * @return array|bool
221 221
  */
222 222
 function inc_glob_to_array_dist($data) {
223
-	$a = glob(
224
-		$data,
225
-		GLOB_MARK | GLOB_NOSORT | GLOB_BRACE
226
-	);
223
+    $a = glob(
224
+        $data,
225
+        GLOB_MARK | GLOB_NOSORT | GLOB_BRACE
226
+    );
227 227
 
228
-	return $a ?: [];
228
+    return $a ?: [];
229 229
 }
230 230
 
231 231
 /**
@@ -236,14 +236,14 @@  discard block
 block discarded – undo
236 236
  * @throws Exception
237 237
  */
238 238
 function inc_yaml_to_array_dist($data) {
239
-	include_spip('inc/yaml-mini');
240
-	if (!function_exists('yaml_decode')) {
241
-		throw new Exception('YAML: impossible de trouver la fonction yaml_decode');
239
+    include_spip('inc/yaml-mini');
240
+    if (!function_exists('yaml_decode')) {
241
+        throw new Exception('YAML: impossible de trouver la fonction yaml_decode');
242 242
 
243
-		return false;
244
-	}
243
+        return false;
244
+    }
245 245
 
246
-	return yaml_decode($data);
246
+    return yaml_decode($data);
247 247
 }
248 248
 
249 249
 
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
  * @return array|bool
259 259
  */
260 260
 function inc_pregfiles_to_array_dist($dir, $regexp = -1, $limit = 10000) {
261
-	return (array)preg_files($dir, $regexp, $limit);
261
+    return (array)preg_files($dir, $regexp, $limit);
262 262
 }
263 263
 
264 264
 /**
@@ -270,23 +270,23 @@  discard block
 block discarded – undo
270 270
  * @return array|bool
271 271
  */
272 272
 function inc_ls_to_array_dist($data) {
273
-	$glob_to_array = charger_fonction('glob_to_array', 'inc');
274
-	$a = $glob_to_array($data);
275
-	foreach ($a as &$v) {
276
-		$b = (array)@stat($v);
277
-		foreach ($b as $k => $ignore) {
278
-			if (is_numeric($k)) {
279
-				unset($b[$k]);
280
-			}
281
-		}
282
-		$b['file'] = preg_replace('`/$`', '', $v) ;
283
-		$v = array_merge(
284
-			pathinfo($v),
285
-			$b
286
-		);
287
-	}
288
-
289
-	return $a;
273
+    $glob_to_array = charger_fonction('glob_to_array', 'inc');
274
+    $a = $glob_to_array($data);
275
+    foreach ($a as &$v) {
276
+        $b = (array)@stat($v);
277
+        foreach ($b as $k => $ignore) {
278
+            if (is_numeric($k)) {
279
+                unset($b[$k]);
280
+            }
281
+        }
282
+        $b['file'] = preg_replace('`/$`', '', $v) ;
283
+        $v = array_merge(
284
+            pathinfo($v),
285
+            $b
286
+        );
287
+    }
288
+
289
+    return $a;
290 290
 }
291 291
 
292 292
 /**
@@ -296,25 +296,25 @@  discard block
 block discarded – undo
296 296
  * @return array|bool
297 297
  */
298 298
 function XMLObjectToArray($object) {
299
-	$xml_array = [];
300
-	for ($object->rewind(); $object->valid(); $object->next()) {
301
-		if (array_key_exists($key = $object->key(), $xml_array)) {
302
-			$key .= '-' . uniqid();
303
-		}
304
-		$vars = get_object_vars($object->current());
305
-		if (isset($vars['@attributes'])) {
306
-			foreach ($vars['@attributes'] as $k => $v) {
307
-				$xml_array[$key][$k] = $v;
308
-			}
309
-		}
310
-		if ($object->hasChildren()) {
311
-			$xml_array[$key][] = XMLObjectToArray(
312
-				$object->current()
313
-			);
314
-		} else {
315
-			$xml_array[$key][] = strval($object->current());
316
-		}
317
-	}
318
-
319
-	return $xml_array;
299
+    $xml_array = [];
300
+    for ($object->rewind(); $object->valid(); $object->next()) {
301
+        if (array_key_exists($key = $object->key(), $xml_array)) {
302
+            $key .= '-' . uniqid();
303
+        }
304
+        $vars = get_object_vars($object->current());
305
+        if (isset($vars['@attributes'])) {
306
+            foreach ($vars['@attributes'] as $k => $v) {
307
+                $xml_array[$key][$k] = $v;
308
+            }
309
+        }
310
+        if ($object->hasChildren()) {
311
+            $xml_array[$key][] = XMLObjectToArray(
312
+                $object->current()
313
+            );
314
+        } else {
315
+            $xml_array[$key][] = strval($object->current());
316
+        }
317
+    }
318
+
319
+    return $xml_array;
320 320
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -121,7 +121,7 @@  discard block
 block discarded – undo
121 121
 function inc_sql_to_array_dist($data) {
122 122
 	# sortir le connecteur de $data
123 123
 	preg_match(',^(?:(\w+):)?(.*)$,Sm', $data, $v);
124
-	$serveur = (string)$v[1];
124
+	$serveur = (string) $v[1];
125 125
 	$req = trim($v[2]);
126 126
 	if ($s = sql_query($req, $serveur)) {
127 127
 		$r = [];
@@ -146,7 +146,7 @@  discard block
 block discarded – undo
146 146
 		$json = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
147 147
 	} catch (JsonException $e) {
148 148
 		$json = null;
149
-		spip_log('Failed to parse Json data : ' . $e->getMessage(), _LOG_INFO);
149
+		spip_log('Failed to parse Json data : '.$e->getMessage(), _LOG_INFO);
150 150
 	}
151 151
 	return is_array($json) ? (array) $json : [];
152 152
 }
@@ -166,13 +166,13 @@  discard block
 block discarded – undo
166 166
 	$i = 1;
167 167
 	foreach ($entete as $k => $v) {
168 168
 		if (trim($v) == '') {
169
-			$v = 'col' . $i;
169
+			$v = 'col'.$i;
170 170
 		} // reperer des eventuelles cases vides
171 171
 		if (is_numeric($v) and $v < 0) {
172
-			$v = '__' . $v;
172
+			$v = '__'.$v;
173 173
 		} // ne pas risquer d'ecraser une cle numerique
174 174
 		if (is_numeric($v)) {
175
-			$v = '_' . $v;
175
+			$v = '_'.$v;
176 176
 		} // ne pas risquer d'ecraser une cle numerique
177 177
 		$v = strtolower(preg_replace(',\W+,', '_', translitteration($v)));
178 178
 		foreach ($csv as &$item) {
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
  * @return array|bool
259 259
  */
260 260
 function inc_pregfiles_to_array_dist($dir, $regexp = -1, $limit = 10000) {
261
-	return (array)preg_files($dir, $regexp, $limit);
261
+	return (array) preg_files($dir, $regexp, $limit);
262 262
 }
263 263
 
264 264
 /**
@@ -273,13 +273,13 @@  discard block
 block discarded – undo
273 273
 	$glob_to_array = charger_fonction('glob_to_array', 'inc');
274 274
 	$a = $glob_to_array($data);
275 275
 	foreach ($a as &$v) {
276
-		$b = (array)@stat($v);
276
+		$b = (array) @stat($v);
277 277
 		foreach ($b as $k => $ignore) {
278 278
 			if (is_numeric($k)) {
279 279
 				unset($b[$k]);
280 280
 			}
281 281
 		}
282
-		$b['file'] = preg_replace('`/$`', '', $v) ;
282
+		$b['file'] = preg_replace('`/$`', '', $v);
283 283
 		$v = array_merge(
284 284
 			pathinfo($v),
285 285
 			$b
@@ -299,7 +299,7 @@  discard block
 block discarded – undo
299 299
 	$xml_array = [];
300 300
 	for ($object->rewind(); $object->valid(); $object->next()) {
301 301
 		if (array_key_exists($key = $object->key(), $xml_array)) {
302
-			$key .= '-' . uniqid();
302
+			$key .= '-'.uniqid();
303 303
 		}
304 304
 		$vars = get_object_vars($object->current());
305 305
 		if (isset($vars['@attributes'])) {
Please login to merge, or discard this patch.
ecrire/iterateur/condition.php 1 patch
Indentation   +6 added lines, -6 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('iterateur/data');
@@ -37,10 +37,10 @@  discard block
 block discarded – undo
37 37
  *     Description de la boucle complétée des champs
38 38
  */
39 39
 function iterateur_CONDITION_dist($b) {
40
-	$b->iterateur = 'CONDITION'; # designe la classe d'iterateur
41
-	$b->show = [
42
-		'field' => []
43
-	];
40
+    $b->iterateur = 'CONDITION'; # designe la classe d'iterateur
41
+    $b->show = [
42
+        'field' => []
43
+    ];
44 44
 
45
-	return $b;
45
+    return $b;
46 46
 }
Please login to merge, or discard this patch.
ecrire/iterateur/pour.php 1 patch
Indentation   +9 added lines, -9 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
 /**
@@ -38,13 +38,13 @@  discard block
 block discarded – undo
38 38
  *     Description de la boucle complétée des champs
39 39
  */
40 40
 function iterateur_POUR_dist($b) {
41
-	$b->iterateur = 'DATA'; # designe la classe d'iterateur
42
-	$b->show = [
43
-		'field' => [
44
-			'cle' => 'STRING',
45
-			'valeur' => 'STRING',
46
-		]
47
-	];
41
+    $b->iterateur = 'DATA'; # designe la classe d'iterateur
42
+    $b->show = [
43
+        'field' => [
44
+            'cle' => 'STRING',
45
+            'valeur' => 'STRING',
46
+        ]
47
+    ];
48 48
 
49
-	return $b;
49
+    return $b;
50 50
 }
Please login to merge, or discard this patch.
ecrire/iterateur/php.php 1 patch
Indentation   +14 added lines, -14 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
 
@@ -38,17 +38,17 @@  discard block
 block discarded – undo
38 38
  *     Description de la boucle complétée des champs
39 39
  */
40 40
 function iterateur_php_dist($b, $iteratorName) {
41
-	$b->iterateur = $iteratorName; # designe la classe d'iterateur
42
-	$b->show = [
43
-		'field' => [
44
-			'cle' => 'STRING',
45
-			'valeur' => 'STRING',
46
-		]
47
-	];
48
-
49
-	foreach (get_class_methods($iteratorName) as $method) {
50
-		$b->show['field'][strtolower($method)] = 'METHOD';
51
-	}
52
-
53
-	return $b;
41
+    $b->iterateur = $iteratorName; # designe la classe d'iterateur
42
+    $b->show = [
43
+        'field' => [
44
+            'cle' => 'STRING',
45
+            'valeur' => 'STRING',
46
+        ]
47
+    ];
48
+
49
+    foreach (get_class_methods($iteratorName) as $method) {
50
+        $b->show['field'][strtolower($method)] = 'METHOD';
51
+    }
52
+
53
+    return $b;
54 54
 }
Please login to merge, or discard this patch.