Completed
Push — master ( 3ef74e...08981b )
by cam
04:31
created
ecrire/public/phraser_html.php 2 patches
Indentation   +861 added lines, -861 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
 /** Début de la partie principale d'une boucle */
@@ -65,83 +65,83 @@  discard block
 block discarded – undo
65 65
 // https://code.spip.net/@phraser_inclure
66 66
 function phraser_inclure($texte, $ligne, $result) {
67 67
 
68
-	while (preg_match(BALISE_INCLURE, $texte, $match)) {
69
-		$match = array_pad($match, 3, null);
70
-		$p = strpos($texte, $match[0]);
71
-		$debut = substr($texte, 0, $p);
72
-		if ($p) {
73
-			$result = phraser_idiomes($debut, $ligne, $result);
74
-		}
75
-		$ligne += substr_count($debut, "\n");
76
-		$champ = new Inclure;
77
-		$champ->ligne = $ligne;
78
-		$ligne += substr_count($match[0], "\n");
79
-		$fichier = $match[2];
80
-		# assurer ici la migration .php3 => .php
81
-		# et de l'ancienne syntaxe INCLURE(page.php3) devenue surperflue
82
-		if ($fichier and preg_match(',^(.*[.]php)3$,', $fichier, $r)) {
83
-			$fichier = $r[1];
84
-		}
85
-		$champ->texte = ($fichier !== 'page.php') ? $fichier : '';
86
-		$texte = substr($texte, $p + strlen($match[0]));
87
-		// on assimile {var=val} a une liste de un argument sans fonction
88
-		phraser_args($texte, "/>", "", $result, $champ);
89
-		if (!$champ->texte or count($champ->param) > 1) {
90
-			if (!function_exists('normaliser_inclure')) {
91
-				include_spip('public/normaliser');
92
-			}
93
-			normaliser_inclure($champ);
94
-		}
95
-		$texte = substr($champ->apres, strpos($champ->apres, '>') + 1);
96
-		$champ->apres = "";
97
-		$texte = preg_replace(',^</INCLU[DR]E>,', '', $texte);
98
-		$result[] = $champ;
99
-	}
100
-
101
-	return (($texte === "") ? $result : phraser_idiomes($texte, $ligne, $result));
68
+    while (preg_match(BALISE_INCLURE, $texte, $match)) {
69
+        $match = array_pad($match, 3, null);
70
+        $p = strpos($texte, $match[0]);
71
+        $debut = substr($texte, 0, $p);
72
+        if ($p) {
73
+            $result = phraser_idiomes($debut, $ligne, $result);
74
+        }
75
+        $ligne += substr_count($debut, "\n");
76
+        $champ = new Inclure;
77
+        $champ->ligne = $ligne;
78
+        $ligne += substr_count($match[0], "\n");
79
+        $fichier = $match[2];
80
+        # assurer ici la migration .php3 => .php
81
+        # et de l'ancienne syntaxe INCLURE(page.php3) devenue surperflue
82
+        if ($fichier and preg_match(',^(.*[.]php)3$,', $fichier, $r)) {
83
+            $fichier = $r[1];
84
+        }
85
+        $champ->texte = ($fichier !== 'page.php') ? $fichier : '';
86
+        $texte = substr($texte, $p + strlen($match[0]));
87
+        // on assimile {var=val} a une liste de un argument sans fonction
88
+        phraser_args($texte, "/>", "", $result, $champ);
89
+        if (!$champ->texte or count($champ->param) > 1) {
90
+            if (!function_exists('normaliser_inclure')) {
91
+                include_spip('public/normaliser');
92
+            }
93
+            normaliser_inclure($champ);
94
+        }
95
+        $texte = substr($champ->apres, strpos($champ->apres, '>') + 1);
96
+        $champ->apres = "";
97
+        $texte = preg_replace(',^</INCLU[DR]E>,', '', $texte);
98
+        $result[] = $champ;
99
+    }
100
+
101
+    return (($texte === "") ? $result : phraser_idiomes($texte, $ligne, $result));
102 102
 }
103 103
 
104 104
 // https://code.spip.net/@phraser_polyglotte
105 105
 function phraser_polyglotte($texte, $ligne, $result) {
106 106
 
107
-	if (preg_match_all(BALISE_POLYGLOTTE, $texte, $m, PREG_SET_ORDER)) {
108
-		foreach ($m as $match) {
109
-			$p = strpos($texte, $match[0]);
110
-			$debut = substr($texte, 0, $p);
111
-			if ($p) {
112
-				$champ = new Texte;
113
-				$champ->texte = $debut;
114
-				$champ->ligne = $ligne;
115
-				$result[] = $champ;
116
-				$ligne += substr_count($champ->texte, "\n");
117
-			}
118
-
119
-			$champ = new Polyglotte;
120
-			$champ->ligne = $ligne;
121
-			$ligne += substr_count($match[0], "\n");
122
-			$lang = '';
123
-			$bloc = $match[1];
124
-			$texte = substr($texte, $p + strlen($match[0]));
125
-			while (preg_match("/^[[:space:]]*([^[{]*)[[:space:]]*[[{]([a-z_]+)[]}](.*)$/si", $bloc, $regs)) {
126
-				$trad = $regs[1];
127
-				if ($trad or $lang) {
128
-					$champ->traductions[$lang] = $trad;
129
-				}
130
-				$lang = $regs[2];
131
-				$bloc = $regs[3];
132
-			}
133
-			$champ->traductions[$lang] = $bloc;
134
-			$result[] = $champ;
135
-		}
136
-	}
137
-	if ($texte !== "") {
138
-		$champ = new Texte;
139
-		$champ->texte = $texte;
140
-		$champ->ligne = $ligne;
141
-		$result[] = $champ;
142
-	}
143
-
144
-	return $result;
107
+    if (preg_match_all(BALISE_POLYGLOTTE, $texte, $m, PREG_SET_ORDER)) {
108
+        foreach ($m as $match) {
109
+            $p = strpos($texte, $match[0]);
110
+            $debut = substr($texte, 0, $p);
111
+            if ($p) {
112
+                $champ = new Texte;
113
+                $champ->texte = $debut;
114
+                $champ->ligne = $ligne;
115
+                $result[] = $champ;
116
+                $ligne += substr_count($champ->texte, "\n");
117
+            }
118
+
119
+            $champ = new Polyglotte;
120
+            $champ->ligne = $ligne;
121
+            $ligne += substr_count($match[0], "\n");
122
+            $lang = '';
123
+            $bloc = $match[1];
124
+            $texte = substr($texte, $p + strlen($match[0]));
125
+            while (preg_match("/^[[:space:]]*([^[{]*)[[:space:]]*[[{]([a-z_]+)[]}](.*)$/si", $bloc, $regs)) {
126
+                $trad = $regs[1];
127
+                if ($trad or $lang) {
128
+                    $champ->traductions[$lang] = $trad;
129
+                }
130
+                $lang = $regs[2];
131
+                $bloc = $regs[3];
132
+            }
133
+            $champ->traductions[$lang] = $bloc;
134
+            $result[] = $champ;
135
+        }
136
+    }
137
+    if ($texte !== "") {
138
+        $champ = new Texte;
139
+        $champ->texte = $texte;
140
+        $champ->ligne = $ligne;
141
+        $result[] = $champ;
142
+    }
143
+
144
+    return $result;
145 145
 }
146 146
 
147 147
 
@@ -163,41 +163,41 @@  discard block
 block discarded – undo
163 163
  * @return array
164 164
  **/
165 165
 function phraser_idiomes($texte, $ligne, $result) {
166
-	while (preg_match(BALISE_IDIOMES, $texte, $match)) {
167
-		$match = array_pad($match, 8, null);
168
-		$p = strpos($texte, $match[0]);
169
-		$ko = (!$match[3] && ($match[5][0] !== '='));
170
-		$debut = substr($texte, 0, $p + ($ko ? strlen($match[0]) : 0));
171
-		if ($debut) {
172
-			$result = phraser_champs($debut, $ligne, $result);
173
-		}
174
-		$texte = substr($texte, $p + strlen($match[0]));
175
-		$ligne += substr_count($debut, "\n");
176
-		if ($ko) {
177
-			continue;
178
-		} // faux idiome
179
-		$champ = new Idiome;
180
-		$champ->ligne = $ligne;
181
-		$ligne += substr_count($match[0], "\n");
182
-		// Stocker les arguments de la balise de traduction
183
-		$args = array();
184
-		$largs = $match[5];
185
-		while (preg_match(BALISE_IDIOMES_ARGS, $largs, $r)) {
186
-			$args[$r[1]] = phraser_champs($r[2], 0, array());
187
-			$largs = substr($largs, strlen($r[0]));
188
-		}
189
-		$champ->arg = $args;
190
-		$champ->nom_champ = strtolower($match[3]);
191
-		$champ->module = $match[2];
192
-		// pas d'imbrication pour les filtres sur langue
193
-		phraser_args($match[7], ":", '', array(), $champ);
194
-		$result[] = $champ;
195
-	}
196
-	if ($texte !== "") {
197
-		$result = phraser_champs($texte, $ligne, $result);
198
-	}
199
-
200
-	return $result;
166
+    while (preg_match(BALISE_IDIOMES, $texte, $match)) {
167
+        $match = array_pad($match, 8, null);
168
+        $p = strpos($texte, $match[0]);
169
+        $ko = (!$match[3] && ($match[5][0] !== '='));
170
+        $debut = substr($texte, 0, $p + ($ko ? strlen($match[0]) : 0));
171
+        if ($debut) {
172
+            $result = phraser_champs($debut, $ligne, $result);
173
+        }
174
+        $texte = substr($texte, $p + strlen($match[0]));
175
+        $ligne += substr_count($debut, "\n");
176
+        if ($ko) {
177
+            continue;
178
+        } // faux idiome
179
+        $champ = new Idiome;
180
+        $champ->ligne = $ligne;
181
+        $ligne += substr_count($match[0], "\n");
182
+        // Stocker les arguments de la balise de traduction
183
+        $args = array();
184
+        $largs = $match[5];
185
+        while (preg_match(BALISE_IDIOMES_ARGS, $largs, $r)) {
186
+            $args[$r[1]] = phraser_champs($r[2], 0, array());
187
+            $largs = substr($largs, strlen($r[0]));
188
+        }
189
+        $champ->arg = $args;
190
+        $champ->nom_champ = strtolower($match[3]);
191
+        $champ->module = $match[2];
192
+        // pas d'imbrication pour les filtres sur langue
193
+        phraser_args($match[7], ":", '', array(), $champ);
194
+        $result[] = $champ;
195
+    }
196
+    if ($texte !== "") {
197
+        $result = phraser_champs($texte, $ligne, $result);
198
+    }
199
+
200
+    return $result;
201 201
 }
202 202
 
203 203
 /**
@@ -215,47 +215,47 @@  discard block
 block discarded – undo
215 215
  * @return array
216 216
  **/
217 217
 function phraser_champs($texte, $ligne, $result) {
218
-	while (preg_match("/" . NOM_DE_CHAMP . "/S", $texte, $match)) {
219
-		$p = strpos($texte, $match[0]);
220
-		// texte après la balise
221
-		$suite = substr($texte, $p + strlen($match[0]));
222
-
223
-		$debut = substr($texte, 0, $p);
224
-		if ($p) {
225
-			$result = phraser_polyglotte($debut, $ligne, $result);
226
-		}
227
-		$ligne += substr_count($debut, "\n");
228
-		$champ = new Champ;
229
-		$champ->ligne = $ligne;
230
-		$ligne += substr_count($match[0], "\n");
231
-		$champ->nom_boucle = $match[2];
232
-		$champ->nom_champ = $match[3];
233
-		$champ->etoile = $match[5];
234
-
235
-		if ($suite and $suite[0] == '{') {
236
-			phraser_arg($suite, '', array(), $champ);
237
-			// ce ltrim est une ereur de conception
238
-			// mais on le conserve par souci de compatibilite
239
-			$texte = ltrim($suite);
240
-			// Il faudrait le normaliser dans l'arbre de syntaxe abstraite
241
-			// pour faire sauter ce cas particulier a la decompilation.
242
-			/* Ce qui suit est malheureusement incomplet pour cela:
218
+    while (preg_match("/" . NOM_DE_CHAMP . "/S", $texte, $match)) {
219
+        $p = strpos($texte, $match[0]);
220
+        // texte après la balise
221
+        $suite = substr($texte, $p + strlen($match[0]));
222
+
223
+        $debut = substr($texte, 0, $p);
224
+        if ($p) {
225
+            $result = phraser_polyglotte($debut, $ligne, $result);
226
+        }
227
+        $ligne += substr_count($debut, "\n");
228
+        $champ = new Champ;
229
+        $champ->ligne = $ligne;
230
+        $ligne += substr_count($match[0], "\n");
231
+        $champ->nom_boucle = $match[2];
232
+        $champ->nom_champ = $match[3];
233
+        $champ->etoile = $match[5];
234
+
235
+        if ($suite and $suite[0] == '{') {
236
+            phraser_arg($suite, '', array(), $champ);
237
+            // ce ltrim est une ereur de conception
238
+            // mais on le conserve par souci de compatibilite
239
+            $texte = ltrim($suite);
240
+            // Il faudrait le normaliser dans l'arbre de syntaxe abstraite
241
+            // pour faire sauter ce cas particulier a la decompilation.
242
+            /* Ce qui suit est malheureusement incomplet pour cela:
243 243
 			if ($n = (strlen($suite) - strlen($texte))) {
244 244
 				$champ->apres = array(new Texte);
245 245
 				$champ->apres[0]->texte = substr($suite,0,$n);
246 246
 			}
247 247
 			*/
248
-		} else {
249
-			$texte = $suite;
250
-		}
251
-		phraser_vieux($champ);
252
-		$result[] = $champ;
253
-	}
254
-	if ($texte !== "") {
255
-		$result = phraser_polyglotte($texte, $ligne, $result);
256
-	}
257
-
258
-	return $result;
248
+        } else {
249
+            $texte = $suite;
250
+        }
251
+        phraser_vieux($champ);
252
+        $result[] = $champ;
253
+    }
254
+    if ($texte !== "") {
255
+        $result = phraser_polyglotte($texte, $ligne, $result);
256
+    }
257
+
258
+    return $result;
259 259
 }
260 260
 
261 261
 // Gestion des imbrications:
@@ -265,15 +265,15 @@  discard block
 block discarded – undo
265 265
 
266 266
 // https://code.spip.net/@phraser_champs_etendus
267 267
 function phraser_champs_etendus($texte, $ligne, $result) {
268
-	if ($texte === "") {
269
-		return $result;
270
-	}
271
-	$sep = '##';
272
-	while (strpos($texte, $sep) !== false) {
273
-		$sep .= '#';
274
-	}
275
-
276
-	return array_merge($result, phraser_champs_interieurs($texte, $ligne, $sep, array()));
268
+    if ($texte === "") {
269
+        return $result;
270
+    }
271
+    $sep = '##';
272
+    while (strpos($texte, $sep) !== false) {
273
+        $sep .= '#';
274
+    }
275
+
276
+    return array_merge($result, phraser_champs_interieurs($texte, $ligne, $sep, array()));
277 277
 }
278 278
 
279 279
 /**
@@ -293,270 +293,270 @@  discard block
 block discarded – undo
293 293
  * @return array
294 294
  */
295 295
 function phraser_args($texte, $fin, $sep, $result, &$pointeur_champ) {
296
-	$texte = ltrim($texte);
297
-	while (($texte !== "") && strpos($fin, $texte[0]) === false) {
298
-		$result = phraser_arg($texte, $sep, $result, $pointeur_champ);
299
-		$texte = ltrim($texte);
300
-	}
296
+    $texte = ltrim($texte);
297
+    while (($texte !== "") && strpos($fin, $texte[0]) === false) {
298
+        $result = phraser_arg($texte, $sep, $result, $pointeur_champ);
299
+        $texte = ltrim($texte);
300
+    }
301 301
 # mettre ici la suite du texte, 
302 302
 # notamment pour que l'appelant vire le caractere fermant si besoin
303
-	$pointeur_champ->apres = $texte;
303
+    $pointeur_champ->apres = $texte;
304 304
 
305
-	return $result;
305
+    return $result;
306 306
 }
307 307
 
308 308
 // https://code.spip.net/@phraser_arg
309 309
 function phraser_arg(&$texte, $sep, $result, &$pointeur_champ) {
310
-	preg_match(",^(\|?[^}{)|]*)(.*)$,ms", $texte, $match);
311
-	$suite = ltrim($match[2]);
312
-	$fonc = trim($match[1]);
313
-	if ($fonc && $fonc[0] == "|") {
314
-		$fonc = ltrim(substr($fonc, 1));
315
-	}
316
-	$res = array($fonc);
317
-	$err_f = '';
318
-	// cas du filtre sans argument ou du critere /
319
-	if (($suite && ($suite[0] != '{')) || ($fonc && $fonc[0] == '/')) {
320
-		// si pas d'argument, alors il faut une fonction ou un double |
321
-		if (!$match[1]) {
322
-			$err_f = array('zbug_erreur_filtre', array('filtre' => $texte));
323
-			erreur_squelette($err_f, $pointeur_champ);
324
-			$texte = '';
325
-		} else {
326
-			$texte = $suite;
327
-		}
328
-		if ($err_f) {
329
-			$pointeur_champ->param = false;
330
-		} elseif ($fonc !== '') {
331
-			$pointeur_champ->param[] = $res;
332
-		}
333
-		// pour les balises avec faux filtres qui boudent ce dur larbeur
334
-		$pointeur_champ->fonctions[] = array($fonc, '');
335
-
336
-		return $result;
337
-	}
338
-	$args = ltrim(substr($suite, 1)); // virer le '(' initial
339
-	$collecte = array();
340
-	while ($args && $args[0] != '}') {
341
-		if ($args[0] == '"') {
342
-			preg_match('/^(")([^"]*)(")(.*)$/ms', $args, $regs);
343
-		} elseif ($args[0] == "'") {
344
-			preg_match("/^(')([^']*)(')(.*)$/ms", $args, $regs);
345
-		} else {
346
-			preg_match("/^([[:space:]]*)([^,([{}]*([(\[{][^])}]*[])}])?[^,}]*)([,}].*)$/ms", $args, $regs);
347
-			if (!strlen($regs[2])) {
348
-				$err_f = array('zbug_erreur_filtre', array('filtre' => $args));
349
-				erreur_squelette($err_f, $pointeur_champ);
350
-				$champ = new Texte;
351
-				$champ->apres = $champ->avant = $args = "";
352
-				break;
353
-			}
354
-		}
355
-		$arg = $regs[2];
356
-		if (trim($regs[1])) {
357
-			$champ = new Texte;
358
-			$champ->texte = $arg;
359
-			$champ->apres = $champ->avant = $regs[1];
360
-			$result[] = $champ;
361
-			$collecte[] = $champ;
362
-			$args = ltrim($regs[count($regs) - 1]);
363
-		} else {
364
-			if (!preg_match("/" . NOM_DE_CHAMP . "([{|])/", $arg, $r)) {
365
-				// 0 est un aveu d'impuissance. A completer
366
-				$arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
367
-
368
-				$args = ltrim($regs[count($regs) - 1]);
369
-				$collecte = array_merge($collecte, $arg);
370
-				$result = array_merge($result, $arg);
371
-			} else {
372
-				$n = strpos($args, $r[0]);
373
-				$pred = substr($args, 0, $n);
374
-				$par = ',}';
375
-				if (preg_match('/^(.*)\($/', $pred, $m)) {
376
-					$pred = $m[1];
377
-					$par = ')';
378
-				}
379
-				if ($pred) {
380
-					$champ = new Texte;
381
-					$champ->texte = $pred;
382
-					$champ->apres = $champ->avant = "";
383
-					$result[] = $champ;
384
-					$collecte[] = $champ;
385
-				}
386
-				$rec = substr($args, $n + strlen($r[0]) - 1);
387
-				$champ = new Champ;
388
-				$champ->nom_boucle = $r[2];
389
-				$champ->nom_champ = $r[3];
390
-				$champ->etoile = $r[5];
391
-				$next = $r[6];
392
-				while ($next == '{') {
393
-					phraser_arg($rec, $sep, array(), $champ);
394
-					$args = ltrim($rec);
395
-					$next = isset($args[0]) ? $args[0] : '';
396
-				}
397
-				while ($next == '|') {
398
-					phraser_args($rec, $par, $sep, array(), $champ);
399
-					$args = $champ->apres;
400
-					$champ->apres = '';
401
-					$next = isset($args[0]) ? $args[0] : '';
402
-				}
403
-				// Si erreur de syntaxe dans un sous-argument, propager.
404
-				if ($champ->param === false) {
405
-					$err_f = true;
406
-				} else {
407
-					phraser_vieux($champ);
408
-				}
409
-				if ($par == ')') {
410
-					$args = substr($args, 1);
411
-				}
412
-				$collecte[] = $champ;
413
-				$result[] = $champ;
414
-			}
415
-		}
416
-		if (isset($args[0]) and $args[0] == ',') {
417
-			$args = ltrim(substr($args, 1));
418
-			if ($collecte) {
419
-				$res[] = $collecte;
420
-				$collecte = array();
421
-			}
422
-		}
423
-	}
424
-	if ($collecte) {
425
-		$res[] = $collecte;
426
-		$collecte = array();
427
-	}
428
-	$texte = substr($args, 1);
429
-	$source = substr($suite, 0, strlen($suite) - strlen($texte));
430
-	// propager les erreurs, et ignorer les param vides
431
-	if ($pointeur_champ->param !== false) {
432
-		if ($err_f) {
433
-			$pointeur_champ->param = false;
434
-		} elseif ($fonc !== '' || count($res) > 1) {
435
-			$pointeur_champ->param[] = $res;
436
-		}
437
-	}
438
-	// pour les balises avec faux filtres qui boudent ce dur larbeur
439
-	$pointeur_champ->fonctions[] = array($fonc, $source);
440
-
441
-	return $result;
310
+    preg_match(",^(\|?[^}{)|]*)(.*)$,ms", $texte, $match);
311
+    $suite = ltrim($match[2]);
312
+    $fonc = trim($match[1]);
313
+    if ($fonc && $fonc[0] == "|") {
314
+        $fonc = ltrim(substr($fonc, 1));
315
+    }
316
+    $res = array($fonc);
317
+    $err_f = '';
318
+    // cas du filtre sans argument ou du critere /
319
+    if (($suite && ($suite[0] != '{')) || ($fonc && $fonc[0] == '/')) {
320
+        // si pas d'argument, alors il faut une fonction ou un double |
321
+        if (!$match[1]) {
322
+            $err_f = array('zbug_erreur_filtre', array('filtre' => $texte));
323
+            erreur_squelette($err_f, $pointeur_champ);
324
+            $texte = '';
325
+        } else {
326
+            $texte = $suite;
327
+        }
328
+        if ($err_f) {
329
+            $pointeur_champ->param = false;
330
+        } elseif ($fonc !== '') {
331
+            $pointeur_champ->param[] = $res;
332
+        }
333
+        // pour les balises avec faux filtres qui boudent ce dur larbeur
334
+        $pointeur_champ->fonctions[] = array($fonc, '');
335
+
336
+        return $result;
337
+    }
338
+    $args = ltrim(substr($suite, 1)); // virer le '(' initial
339
+    $collecte = array();
340
+    while ($args && $args[0] != '}') {
341
+        if ($args[0] == '"') {
342
+            preg_match('/^(")([^"]*)(")(.*)$/ms', $args, $regs);
343
+        } elseif ($args[0] == "'") {
344
+            preg_match("/^(')([^']*)(')(.*)$/ms", $args, $regs);
345
+        } else {
346
+            preg_match("/^([[:space:]]*)([^,([{}]*([(\[{][^])}]*[])}])?[^,}]*)([,}].*)$/ms", $args, $regs);
347
+            if (!strlen($regs[2])) {
348
+                $err_f = array('zbug_erreur_filtre', array('filtre' => $args));
349
+                erreur_squelette($err_f, $pointeur_champ);
350
+                $champ = new Texte;
351
+                $champ->apres = $champ->avant = $args = "";
352
+                break;
353
+            }
354
+        }
355
+        $arg = $regs[2];
356
+        if (trim($regs[1])) {
357
+            $champ = new Texte;
358
+            $champ->texte = $arg;
359
+            $champ->apres = $champ->avant = $regs[1];
360
+            $result[] = $champ;
361
+            $collecte[] = $champ;
362
+            $args = ltrim($regs[count($regs) - 1]);
363
+        } else {
364
+            if (!preg_match("/" . NOM_DE_CHAMP . "([{|])/", $arg, $r)) {
365
+                // 0 est un aveu d'impuissance. A completer
366
+                $arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
367
+
368
+                $args = ltrim($regs[count($regs) - 1]);
369
+                $collecte = array_merge($collecte, $arg);
370
+                $result = array_merge($result, $arg);
371
+            } else {
372
+                $n = strpos($args, $r[0]);
373
+                $pred = substr($args, 0, $n);
374
+                $par = ',}';
375
+                if (preg_match('/^(.*)\($/', $pred, $m)) {
376
+                    $pred = $m[1];
377
+                    $par = ')';
378
+                }
379
+                if ($pred) {
380
+                    $champ = new Texte;
381
+                    $champ->texte = $pred;
382
+                    $champ->apres = $champ->avant = "";
383
+                    $result[] = $champ;
384
+                    $collecte[] = $champ;
385
+                }
386
+                $rec = substr($args, $n + strlen($r[0]) - 1);
387
+                $champ = new Champ;
388
+                $champ->nom_boucle = $r[2];
389
+                $champ->nom_champ = $r[3];
390
+                $champ->etoile = $r[5];
391
+                $next = $r[6];
392
+                while ($next == '{') {
393
+                    phraser_arg($rec, $sep, array(), $champ);
394
+                    $args = ltrim($rec);
395
+                    $next = isset($args[0]) ? $args[0] : '';
396
+                }
397
+                while ($next == '|') {
398
+                    phraser_args($rec, $par, $sep, array(), $champ);
399
+                    $args = $champ->apres;
400
+                    $champ->apres = '';
401
+                    $next = isset($args[0]) ? $args[0] : '';
402
+                }
403
+                // Si erreur de syntaxe dans un sous-argument, propager.
404
+                if ($champ->param === false) {
405
+                    $err_f = true;
406
+                } else {
407
+                    phraser_vieux($champ);
408
+                }
409
+                if ($par == ')') {
410
+                    $args = substr($args, 1);
411
+                }
412
+                $collecte[] = $champ;
413
+                $result[] = $champ;
414
+            }
415
+        }
416
+        if (isset($args[0]) and $args[0] == ',') {
417
+            $args = ltrim(substr($args, 1));
418
+            if ($collecte) {
419
+                $res[] = $collecte;
420
+                $collecte = array();
421
+            }
422
+        }
423
+    }
424
+    if ($collecte) {
425
+        $res[] = $collecte;
426
+        $collecte = array();
427
+    }
428
+    $texte = substr($args, 1);
429
+    $source = substr($suite, 0, strlen($suite) - strlen($texte));
430
+    // propager les erreurs, et ignorer les param vides
431
+    if ($pointeur_champ->param !== false) {
432
+        if ($err_f) {
433
+            $pointeur_champ->param = false;
434
+        } elseif ($fonc !== '' || count($res) > 1) {
435
+            $pointeur_champ->param[] = $res;
436
+        }
437
+    }
438
+    // pour les balises avec faux filtres qui boudent ce dur larbeur
439
+    $pointeur_champ->fonctions[] = array($fonc, $source);
440
+
441
+    return $result;
442 442
 }
443 443
 
444 444
 
445 445
 // https://code.spip.net/@phraser_champs_exterieurs
446 446
 function phraser_champs_exterieurs($texte, $ligne, $sep, $nested) {
447
-	$res = array();
448
-	while (($p = strpos($texte, "%$sep")) !== false) {
449
-		if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
450
-			break;
451
-		}
452
-		$debut = substr($texte, 0, $p);
453
-		$texte = substr($texte, $p + strlen($m[0]));
454
-		if ($p) {
455
-			$res = phraser_inclure($debut, $ligne, $res);
456
-		}
457
-		$ligne += substr_count($debut, "\n");
458
-		$res[] = $nested[$m[1]];
459
-	}
460
-
461
-	return (($texte === '') ? $res : phraser_inclure($texte, $ligne, $res));
447
+    $res = array();
448
+    while (($p = strpos($texte, "%$sep")) !== false) {
449
+        if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
450
+            break;
451
+        }
452
+        $debut = substr($texte, 0, $p);
453
+        $texte = substr($texte, $p + strlen($m[0]));
454
+        if ($p) {
455
+            $res = phraser_inclure($debut, $ligne, $res);
456
+        }
457
+        $ligne += substr_count($debut, "\n");
458
+        $res[] = $nested[$m[1]];
459
+    }
460
+
461
+    return (($texte === '') ? $res : phraser_inclure($texte, $ligne, $res));
462 462
 }
463 463
 
464 464
 // https://code.spip.net/@phraser_champs_interieurs
465 465
 function phraser_champs_interieurs($texte, $ligne, $sep, $result) {
466
-	$i = 0; // en fait count($result)
467
-	$x = "";
468
-
469
-	while (true) {
470
-		$j = $i;
471
-		$n = $ligne;
472
-		while (preg_match(CHAMP_ETENDU, $texte, $match)) {
473
-			$p = strpos($texte, $match[0]);
474
-			$debut = substr($texte, 0, $p);
475
-			if ($p) {
476
-				$result[$i] = $debut;
477
-				$i++;
478
-			}
479
-			$nom = $match[4];
480
-			$champ = new Champ;
481
-			// ca ne marche pas encore en cas de champ imbrique
482
-			$champ->ligne = $x ? 0 : ($n + substr_count($debut, "\n"));
483
-			$champ->nom_boucle = $match[3];
484
-			$champ->nom_champ = $nom;
485
-			$champ->etoile = $match[6];
486
-			// phraser_args indiquera ou commence apres
487
-			$result = phraser_args($match[7], ")", $sep, $result, $champ);
488
-			phraser_vieux($champ);
489
-			$champ->avant =
490
-				phraser_champs_exterieurs($match[1], $n, $sep, $result);
491
-			$debut = substr($champ->apres, 1);
492
-			if (!empty($debut)) {
493
-				$n += substr_count(substr($texte, 0, strpos($texte, $debut)), "\n");
494
-			}
495
-			$champ->apres = phraser_champs_exterieurs($debut, $n, $sep, $result);
496
-
497
-			$result[$i] = $champ;
498
-			$i++;
499
-			$texte = substr($texte, $p + strlen($match[0]));
500
-		}
501
-		if ($texte !== "") {
502
-			$result[$i] = $texte;
503
-			$i++;
504
-		}
505
-		$x = '';
506
-
507
-		while ($j < $i) {
508
-			$z = $result[$j];
509
-			// j'aurais besoin de connaitre le nombre de lignes...
510
-			if (is_object($z)) {
511
-				$x .= "%$sep$j@";
512
-			} else {
513
-				$x .= $z;
514
-			}
515
-			$j++;
516
-		}
517
-		if (preg_match(CHAMP_ETENDU, $x)) {
518
-			$texte = $x;
519
-		} else {
520
-			return phraser_champs_exterieurs($x, $ligne, $sep, $result);
521
-		}
522
-	}
466
+    $i = 0; // en fait count($result)
467
+    $x = "";
468
+
469
+    while (true) {
470
+        $j = $i;
471
+        $n = $ligne;
472
+        while (preg_match(CHAMP_ETENDU, $texte, $match)) {
473
+            $p = strpos($texte, $match[0]);
474
+            $debut = substr($texte, 0, $p);
475
+            if ($p) {
476
+                $result[$i] = $debut;
477
+                $i++;
478
+            }
479
+            $nom = $match[4];
480
+            $champ = new Champ;
481
+            // ca ne marche pas encore en cas de champ imbrique
482
+            $champ->ligne = $x ? 0 : ($n + substr_count($debut, "\n"));
483
+            $champ->nom_boucle = $match[3];
484
+            $champ->nom_champ = $nom;
485
+            $champ->etoile = $match[6];
486
+            // phraser_args indiquera ou commence apres
487
+            $result = phraser_args($match[7], ")", $sep, $result, $champ);
488
+            phraser_vieux($champ);
489
+            $champ->avant =
490
+                phraser_champs_exterieurs($match[1], $n, $sep, $result);
491
+            $debut = substr($champ->apres, 1);
492
+            if (!empty($debut)) {
493
+                $n += substr_count(substr($texte, 0, strpos($texte, $debut)), "\n");
494
+            }
495
+            $champ->apres = phraser_champs_exterieurs($debut, $n, $sep, $result);
496
+
497
+            $result[$i] = $champ;
498
+            $i++;
499
+            $texte = substr($texte, $p + strlen($match[0]));
500
+        }
501
+        if ($texte !== "") {
502
+            $result[$i] = $texte;
503
+            $i++;
504
+        }
505
+        $x = '';
506
+
507
+        while ($j < $i) {
508
+            $z = $result[$j];
509
+            // j'aurais besoin de connaitre le nombre de lignes...
510
+            if (is_object($z)) {
511
+                $x .= "%$sep$j@";
512
+            } else {
513
+                $x .= $z;
514
+            }
515
+            $j++;
516
+        }
517
+        if (preg_match(CHAMP_ETENDU, $x)) {
518
+            $texte = $x;
519
+        } else {
520
+            return phraser_champs_exterieurs($x, $ligne, $sep, $result);
521
+        }
522
+    }
523 523
 }
524 524
 
525 525
 function phraser_vieux(&$champ) {
526
-	$nom = $champ->nom_champ;
527
-	if ($nom == 'EMBED_DOCUMENT') {
528
-		if (!function_exists('phraser_vieux_emb')) {
529
-			include_spip('public/normaliser');
530
-		}
531
-		phraser_vieux_emb($champ);
532
-	} elseif ($nom == 'EXPOSER') {
533
-		if (!function_exists('phraser_vieux_exposer')) {
534
-			include_spip('public/normaliser');
535
-		}
536
-		phraser_vieux_exposer($champ);
537
-	} elseif ($champ->param) {
538
-		if ($nom == 'FORMULAIRE_RECHERCHE') {
539
-			if (!function_exists('phraser_vieux_recherche')) {
540
-				include_spip('public/normaliser');
541
-			}
542
-			phraser_vieux_recherche($champ);
543
-		} elseif (preg_match(",^LOGO_[A-Z]+,", $nom)) {
544
-			if (!function_exists('phraser_vieux_logos')) {
545
-				include_spip('public/normaliser');
546
-			}
547
-			phraser_vieux_logos($champ);
548
-		} elseif ($nom == 'MODELE') {
549
-			if (!function_exists('phraser_vieux_modele')) {
550
-				include_spip('public/normaliser');
551
-			}
552
-			phraser_vieux_modele($champ);
553
-		} elseif ($nom == 'INCLURE' or $nom == 'INCLUDE') {
554
-			if (!function_exists('phraser_vieux_inclu')) {
555
-				include_spip('public/normaliser');
556
-			}
557
-			phraser_vieux_inclu($champ);
558
-		}
559
-	}
526
+    $nom = $champ->nom_champ;
527
+    if ($nom == 'EMBED_DOCUMENT') {
528
+        if (!function_exists('phraser_vieux_emb')) {
529
+            include_spip('public/normaliser');
530
+        }
531
+        phraser_vieux_emb($champ);
532
+    } elseif ($nom == 'EXPOSER') {
533
+        if (!function_exists('phraser_vieux_exposer')) {
534
+            include_spip('public/normaliser');
535
+        }
536
+        phraser_vieux_exposer($champ);
537
+    } elseif ($champ->param) {
538
+        if ($nom == 'FORMULAIRE_RECHERCHE') {
539
+            if (!function_exists('phraser_vieux_recherche')) {
540
+                include_spip('public/normaliser');
541
+            }
542
+            phraser_vieux_recherche($champ);
543
+        } elseif (preg_match(",^LOGO_[A-Z]+,", $nom)) {
544
+            if (!function_exists('phraser_vieux_logos')) {
545
+                include_spip('public/normaliser');
546
+            }
547
+            phraser_vieux_logos($champ);
548
+        } elseif ($nom == 'MODELE') {
549
+            if (!function_exists('phraser_vieux_modele')) {
550
+                include_spip('public/normaliser');
551
+            }
552
+            phraser_vieux_modele($champ);
553
+        } elseif ($nom == 'INCLURE' or $nom == 'INCLUDE') {
554
+            if (!function_exists('phraser_vieux_inclu')) {
555
+                include_spip('public/normaliser');
556
+            }
557
+            phraser_vieux_inclu($champ);
558
+        }
559
+    }
560 560
 }
561 561
 
562 562
 
@@ -584,190 +584,190 @@  discard block
 block discarded – undo
584 584
  **/
585 585
 function phraser_criteres($params, &$result) {
586 586
 
587
-	$err_ci = ''; // indiquera s'il y a eu une erreur
588
-	$args = array();
589
-	$type = $result->type_requete;
590
-	$doublons = array();
591
-	foreach ($params as $v) {
592
-		$var = $v[1][0];
593
-		$param = ($var->type != 'texte') ? "" : $var->texte;
594
-		if ((count($v) > 2) && (!preg_match(",[^A-Za-z]IN[^A-Za-z],i", $param))) {
595
-			// plus d'un argument et pas le critere IN:
596
-			// detecter comme on peut si c'est le critere implicite LIMIT debut, fin
597
-			if ($var->type != 'texte'
598
-				or preg_match("/^(n|n-|(n-)?\d+)$/S", $param)
599
-			) {
600
-				$op = ',';
601
-				$not = "";
602
-				$cond = false;
603
-			} else {
604
-				// Le debut du premier argument est l'operateur
605
-				preg_match("/^([!]?)([a-zA-Z][a-zA-Z0-9_]*)[[:space:]]*(\??)[[:space:]]*(.*)$/ms", $param, $m);
606
-				$op = $m[2];
607
-				$not = $m[1];
608
-				$cond = $m[3];
609
-				// virer le premier argument,
610
-				// et mettre son reliquat eventuel
611
-				// Recopier pour ne pas alterer le texte source
612
-				// utile au debusqueur
613
-				if ($m[4]) {
614
-					// une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
615
-					if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
616
-						$c = null;
617
-						eval('$c = ' . $m[4] . ';');
618
-						if (isset($c)) {
619
-							$m[4] = $c;
620
-						}
621
-					}
622
-					$texte = new Texte;
623
-					$texte->texte = $m[4];
624
-					$v[1][0] = $texte;
625
-				} else {
626
-					array_shift($v[1]);
627
-				}
628
-			}
629
-			array_shift($v); // $v[O] est vide
630
-			$crit = new Critere;
631
-			$crit->op = $op;
632
-			$crit->not = $not;
633
-			$crit->cond = $cond;
634
-			$crit->exclus = "";
635
-			$crit->param = $v;
636
-			$args[] = $crit;
637
-		} else {
638
-			if ($var->type != 'texte') {
639
-				// cas 1 seul arg ne commencant pas par du texte brut: 
640
-				// erreur ou critere infixe "/"
641
-				if (($v[1][1]->type != 'texte') || (trim($v[1][1]->texte) != '/')) {
642
-					$err_ci = array(
643
-						'zbug_critere_inconnu',
644
-						array('critere' => $var->nom_champ)
645
-					);
646
-					erreur_squelette($err_ci, $result);
647
-				} else {
648
-					$crit = new Critere;
649
-					$crit->op = '/';
650
-					$crit->not = "";
651
-					$crit->exclus = "";
652
-					$crit->param = array(array($v[1][0]), array($v[1][2]));
653
-					$args[] = $crit;
654
-				}
655
-			} else {
656
-				// traiter qq lexemes particuliers pour faciliter la suite
657
-				// les separateurs
658
-				if ($var->apres) {
659
-					$result->separateur[] = $param;
660
-				} elseif (($param == 'tout') or ($param == 'tous')) {
661
-					$result->modificateur['tout'] = true;
662
-				} elseif ($param == 'plat') {
663
-					$result->modificateur['plat'] = true;
664
-				}
665
-
666
-				// Boucle hierarchie, analyser le critere id_rubrique
667
-				// et les autres critères {id_x} pour forcer {tout} sur
668
-				// ceux-ci pour avoir la rubrique mere...
669
-				// Les autres critères de la boucle hierarchie doivent être
670
-				// traités normalement.
671
-				elseif (strcasecmp($type, 'hierarchie') == 0
672
-					and !preg_match(",^id_rubrique\b,", $param)
673
-					and preg_match(",^id_\w+\s*$,", $param)
674
-				) {
675
-					$result->modificateur['tout'] = true;
676
-				} elseif (strcasecmp($type, 'hierarchie') == 0 and $param == "id_rubrique") {
677
-					// rien a faire sur {id_rubrique} tout seul
678
-				} else {
679
-					// pas d'emplacement statique, faut un dynamique
680
-					// mais il y a 2 cas qui ont les 2 !
681
-					if (($param == 'unique') || (preg_match(',^!?doublons *,', $param))) {
682
-						// cette variable sera inseree dans le code
683
-						// et son nom sert d'indicateur des maintenant
684
-						$result->doublons = '$doublons_index';
685
-						if ($param == 'unique') {
686
-							$param = 'doublons';
687
-						}
688
-					} elseif ($param == 'recherche') {
689
-						// meme chose (a cause de #nom_de_boucle:URL_*)
690
-						$result->hash = ' ';
691
-					}
692
-
693
-					if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
694
-						$crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
695
-					} elseif (preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
696
-						')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)) {
697
-						$a2 = trim($m[8]);
698
-						if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and ($a2[0] == substr($a2, -1))) {
699
-							$a2 = substr($a2, 1, -1);
700
-						}
701
-						$crit = phraser_critere_infixe($m[2], $a2, $v,
702
-							(($m[2] == 'lang_select') ? $m[2] : $m[7]),
703
-							$m[6], $m[5]);
704
-						$crit->exclus = $m[1];
705
-					} elseif (preg_match("/^([!]?)\s*(" .
706
-						CHAMP_SQL_PLUS_FONC .
707
-						")\s*(\??)(.*)$/is", $param, $m)) {
708
-						// contient aussi les comparaisons implicites !
709
-						// Comme ci-dessus: 
710
-						// le premier arg contient l'operateur
711
-						array_shift($v);
712
-						if ($m[6]) {
713
-							$v[0][0] = new Texte;
714
-							$v[0][0]->texte = $m[6];
715
-						} else {
716
-							array_shift($v[0]);
717
-							if (!$v[0]) {
718
-								array_shift($v);
719
-							}
720
-						}
721
-						$crit = new Critere;
722
-						$crit->op = $m[2];
723
-						$crit->param = $v;
724
-						$crit->not = $m[1];
725
-						$crit->cond = $m[5];
726
-					} else {
727
-						$err_ci = array(
728
-							'zbug_critere_inconnu',
729
-							array('critere' => $param)
730
-						);
731
-						erreur_squelette($err_ci, $result);
732
-					}
733
-
734
-					if ((!preg_match(',^!?doublons *,', $param)) || $crit->not) {
735
-						$args[] = $crit;
736
-					} else {
737
-						$doublons[] = $crit;
738
-					}
739
-				}
740
-			}
741
-		}
742
-	}
743
-
744
-	// les doublons non nies doivent etre le dernier critere
745
-	// pour que la variable $doublon_index ait la bonne valeur
746
-	// cf critere_doublon
747
-	if ($doublons) {
748
-		$args = array_merge($args, $doublons);
749
-	}
750
-
751
-	// Si erreur, laisser la chaine dans ce champ pour le HTTP 503
752
-	if (!$err_ci) {
753
-		$result->criteres = $args;
754
-	}
587
+    $err_ci = ''; // indiquera s'il y a eu une erreur
588
+    $args = array();
589
+    $type = $result->type_requete;
590
+    $doublons = array();
591
+    foreach ($params as $v) {
592
+        $var = $v[1][0];
593
+        $param = ($var->type != 'texte') ? "" : $var->texte;
594
+        if ((count($v) > 2) && (!preg_match(",[^A-Za-z]IN[^A-Za-z],i", $param))) {
595
+            // plus d'un argument et pas le critere IN:
596
+            // detecter comme on peut si c'est le critere implicite LIMIT debut, fin
597
+            if ($var->type != 'texte'
598
+                or preg_match("/^(n|n-|(n-)?\d+)$/S", $param)
599
+            ) {
600
+                $op = ',';
601
+                $not = "";
602
+                $cond = false;
603
+            } else {
604
+                // Le debut du premier argument est l'operateur
605
+                preg_match("/^([!]?)([a-zA-Z][a-zA-Z0-9_]*)[[:space:]]*(\??)[[:space:]]*(.*)$/ms", $param, $m);
606
+                $op = $m[2];
607
+                $not = $m[1];
608
+                $cond = $m[3];
609
+                // virer le premier argument,
610
+                // et mettre son reliquat eventuel
611
+                // Recopier pour ne pas alterer le texte source
612
+                // utile au debusqueur
613
+                if ($m[4]) {
614
+                    // une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
615
+                    if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
616
+                        $c = null;
617
+                        eval('$c = ' . $m[4] . ';');
618
+                        if (isset($c)) {
619
+                            $m[4] = $c;
620
+                        }
621
+                    }
622
+                    $texte = new Texte;
623
+                    $texte->texte = $m[4];
624
+                    $v[1][0] = $texte;
625
+                } else {
626
+                    array_shift($v[1]);
627
+                }
628
+            }
629
+            array_shift($v); // $v[O] est vide
630
+            $crit = new Critere;
631
+            $crit->op = $op;
632
+            $crit->not = $not;
633
+            $crit->cond = $cond;
634
+            $crit->exclus = "";
635
+            $crit->param = $v;
636
+            $args[] = $crit;
637
+        } else {
638
+            if ($var->type != 'texte') {
639
+                // cas 1 seul arg ne commencant pas par du texte brut: 
640
+                // erreur ou critere infixe "/"
641
+                if (($v[1][1]->type != 'texte') || (trim($v[1][1]->texte) != '/')) {
642
+                    $err_ci = array(
643
+                        'zbug_critere_inconnu',
644
+                        array('critere' => $var->nom_champ)
645
+                    );
646
+                    erreur_squelette($err_ci, $result);
647
+                } else {
648
+                    $crit = new Critere;
649
+                    $crit->op = '/';
650
+                    $crit->not = "";
651
+                    $crit->exclus = "";
652
+                    $crit->param = array(array($v[1][0]), array($v[1][2]));
653
+                    $args[] = $crit;
654
+                }
655
+            } else {
656
+                // traiter qq lexemes particuliers pour faciliter la suite
657
+                // les separateurs
658
+                if ($var->apres) {
659
+                    $result->separateur[] = $param;
660
+                } elseif (($param == 'tout') or ($param == 'tous')) {
661
+                    $result->modificateur['tout'] = true;
662
+                } elseif ($param == 'plat') {
663
+                    $result->modificateur['plat'] = true;
664
+                }
665
+
666
+                // Boucle hierarchie, analyser le critere id_rubrique
667
+                // et les autres critères {id_x} pour forcer {tout} sur
668
+                // ceux-ci pour avoir la rubrique mere...
669
+                // Les autres critères de la boucle hierarchie doivent être
670
+                // traités normalement.
671
+                elseif (strcasecmp($type, 'hierarchie') == 0
672
+                    and !preg_match(",^id_rubrique\b,", $param)
673
+                    and preg_match(",^id_\w+\s*$,", $param)
674
+                ) {
675
+                    $result->modificateur['tout'] = true;
676
+                } elseif (strcasecmp($type, 'hierarchie') == 0 and $param == "id_rubrique") {
677
+                    // rien a faire sur {id_rubrique} tout seul
678
+                } else {
679
+                    // pas d'emplacement statique, faut un dynamique
680
+                    // mais il y a 2 cas qui ont les 2 !
681
+                    if (($param == 'unique') || (preg_match(',^!?doublons *,', $param))) {
682
+                        // cette variable sera inseree dans le code
683
+                        // et son nom sert d'indicateur des maintenant
684
+                        $result->doublons = '$doublons_index';
685
+                        if ($param == 'unique') {
686
+                            $param = 'doublons';
687
+                        }
688
+                    } elseif ($param == 'recherche') {
689
+                        // meme chose (a cause de #nom_de_boucle:URL_*)
690
+                        $result->hash = ' ';
691
+                    }
692
+
693
+                    if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
694
+                        $crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
695
+                    } elseif (preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
696
+                        ')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)) {
697
+                        $a2 = trim($m[8]);
698
+                        if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and ($a2[0] == substr($a2, -1))) {
699
+                            $a2 = substr($a2, 1, -1);
700
+                        }
701
+                        $crit = phraser_critere_infixe($m[2], $a2, $v,
702
+                            (($m[2] == 'lang_select') ? $m[2] : $m[7]),
703
+                            $m[6], $m[5]);
704
+                        $crit->exclus = $m[1];
705
+                    } elseif (preg_match("/^([!]?)\s*(" .
706
+                        CHAMP_SQL_PLUS_FONC .
707
+                        ")\s*(\??)(.*)$/is", $param, $m)) {
708
+                        // contient aussi les comparaisons implicites !
709
+                        // Comme ci-dessus: 
710
+                        // le premier arg contient l'operateur
711
+                        array_shift($v);
712
+                        if ($m[6]) {
713
+                            $v[0][0] = new Texte;
714
+                            $v[0][0]->texte = $m[6];
715
+                        } else {
716
+                            array_shift($v[0]);
717
+                            if (!$v[0]) {
718
+                                array_shift($v);
719
+                            }
720
+                        }
721
+                        $crit = new Critere;
722
+                        $crit->op = $m[2];
723
+                        $crit->param = $v;
724
+                        $crit->not = $m[1];
725
+                        $crit->cond = $m[5];
726
+                    } else {
727
+                        $err_ci = array(
728
+                            'zbug_critere_inconnu',
729
+                            array('critere' => $param)
730
+                        );
731
+                        erreur_squelette($err_ci, $result);
732
+                    }
733
+
734
+                    if ((!preg_match(',^!?doublons *,', $param)) || $crit->not) {
735
+                        $args[] = $crit;
736
+                    } else {
737
+                        $doublons[] = $crit;
738
+                    }
739
+                }
740
+            }
741
+        }
742
+    }
743
+
744
+    // les doublons non nies doivent etre le dernier critere
745
+    // pour que la variable $doublon_index ait la bonne valeur
746
+    // cf critere_doublon
747
+    if ($doublons) {
748
+        $args = array_merge($args, $doublons);
749
+    }
750
+
751
+    // Si erreur, laisser la chaine dans ce champ pour le HTTP 503
752
+    if (!$err_ci) {
753
+        $result->criteres = $args;
754
+    }
755 755
 }
756 756
 
757 757
 // https://code.spip.net/@phraser_critere_infixe
758 758
 function phraser_critere_infixe($arg1, $arg2, $args, $op, $not, $cond) {
759
-	$args[0] = new Texte;
760
-	$args[0]->texte = $arg1;
761
-	$args[0] = array($args[0]);
762
-	$args[1][0] = new Texte;
763
-	$args[1][0]->texte = $arg2;
764
-	$crit = new Critere;
765
-	$crit->op = $op;
766
-	$crit->not = $not;
767
-	$crit->cond = $cond;
768
-	$crit->param = $args;
769
-
770
-	return $crit;
759
+    $args[0] = new Texte;
760
+    $args[0]->texte = $arg1;
761
+    $args[0] = array($args[0]);
762
+    $args[1][0] = new Texte;
763
+    $args[1][0]->texte = $arg2;
764
+    $crit = new Critere;
765
+    $crit->op = $op;
766
+    $crit->not = $not;
767
+    $crit->cond = $cond;
768
+    $crit->param = $args;
769
+
770
+    return $crit;
771 771
 }
772 772
 
773 773
 /**
@@ -778,12 +778,12 @@  discard block
 block discarded – undo
778 778
  * @return int
779 779
  */
780 780
 function public_compte_ligne($texte, $debut = 0, $longueur = null) {
781
-	if (is_null($longueur)) {
782
-		return substr_count($texte, "\n", $debut);
783
-	}
784
-	else {
785
-		return substr_count($texte, "\n", $debut, $longueur);
786
-	}
781
+    if (is_null($longueur)) {
782
+        return substr_count($texte, "\n", $debut);
783
+    }
784
+    else {
785
+        return substr_count($texte, "\n", $debut, $longueur);
786
+    }
787 787
 }
788 788
 
789 789
 
@@ -798,286 +798,286 @@  discard block
 block discarded – undo
798 798
  * @return array|null
799 799
  */
800 800
 function public_trouver_premiere_boucle($texte, $id_parent, $descr) {
801
-	$premiere_boucle = null;
802
-	$current_pos = 0;
803
-	while (($pos_boucle = strpos($texte, BALISE_BOUCLE, $current_pos)) !== false) {
804
-		$current_pos = $pos_boucle + 1;
805
-		$pos_parent = strpos($texte,'(', $pos_boucle);
806
-		if ($pos_parent === false
807
-		  or !$id_boucle = trim(substr($texte,$pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)))
808
-			or !(is_numeric($id_boucle) or strpos($id_boucle, '_') === 0)) {
809
-
810
-			$result = new Boucle;
811
-			$result->id_parent = $id_parent;
812
-			$result->descr = $descr;
813
-
814
-			// un id_boucle pour l'affichage de l'erreur
815
-			if (!$id_boucle) {
816
-				$id_boucle = substr($texte,$pos_boucle + strlen(BALISE_BOUCLE), 15);
817
-			}
818
-			$result->id_boucle = $id_boucle;
819
-			$err_b = array('zbug_erreur_boucle_syntaxe', array('id' => $id_boucle));
820
-			erreur_squelette($err_b, $result);
821
-
822
-			continue;
823
-		}
824
-		else {
825
-			$boucle = [
826
-				'id_boucle' => $id_boucle,
827
-				'debut_boucle' => $pos_boucle,
828
-				'pos_boucle' => $pos_boucle,
829
-				'pos_parent' => $pos_parent,
830
-				'pos_precond' => false,
831
-				'pos_precond_inside' => false,
832
-				'pos_preaff' => false,
833
-				'pos_preaff_inside' => false,
834
-			];
835
-
836
-			// trouver sa position de depart reelle : au <B_ ou au <BB_
837
-			$precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
838
-			$pos_precond = strpos($texte, $precond_boucle);
839
-			if ($pos_precond !== false and $pos_precond < $boucle['debut_boucle']) {
840
-				$boucle['debut_boucle'] = $pos_precond;
841
-				$boucle['pos_precond'] = $pos_precond;
842
-				$boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
843
-			}
844
-
845
-			$preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
846
-			$pos_preaff = strpos($texte, $preaff_boucle);
847
-			if ($pos_preaff !== false and $pos_preaff < $boucle['debut_boucle']) {
848
-				$boucle['debut_boucle'] = $pos_preaff;
849
-				$boucle['pos_preaff'] = $pos_preaff;
850
-				$boucle['pos_preaff_inside'] = $pos_preaff + strlen($preaff_boucle);
851
-			}
852
-
853
-			if (is_null($premiere_boucle) or $premiere_boucle['debut_boucle'] > $boucle['debut_boucle']) {
854
-				$premiere_boucle = $boucle;
855
-			}
856
-		}
857
-	}
858
-
859
-	return $premiere_boucle;
801
+    $premiere_boucle = null;
802
+    $current_pos = 0;
803
+    while (($pos_boucle = strpos($texte, BALISE_BOUCLE, $current_pos)) !== false) {
804
+        $current_pos = $pos_boucle + 1;
805
+        $pos_parent = strpos($texte,'(', $pos_boucle);
806
+        if ($pos_parent === false
807
+          or !$id_boucle = trim(substr($texte,$pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)))
808
+            or !(is_numeric($id_boucle) or strpos($id_boucle, '_') === 0)) {
809
+
810
+            $result = new Boucle;
811
+            $result->id_parent = $id_parent;
812
+            $result->descr = $descr;
813
+
814
+            // un id_boucle pour l'affichage de l'erreur
815
+            if (!$id_boucle) {
816
+                $id_boucle = substr($texte,$pos_boucle + strlen(BALISE_BOUCLE), 15);
817
+            }
818
+            $result->id_boucle = $id_boucle;
819
+            $err_b = array('zbug_erreur_boucle_syntaxe', array('id' => $id_boucle));
820
+            erreur_squelette($err_b, $result);
821
+
822
+            continue;
823
+        }
824
+        else {
825
+            $boucle = [
826
+                'id_boucle' => $id_boucle,
827
+                'debut_boucle' => $pos_boucle,
828
+                'pos_boucle' => $pos_boucle,
829
+                'pos_parent' => $pos_parent,
830
+                'pos_precond' => false,
831
+                'pos_precond_inside' => false,
832
+                'pos_preaff' => false,
833
+                'pos_preaff_inside' => false,
834
+            ];
835
+
836
+            // trouver sa position de depart reelle : au <B_ ou au <BB_
837
+            $precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
838
+            $pos_precond = strpos($texte, $precond_boucle);
839
+            if ($pos_precond !== false and $pos_precond < $boucle['debut_boucle']) {
840
+                $boucle['debut_boucle'] = $pos_precond;
841
+                $boucle['pos_precond'] = $pos_precond;
842
+                $boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
843
+            }
844
+
845
+            $preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
846
+            $pos_preaff = strpos($texte, $preaff_boucle);
847
+            if ($pos_preaff !== false and $pos_preaff < $boucle['debut_boucle']) {
848
+                $boucle['debut_boucle'] = $pos_preaff;
849
+                $boucle['pos_preaff'] = $pos_preaff;
850
+                $boucle['pos_preaff_inside'] = $pos_preaff + strlen($preaff_boucle);
851
+            }
852
+
853
+            if (is_null($premiere_boucle) or $premiere_boucle['debut_boucle'] > $boucle['debut_boucle']) {
854
+                $premiere_boucle = $boucle;
855
+            }
856
+        }
857
+    }
858
+
859
+    return $premiere_boucle;
860 860
 }
861 861
 
862 862
 
863 863
 function public_phraser_html_dist($texte, $id_parent, &$boucles, $descr, $ligne = 1) {
864 864
 
865
-	$all_res = array();
866
-
867
-	while ($boucle = public_trouver_premiere_boucle($texte, $id_parent, $descr)) {
868
-		$err_b = ''; // indiquera s'il y a eu une erreur
869
-		$result = new Boucle;
870
-		$result->id_parent = $id_parent;
871
-		$result->descr = $descr;
872
-
873
-		$pos_boucle = $boucle['pos_boucle'];
874
-		$id_boucle = $boucle['id_boucle'];
875
-		$pos_parent = $boucle['pos_parent'];
876
-
877
-		$ligne_preaff = $ligne_avant = $ligne_milieu = $ligne + public_compte_ligne($texte, 0, $pos_parent);
878
-		$pos_debut_boucle = $pos_boucle;
879
-		$milieu = substr($texte, $pos_parent);
880
-
881
-		// Regarder si on a une partie conditionnelle avant <B_xxx>
882
-		if ($boucle['pos_precond'] !== false) {
883
-
884
-			$pos_debut_boucle = $boucle['pos_precond'];
885
-
886
-			$pos_avant = $boucle['pos_precond_inside'];
887
-			$result->avant = substr($texte, $pos_avant, $pos_boucle - $pos_avant);
888
-			$ligne_avant = $ligne +  public_compte_ligne($texte,0, $pos_avant);
889
-		}
890
-
891
-		// Regarder si on a une partie inconditionnelle avant <BB_xxx>
892
-		if ($boucle['pos_preaff'] !== false) {
893
-
894
-			$end_preaff = $pos_debut_boucle;
895
-
896
-			$pos_preaff = $boucle['pos_preaff_inside'];
897
-			$result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
898
-			$ligne_preaff = $ligne +  public_compte_ligne($texte,0, $pos_preaff);
899
-		}
900
-
901
-		$debut = substr($texte, 0, $boucle['debut_boucle']);
902
-
903
-		$result->id_boucle = $id_boucle;
904
-
905
-		if (!preg_match(SPEC_BOUCLE, $milieu, $match)) {
906
-			$err_b = array('zbug_erreur_boucle_syntaxe', array('id' => $id_boucle));
907
-			erreur_squelette($err_b, $result);
908
-
909
-			$ligne += public_compte_ligne($texte, 0, $pos_boucle + 1);
910
-			$texte = substr($texte, $pos_boucle + 1);
911
-			continue;
912
-		}
913
-
914
-		$result->type_requete = $match[0];
915
-		$milieu = substr($milieu, strlen($match[0]));
916
-		$pos_boucle = $pos_parent + strlen($match[0]); // on s'en sert pour compter les lignes plus precisemment
917
-
918
-		$type = $match[1];
919
-		$jointures = trim($match[2]);
920
-		$table_optionnelle = ($match[3]);
921
-		if ($jointures) {
922
-			// on affecte pas ici les jointures explicites, mais dans la compilation
923
-			// ou elles seront completees des jointures declarees
924
-			$result->jointures_explicites = $jointures;
925
-		}
926
-
927
-		if ($table_optionnelle) {
928
-			$result->table_optionnelle = $type;
929
-		}
930
-
931
-		// 1ere passe sur les criteres, vu comme des arguments sans fct
932
-		// Resultat mis dans result->param
933
-		phraser_args($milieu, "/>", "", $all_res, $result);
934
-
935
-		// En 2e passe result->criteres contiendra un tableau
936
-		// pour l'instant on met le source (chaine) :
937
-		// si elle reste ici au final, c'est qu'elle contient une erreur
938
-		$pos_fin_criteres = strpos($milieu, $result->apres);
939
-		$pos_boucle += $pos_fin_criteres; // on s'en sert pour compter les lignes plus precisemment
940
-		$result->criteres = substr($milieu, 0, $pos_fin_criteres);
941
-		$milieu = $result->apres;
942
-		$result->apres = "";
943
-
944
-		//
945
-		// Recuperer la fin :
946
-		//
947
-		if ($milieu[0] === '/') {
948
-			// boucle autofermante : pas de partie conditionnelle apres
949
-			$suite = substr($milieu, 2);
950
-			$pos_boucle += 2;
951
-			$milieu = '';
952
-		} else {
953
-			$milieu = substr($milieu, 1);
954
-			$pos_boucle += 1;
955
-
956
-			$fin_boucle = BALISE_FIN_BOUCLE . $id_boucle . ">";
957
-			$pos_fin = strpos($milieu, $fin_boucle);
958
-			if ($pos_fin === false) {
959
-				$err_b = array(
960
-					'zbug_erreur_boucle_fermant',
961
-					array('id' => $id_boucle)
962
-				);
963
-				erreur_squelette($err_b, $result);
964
-			}
965
-
966
-			$pos_boucle += $pos_fin + strlen($fin_boucle);
967
-			$suite = substr($milieu, $pos_fin + strlen($fin_boucle));
968
-			$milieu = substr($milieu, 0, $pos_fin);
969
-		}
970
-
971
-		$result->milieu = $milieu;
972
-		$ligne_suite = $ligne_apres = $ligne + public_compte_ligne($texte, 0, $pos_boucle);
973
-
974
-		//
975
-		// 1. Recuperer la partie conditionnelle apres
976
-		//
977
-		$apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . ">";
978
-		$pos_apres = strpos($suite, $apres_boucle);
979
-		if ($pos_apres !== false) {
980
-			$result->apres = substr($suite, 0, $pos_apres);
981
-			$pos_apres += strlen($apres_boucle);
982
-			$suite = substr($suite, $pos_apres);
983
-			$ligne_suite += public_compte_ligne($texte, $pos_boucle, $pos_apres);
984
-			$pos_boucle += $pos_apres ;
985
-		}
986
-
987
-
988
-		//
989
-		// 2. Recuperer la partie alternative
990
-		//
991
-		$ligne_altern = $ligne_suite;
992
-		$altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . ">";
993
-		$pos_altern = strpos($suite, $altern_boucle);
994
-		if ($pos_altern !== false) {
995
-			$result->altern = substr($suite, 0, $pos_altern);
996
-			$pos_altern += strlen($altern_boucle);
997
-			$suite = substr($suite, $pos_altern);
998
-			$ligne_suite += public_compte_ligne($texte, $pos_boucle, $pos_altern);
999
-			$pos_boucle += $pos_altern;
1000
-		}
1001
-
1002
-		//
1003
-		// 3. Recuperer la partie footer non alternative
1004
-		//
1005
-		$ligne_postaff = $ligne_suite;
1006
-		$postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . ">";
1007
-		$pos_postaff = strpos($suite, $postaff_boucle);
1008
-		if ($pos_postaff !== false) {
1009
-			$result->postaff = substr($suite, 0, $pos_postaff);
1010
-			$pos_postaff += strlen($postaff_boucle);
1011
-			$suite = substr($suite, $pos_postaff);
1012
-			$ligne_suite += public_compte_ligne($texte, $pos_boucle, $pos_postaff);
1013
-			$pos_boucle += $pos_postaff ;
1014
-		}
1015
-
1016
-		$result->ligne = $ligne_preaff;
1017
-
1018
-		if ($p = strpos($type, ':')) {
1019
-			$result->sql_serveur = substr($type, 0, $p);
1020
-			$type = substr($type, $p + 1);
1021
-		}
1022
-		$soustype = strtolower($type);
1023
-
1024
-		if (!isset($GLOBALS["table_des_tables"][$soustype])) {
1025
-			$soustype = $type;
1026
-		}
1027
-
1028
-		$result->type_requete = $soustype;
1029
-		// Lancer la 2e passe sur les criteres si la 1ere etait bonne
1030
-		if (!is_array($result->param)) {
1031
-			$err_b = true;
1032
-		} else {
1033
-			phraser_criteres($result->param, $result);
1034
-			if (strncasecmp($soustype, TYPE_RECURSIF, strlen(TYPE_RECURSIF)) == 0) {
1035
-				$result->type_requete = TYPE_RECURSIF;
1036
-				$args = $result->param;
1037
-				array_unshift($args,
1038
-					substr($type, strlen(TYPE_RECURSIF)));
1039
-				$result->param = $args;
1040
-			}
1041
-		}
1042
-
1043
-		$descr['id_mere_contexte'] = $id_boucle;
1044
-		$result->milieu = public_phraser_html_dist($milieu, $id_boucle, $boucles, $descr, $ligne_milieu);
1045
-		// reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre
1046
-		// ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle
1047
-		// si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite
1048
-		if (empty($boucles[$id_boucle])){
1049
-			$boucles[$id_boucle] = null;
1050
-		}
1051
-		$result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff);
1052
-		$result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant);
1053
-		$result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres);
1054
-		$result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern);
1055
-		$result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff);
1056
-
1057
-		// Prevenir le generateur de code que le squelette est faux
1058
-		if ($err_b) {
1059
-			$result->type_requete = false;
1060
-		}
1061
-
1062
-		// Verifier qu'il n'y a pas double definition
1063
-		// apres analyse des sous-parties (pas avant).
1064
-		if (!empty($boucles[$id_boucle])) {
1065
-			$err_b_d = array(
1066
-				'zbug_erreur_boucle_double',
1067
-				array('id' => $id_boucle)
1068
-			);
1069
-			erreur_squelette($err_b_d, $result);
1070
-			// Prevenir le generateur de code que le squelette est faux
1071
-			$boucles[$id_boucle]->type_requete = false;
1072
-		} else {
1073
-			$boucles[$id_boucle] = $result;
1074
-		}
1075
-		$all_res = phraser_champs_etendus($debut, $ligne, $all_res);
1076
-		$all_res[] = &$boucles[$id_boucle];
1077
-
1078
-		$ligne = $ligne_suite;
1079
-		$texte = $suite;
1080
-	}
1081
-
1082
-	return phraser_champs_etendus($texte, $ligne, $all_res);
865
+    $all_res = array();
866
+
867
+    while ($boucle = public_trouver_premiere_boucle($texte, $id_parent, $descr)) {
868
+        $err_b = ''; // indiquera s'il y a eu une erreur
869
+        $result = new Boucle;
870
+        $result->id_parent = $id_parent;
871
+        $result->descr = $descr;
872
+
873
+        $pos_boucle = $boucle['pos_boucle'];
874
+        $id_boucle = $boucle['id_boucle'];
875
+        $pos_parent = $boucle['pos_parent'];
876
+
877
+        $ligne_preaff = $ligne_avant = $ligne_milieu = $ligne + public_compte_ligne($texte, 0, $pos_parent);
878
+        $pos_debut_boucle = $pos_boucle;
879
+        $milieu = substr($texte, $pos_parent);
880
+
881
+        // Regarder si on a une partie conditionnelle avant <B_xxx>
882
+        if ($boucle['pos_precond'] !== false) {
883
+
884
+            $pos_debut_boucle = $boucle['pos_precond'];
885
+
886
+            $pos_avant = $boucle['pos_precond_inside'];
887
+            $result->avant = substr($texte, $pos_avant, $pos_boucle - $pos_avant);
888
+            $ligne_avant = $ligne +  public_compte_ligne($texte,0, $pos_avant);
889
+        }
890
+
891
+        // Regarder si on a une partie inconditionnelle avant <BB_xxx>
892
+        if ($boucle['pos_preaff'] !== false) {
893
+
894
+            $end_preaff = $pos_debut_boucle;
895
+
896
+            $pos_preaff = $boucle['pos_preaff_inside'];
897
+            $result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
898
+            $ligne_preaff = $ligne +  public_compte_ligne($texte,0, $pos_preaff);
899
+        }
900
+
901
+        $debut = substr($texte, 0, $boucle['debut_boucle']);
902
+
903
+        $result->id_boucle = $id_boucle;
904
+
905
+        if (!preg_match(SPEC_BOUCLE, $milieu, $match)) {
906
+            $err_b = array('zbug_erreur_boucle_syntaxe', array('id' => $id_boucle));
907
+            erreur_squelette($err_b, $result);
908
+
909
+            $ligne += public_compte_ligne($texte, 0, $pos_boucle + 1);
910
+            $texte = substr($texte, $pos_boucle + 1);
911
+            continue;
912
+        }
913
+
914
+        $result->type_requete = $match[0];
915
+        $milieu = substr($milieu, strlen($match[0]));
916
+        $pos_boucle = $pos_parent + strlen($match[0]); // on s'en sert pour compter les lignes plus precisemment
917
+
918
+        $type = $match[1];
919
+        $jointures = trim($match[2]);
920
+        $table_optionnelle = ($match[3]);
921
+        if ($jointures) {
922
+            // on affecte pas ici les jointures explicites, mais dans la compilation
923
+            // ou elles seront completees des jointures declarees
924
+            $result->jointures_explicites = $jointures;
925
+        }
926
+
927
+        if ($table_optionnelle) {
928
+            $result->table_optionnelle = $type;
929
+        }
930
+
931
+        // 1ere passe sur les criteres, vu comme des arguments sans fct
932
+        // Resultat mis dans result->param
933
+        phraser_args($milieu, "/>", "", $all_res, $result);
934
+
935
+        // En 2e passe result->criteres contiendra un tableau
936
+        // pour l'instant on met le source (chaine) :
937
+        // si elle reste ici au final, c'est qu'elle contient une erreur
938
+        $pos_fin_criteres = strpos($milieu, $result->apres);
939
+        $pos_boucle += $pos_fin_criteres; // on s'en sert pour compter les lignes plus precisemment
940
+        $result->criteres = substr($milieu, 0, $pos_fin_criteres);
941
+        $milieu = $result->apres;
942
+        $result->apres = "";
943
+
944
+        //
945
+        // Recuperer la fin :
946
+        //
947
+        if ($milieu[0] === '/') {
948
+            // boucle autofermante : pas de partie conditionnelle apres
949
+            $suite = substr($milieu, 2);
950
+            $pos_boucle += 2;
951
+            $milieu = '';
952
+        } else {
953
+            $milieu = substr($milieu, 1);
954
+            $pos_boucle += 1;
955
+
956
+            $fin_boucle = BALISE_FIN_BOUCLE . $id_boucle . ">";
957
+            $pos_fin = strpos($milieu, $fin_boucle);
958
+            if ($pos_fin === false) {
959
+                $err_b = array(
960
+                    'zbug_erreur_boucle_fermant',
961
+                    array('id' => $id_boucle)
962
+                );
963
+                erreur_squelette($err_b, $result);
964
+            }
965
+
966
+            $pos_boucle += $pos_fin + strlen($fin_boucle);
967
+            $suite = substr($milieu, $pos_fin + strlen($fin_boucle));
968
+            $milieu = substr($milieu, 0, $pos_fin);
969
+        }
970
+
971
+        $result->milieu = $milieu;
972
+        $ligne_suite = $ligne_apres = $ligne + public_compte_ligne($texte, 0, $pos_boucle);
973
+
974
+        //
975
+        // 1. Recuperer la partie conditionnelle apres
976
+        //
977
+        $apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . ">";
978
+        $pos_apres = strpos($suite, $apres_boucle);
979
+        if ($pos_apres !== false) {
980
+            $result->apres = substr($suite, 0, $pos_apres);
981
+            $pos_apres += strlen($apres_boucle);
982
+            $suite = substr($suite, $pos_apres);
983
+            $ligne_suite += public_compte_ligne($texte, $pos_boucle, $pos_apres);
984
+            $pos_boucle += $pos_apres ;
985
+        }
986
+
987
+
988
+        //
989
+        // 2. Recuperer la partie alternative
990
+        //
991
+        $ligne_altern = $ligne_suite;
992
+        $altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . ">";
993
+        $pos_altern = strpos($suite, $altern_boucle);
994
+        if ($pos_altern !== false) {
995
+            $result->altern = substr($suite, 0, $pos_altern);
996
+            $pos_altern += strlen($altern_boucle);
997
+            $suite = substr($suite, $pos_altern);
998
+            $ligne_suite += public_compte_ligne($texte, $pos_boucle, $pos_altern);
999
+            $pos_boucle += $pos_altern;
1000
+        }
1001
+
1002
+        //
1003
+        // 3. Recuperer la partie footer non alternative
1004
+        //
1005
+        $ligne_postaff = $ligne_suite;
1006
+        $postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . ">";
1007
+        $pos_postaff = strpos($suite, $postaff_boucle);
1008
+        if ($pos_postaff !== false) {
1009
+            $result->postaff = substr($suite, 0, $pos_postaff);
1010
+            $pos_postaff += strlen($postaff_boucle);
1011
+            $suite = substr($suite, $pos_postaff);
1012
+            $ligne_suite += public_compte_ligne($texte, $pos_boucle, $pos_postaff);
1013
+            $pos_boucle += $pos_postaff ;
1014
+        }
1015
+
1016
+        $result->ligne = $ligne_preaff;
1017
+
1018
+        if ($p = strpos($type, ':')) {
1019
+            $result->sql_serveur = substr($type, 0, $p);
1020
+            $type = substr($type, $p + 1);
1021
+        }
1022
+        $soustype = strtolower($type);
1023
+
1024
+        if (!isset($GLOBALS["table_des_tables"][$soustype])) {
1025
+            $soustype = $type;
1026
+        }
1027
+
1028
+        $result->type_requete = $soustype;
1029
+        // Lancer la 2e passe sur les criteres si la 1ere etait bonne
1030
+        if (!is_array($result->param)) {
1031
+            $err_b = true;
1032
+        } else {
1033
+            phraser_criteres($result->param, $result);
1034
+            if (strncasecmp($soustype, TYPE_RECURSIF, strlen(TYPE_RECURSIF)) == 0) {
1035
+                $result->type_requete = TYPE_RECURSIF;
1036
+                $args = $result->param;
1037
+                array_unshift($args,
1038
+                    substr($type, strlen(TYPE_RECURSIF)));
1039
+                $result->param = $args;
1040
+            }
1041
+        }
1042
+
1043
+        $descr['id_mere_contexte'] = $id_boucle;
1044
+        $result->milieu = public_phraser_html_dist($milieu, $id_boucle, $boucles, $descr, $ligne_milieu);
1045
+        // reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre
1046
+        // ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle
1047
+        // si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite
1048
+        if (empty($boucles[$id_boucle])){
1049
+            $boucles[$id_boucle] = null;
1050
+        }
1051
+        $result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff);
1052
+        $result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant);
1053
+        $result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres);
1054
+        $result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern);
1055
+        $result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff);
1056
+
1057
+        // Prevenir le generateur de code que le squelette est faux
1058
+        if ($err_b) {
1059
+            $result->type_requete = false;
1060
+        }
1061
+
1062
+        // Verifier qu'il n'y a pas double definition
1063
+        // apres analyse des sous-parties (pas avant).
1064
+        if (!empty($boucles[$id_boucle])) {
1065
+            $err_b_d = array(
1066
+                'zbug_erreur_boucle_double',
1067
+                array('id' => $id_boucle)
1068
+            );
1069
+            erreur_squelette($err_b_d, $result);
1070
+            // Prevenir le generateur de code que le squelette est faux
1071
+            $boucles[$id_boucle]->type_requete = false;
1072
+        } else {
1073
+            $boucles[$id_boucle] = $result;
1074
+        }
1075
+        $all_res = phraser_champs_etendus($debut, $ligne, $all_res);
1076
+        $all_res[] = &$boucles[$id_boucle];
1077
+
1078
+        $ligne = $ligne_suite;
1079
+        $texte = $suite;
1080
+    }
1081
+
1082
+    return phraser_champs_etendus($texte, $ligne, $all_res);
1083 1083
 }
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -48,19 +48,19 @@  discard block
 block discarded – undo
48 48
  * Nom d'une balise #TOTO
49 49
  *
50 50
  * Écriture alambiquée pour rester compatible avec les hexadecimaux des vieux squelettes */
51
-define('NOM_DE_CHAMP', "#((" . NOM_DE_BOUCLE . "):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)\b(\*{0,2})");
51
+define('NOM_DE_CHAMP', "#((".NOM_DE_BOUCLE."):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)\b(\*{0,2})");
52 52
 /** Balise complète [...(#TOTO) ... ] */
53
-define('CHAMP_ETENDU', '/\[([^]\[]*)\(' . NOM_DE_CHAMP . '([^[)]*\)[^]\[]*)\]/S');
53
+define('CHAMP_ETENDU', '/\[([^]\[]*)\('.NOM_DE_CHAMP.'([^[)]*\)[^]\[]*)\]/S');
54 54
 
55 55
 define('BALISE_INCLURE', '/<INCLU[DR]E[[:space:]]*(\(([^)]*)\))?/S');
56 56
 define('BALISE_POLYGLOTTE', ',<multi>(.*)</multi>,Uims');
57 57
 define('BALISE_IDIOMES', ',<:(([a-z0-9_]+):)?([a-z0-9_]*)({([^\|=>]*=[^\|>]*)})?((\|[^>]*)?:/?>),iS');
58
-define('BALISE_IDIOMES_ARGS', '@^\s*([^= ]*)\s*=\s*((' . NOM_DE_CHAMP . '[{][^}]*})?[^,]*)\s*,?\s*@s');
58
+define('BALISE_IDIOMES_ARGS', '@^\s*([^= ]*)\s*=\s*(('.NOM_DE_CHAMP.'[{][^}]*})?[^,]*)\s*,?\s*@s');
59 59
 
60 60
 /** Champ sql dans parenthèse ex: (id_article) */
61 61
 define('SQL_ARGS', '(\([^)]*\))');
62 62
 /** Fonction SQL sur un champ ex: SUM(visites) */
63
-define('CHAMP_SQL_PLUS_FONC', '`?([A-Z_\/][A-Z_\/0-9.]*)' . SQL_ARGS . '?`?');
63
+define('CHAMP_SQL_PLUS_FONC', '`?([A-Z_\/][A-Z_\/0-9.]*)'.SQL_ARGS.'?`?');
64 64
 
65 65
 // https://code.spip.net/@phraser_inclure
66 66
 function phraser_inclure($texte, $ligne, $result) {
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
  * @return array
216 216
  **/
217 217
 function phraser_champs($texte, $ligne, $result) {
218
-	while (preg_match("/" . NOM_DE_CHAMP . "/S", $texte, $match)) {
218
+	while (preg_match("/".NOM_DE_CHAMP."/S", $texte, $match)) {
219 219
 		$p = strpos($texte, $match[0]);
220 220
 		// texte après la balise
221 221
 		$suite = substr($texte, $p + strlen($match[0]));
@@ -361,7 +361,7 @@  discard block
 block discarded – undo
361 361
 			$collecte[] = $champ;
362 362
 			$args = ltrim($regs[count($regs) - 1]);
363 363
 		} else {
364
-			if (!preg_match("/" . NOM_DE_CHAMP . "([{|])/", $arg, $r)) {
364
+			if (!preg_match("/".NOM_DE_CHAMP."([{|])/", $arg, $r)) {
365 365
 				// 0 est un aveu d'impuissance. A completer
366 366
 				$arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
367 367
 
@@ -446,7 +446,7 @@  discard block
 block discarded – undo
446 446
 function phraser_champs_exterieurs($texte, $ligne, $sep, $nested) {
447 447
 	$res = array();
448 448
 	while (($p = strpos($texte, "%$sep")) !== false) {
449
-		if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
449
+		if (!preg_match(',^%'.preg_quote($sep).'([0-9]+)@,', substr($texte, $p), $m)) {
450 450
 			break;
451 451
 		}
452 452
 		$debut = substr($texte, 0, $p);
@@ -614,7 +614,7 @@  discard block
 block discarded – undo
614 614
 					// une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
615 615
 					if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
616 616
 						$c = null;
617
-						eval('$c = ' . $m[4] . ';');
617
+						eval('$c = '.$m[4].';');
618 618
 						if (isset($c)) {
619 619
 							$m[4] = $c;
620 620
 						}
@@ -692,7 +692,7 @@  discard block
 block discarded – undo
692 692
 
693 693
 					if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
694 694
 						$crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
695
-					} elseif (preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
695
+					} elseif (preg_match(',^([!]?)('.CHAMP_SQL_PLUS_FONC.
696 696
 						')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)) {
697 697
 						$a2 = trim($m[8]);
698 698
 						if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and ($a2[0] == substr($a2, -1))) {
@@ -702,8 +702,8 @@  discard block
 block discarded – undo
702 702
 							(($m[2] == 'lang_select') ? $m[2] : $m[7]),
703 703
 							$m[6], $m[5]);
704 704
 						$crit->exclus = $m[1];
705
-					} elseif (preg_match("/^([!]?)\s*(" .
706
-						CHAMP_SQL_PLUS_FONC .
705
+					} elseif (preg_match("/^([!]?)\s*(".
706
+						CHAMP_SQL_PLUS_FONC.
707 707
 						")\s*(\??)(.*)$/is", $param, $m)) {
708 708
 						// contient aussi les comparaisons implicites !
709 709
 						// Comme ci-dessus: 
@@ -802,9 +802,9 @@  discard block
 block discarded – undo
802 802
 	$current_pos = 0;
803 803
 	while (($pos_boucle = strpos($texte, BALISE_BOUCLE, $current_pos)) !== false) {
804 804
 		$current_pos = $pos_boucle + 1;
805
-		$pos_parent = strpos($texte,'(', $pos_boucle);
805
+		$pos_parent = strpos($texte, '(', $pos_boucle);
806 806
 		if ($pos_parent === false
807
-		  or !$id_boucle = trim(substr($texte,$pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)))
807
+		  or !$id_boucle = trim(substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)))
808 808
 			or !(is_numeric($id_boucle) or strpos($id_boucle, '_') === 0)) {
809 809
 
810 810
 			$result = new Boucle;
@@ -813,7 +813,7 @@  discard block
 block discarded – undo
813 813
 
814 814
 			// un id_boucle pour l'affichage de l'erreur
815 815
 			if (!$id_boucle) {
816
-				$id_boucle = substr($texte,$pos_boucle + strlen(BALISE_BOUCLE), 15);
816
+				$id_boucle = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
817 817
 			}
818 818
 			$result->id_boucle = $id_boucle;
819 819
 			$err_b = array('zbug_erreur_boucle_syntaxe', array('id' => $id_boucle));
@@ -834,7 +834,7 @@  discard block
 block discarded – undo
834 834
 			];
835 835
 
836 836
 			// trouver sa position de depart reelle : au <B_ ou au <BB_
837
-			$precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
837
+			$precond_boucle = BALISE_PRECOND_BOUCLE.$id_boucle.'>';
838 838
 			$pos_precond = strpos($texte, $precond_boucle);
839 839
 			if ($pos_precond !== false and $pos_precond < $boucle['debut_boucle']) {
840 840
 				$boucle['debut_boucle'] = $pos_precond;
@@ -842,7 +842,7 @@  discard block
 block discarded – undo
842 842
 				$boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
843 843
 			}
844 844
 
845
-			$preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
845
+			$preaff_boucle = BALISE_PREAFF_BOUCLE.$id_boucle.'>';
846 846
 			$pos_preaff = strpos($texte, $preaff_boucle);
847 847
 			if ($pos_preaff !== false and $pos_preaff < $boucle['debut_boucle']) {
848 848
 				$boucle['debut_boucle'] = $pos_preaff;
@@ -885,7 +885,7 @@  discard block
 block discarded – undo
885 885
 
886 886
 			$pos_avant = $boucle['pos_precond_inside'];
887 887
 			$result->avant = substr($texte, $pos_avant, $pos_boucle - $pos_avant);
888
-			$ligne_avant = $ligne +  public_compte_ligne($texte,0, $pos_avant);
888
+			$ligne_avant = $ligne + public_compte_ligne($texte, 0, $pos_avant);
889 889
 		}
890 890
 
891 891
 		// Regarder si on a une partie inconditionnelle avant <BB_xxx>
@@ -895,7 +895,7 @@  discard block
 block discarded – undo
895 895
 
896 896
 			$pos_preaff = $boucle['pos_preaff_inside'];
897 897
 			$result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
898
-			$ligne_preaff = $ligne +  public_compte_ligne($texte,0, $pos_preaff);
898
+			$ligne_preaff = $ligne + public_compte_ligne($texte, 0, $pos_preaff);
899 899
 		}
900 900
 
901 901
 		$debut = substr($texte, 0, $boucle['debut_boucle']);
@@ -953,7 +953,7 @@  discard block
 block discarded – undo
953 953
 			$milieu = substr($milieu, 1);
954 954
 			$pos_boucle += 1;
955 955
 
956
-			$fin_boucle = BALISE_FIN_BOUCLE . $id_boucle . ">";
956
+			$fin_boucle = BALISE_FIN_BOUCLE.$id_boucle.">";
957 957
 			$pos_fin = strpos($milieu, $fin_boucle);
958 958
 			if ($pos_fin === false) {
959 959
 				$err_b = array(
@@ -974,14 +974,14 @@  discard block
 block discarded – undo
974 974
 		//
975 975
 		// 1. Recuperer la partie conditionnelle apres
976 976
 		//
977
-		$apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . ">";
977
+		$apres_boucle = BALISE_POSTCOND_BOUCLE.$id_boucle.">";
978 978
 		$pos_apres = strpos($suite, $apres_boucle);
979 979
 		if ($pos_apres !== false) {
980 980
 			$result->apres = substr($suite, 0, $pos_apres);
981 981
 			$pos_apres += strlen($apres_boucle);
982 982
 			$suite = substr($suite, $pos_apres);
983 983
 			$ligne_suite += public_compte_ligne($texte, $pos_boucle, $pos_apres);
984
-			$pos_boucle += $pos_apres ;
984
+			$pos_boucle += $pos_apres;
985 985
 		}
986 986
 
987 987
 
@@ -989,7 +989,7 @@  discard block
 block discarded – undo
989 989
 		// 2. Recuperer la partie alternative
990 990
 		//
991 991
 		$ligne_altern = $ligne_suite;
992
-		$altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . ">";
992
+		$altern_boucle = BALISE_ALT_BOUCLE.$id_boucle.">";
993 993
 		$pos_altern = strpos($suite, $altern_boucle);
994 994
 		if ($pos_altern !== false) {
995 995
 			$result->altern = substr($suite, 0, $pos_altern);
@@ -1003,14 +1003,14 @@  discard block
 block discarded – undo
1003 1003
 		// 3. Recuperer la partie footer non alternative
1004 1004
 		//
1005 1005
 		$ligne_postaff = $ligne_suite;
1006
-		$postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . ">";
1006
+		$postaff_boucle = BALISE_POSTAFF_BOUCLE.$id_boucle.">";
1007 1007
 		$pos_postaff = strpos($suite, $postaff_boucle);
1008 1008
 		if ($pos_postaff !== false) {
1009 1009
 			$result->postaff = substr($suite, 0, $pos_postaff);
1010 1010
 			$pos_postaff += strlen($postaff_boucle);
1011 1011
 			$suite = substr($suite, $pos_postaff);
1012 1012
 			$ligne_suite += public_compte_ligne($texte, $pos_boucle, $pos_postaff);
1013
-			$pos_boucle += $pos_postaff ;
1013
+			$pos_boucle += $pos_postaff;
1014 1014
 		}
1015 1015
 
1016 1016
 		$result->ligne = $ligne_preaff;
@@ -1045,7 +1045,7 @@  discard block
 block discarded – undo
1045 1045
 		// reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre
1046 1046
 		// ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle
1047 1047
 		// si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite
1048
-		if (empty($boucles[$id_boucle])){
1048
+		if (empty($boucles[$id_boucle])) {
1049 1049
 			$boucles[$id_boucle] = null;
1050 1050
 		}
1051 1051
 		$result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff);
Please login to merge, or discard this patch.