Completed
Push — master ( 9f830f...81b3f6 )
by cam
04:25
created
ecrire/public/compiler.php 2 patches
Indentation   +1169 added lines, -1169 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  **/
19 19
 
20 20
 if (!defined('_ECRIRE_INC_VERSION')) {
21
-	return;
21
+    return;
22 22
 }
23 23
 
24 24
 /** Repérer un code ne calculant rien, meme avec commentaire */
@@ -60,91 +60,91 @@  discard block
 block discarded – undo
60 60
 
61 61
 // https://code.spip.net/@argumenter_inclure
62 62
 function argumenter_inclure(
63
-	$params,
64
-	$rejet_filtres,
65
-	$p,
66
-	&$boucles,
67
-	$id_boucle,
68
-	$echap = true,
69
-	$lang = '',
70
-	$fond1 = false
63
+    $params,
64
+    $rejet_filtres,
65
+    $p,
66
+    &$boucles,
67
+    $id_boucle,
68
+    $echap = true,
69
+    $lang = '',
70
+    $fond1 = false
71 71
 ) {
72
-	$l = array();
73
-	$erreur_p_i_i = '';
74
-	if (!is_array($params)) {
75
-		return $l;
76
-	}
77
-	foreach ($params as $k => $couple) {
78
-		// la liste d'arguments d'inclusion peut se terminer par un filtre
79
-		$filtre = array_shift($couple);
80
-		if ($filtre) {
81
-			break;
82
-		}
83
-		foreach ($couple as $n => $val) {
84
-			$var = $val[0];
85
-			if ($var->type != 'texte') {
86
-				if ($n or $k or $fond1) {
87
-					$erreur_p_i_i = array(
88
-						'zbug_parametres_inclus_incorrects',
89
-						array('param' => $var->nom_champ)
90
-					);
91
-					erreur_squelette($erreur_p_i_i, $p);
92
-					break;
93
-				} else {
94
-					$l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle);
95
-				}
96
-			} else {
97
-				preg_match(",^([^=]*)(=?)(.*)$,m", $var->texte, $m);
98
-				$m = array_pad($m, 3, null);
99
-				$var = $m[1];
100
-				$auto = false;;
101
-				if ($m[2]) {
102
-					$v = $m[3];
103
-					if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) {
104
-						$v = $m[1];
105
-					}
106
-					$val[0] = new Texte;
107
-					$val[0]->texte = $v;
108
-				} elseif ($k or $n or $fond1) {
109
-					$auto = true;
110
-				} else {
111
-					$var = 1;
112
-				}
113
-
114
-				if ($var == 'lang') {
115
-					$lang = !$auto
116
-						? calculer_liste($val, $p->descr, $boucles, $id_boucle)
117
-						: '$GLOBALS["spip_lang"]';
118
-				} else {
119
-					$val = $auto
120
-						? index_pile($id_boucle, $var, $boucles)
121
-						: calculer_liste($val, $p->descr, $boucles, $id_boucle);
122
-					if ($var !== 1) {
123
-						$val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
124
-							. $val . ($echap ? ") . '" : " ");
125
-					} else {
126
-						$val = $echap ? "'.$val.'" : $val;
127
-					}
128
-					$l[$var] = $val;
129
-				}
130
-			}
131
-		}
132
-	}
133
-	if ($erreur_p_i_i) {
134
-		return false;
135
-	}
136
-	// Cas particulier de la langue : si {lang=xx} est definie, on
137
-	// la passe, sinon on passe la langue courante au moment du calcul
138
-	// sauf si on n'en veut pas 
139
-	if ($lang === false) {
140
-		return $l;
141
-	}
142
-	if (!$lang) {
143
-		$lang = '$GLOBALS["spip_lang"]';
144
-	}
145
-	$l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : " ");
146
-
147
-	return $l;
72
+    $l = array();
73
+    $erreur_p_i_i = '';
74
+    if (!is_array($params)) {
75
+        return $l;
76
+    }
77
+    foreach ($params as $k => $couple) {
78
+        // la liste d'arguments d'inclusion peut se terminer par un filtre
79
+        $filtre = array_shift($couple);
80
+        if ($filtre) {
81
+            break;
82
+        }
83
+        foreach ($couple as $n => $val) {
84
+            $var = $val[0];
85
+            if ($var->type != 'texte') {
86
+                if ($n or $k or $fond1) {
87
+                    $erreur_p_i_i = array(
88
+                        'zbug_parametres_inclus_incorrects',
89
+                        array('param' => $var->nom_champ)
90
+                    );
91
+                    erreur_squelette($erreur_p_i_i, $p);
92
+                    break;
93
+                } else {
94
+                    $l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle);
95
+                }
96
+            } else {
97
+                preg_match(",^([^=]*)(=?)(.*)$,m", $var->texte, $m);
98
+                $m = array_pad($m, 3, null);
99
+                $var = $m[1];
100
+                $auto = false;;
101
+                if ($m[2]) {
102
+                    $v = $m[3];
103
+                    if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) {
104
+                        $v = $m[1];
105
+                    }
106
+                    $val[0] = new Texte;
107
+                    $val[0]->texte = $v;
108
+                } elseif ($k or $n or $fond1) {
109
+                    $auto = true;
110
+                } else {
111
+                    $var = 1;
112
+                }
113
+
114
+                if ($var == 'lang') {
115
+                    $lang = !$auto
116
+                        ? calculer_liste($val, $p->descr, $boucles, $id_boucle)
117
+                        : '$GLOBALS["spip_lang"]';
118
+                } else {
119
+                    $val = $auto
120
+                        ? index_pile($id_boucle, $var, $boucles)
121
+                        : calculer_liste($val, $p->descr, $boucles, $id_boucle);
122
+                    if ($var !== 1) {
123
+                        $val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
124
+                            . $val . ($echap ? ") . '" : " ");
125
+                    } else {
126
+                        $val = $echap ? "'.$val.'" : $val;
127
+                    }
128
+                    $l[$var] = $val;
129
+                }
130
+            }
131
+        }
132
+    }
133
+    if ($erreur_p_i_i) {
134
+        return false;
135
+    }
136
+    // Cas particulier de la langue : si {lang=xx} est definie, on
137
+    // la passe, sinon on passe la langue courante au moment du calcul
138
+    // sauf si on n'en veut pas 
139
+    if ($lang === false) {
140
+        return $l;
141
+    }
142
+    if (!$lang) {
143
+        $lang = '$GLOBALS["spip_lang"]';
144
+    }
145
+    $l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : " ");
146
+
147
+    return $l;
148 148
 }
149 149
 
150 150
 /**
@@ -168,77 +168,77 @@  discard block
 block discarded – undo
168 168
  **/
169 169
 function calculer_inclure($p, &$boucles, $id_boucle) {
170 170
 
171
-	$_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
172
-	if (is_string($p->texte)) {
173
-		$fichier = $p->texte;
174
-		$code = "\"".str_replace('"','\"',$fichier)."\"";
175
-
176
-	} else {
177
-		$code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
178
-		if ($code and preg_match("/^'([^']*)'/s", $code, $r)) {
179
-			$fichier = $r[1];
180
-		} else {
181
-			$fichier = '';
182
-		}
183
-	}
184
-	if (!$code or $code === '""' or $code === "''") {
185
-		$trace = $p->fonctions;
186
-		while (is_array($trace)
187
-		  and $trace = array_filter($trace)
188
-			and count($trace)==1) {
189
-			$trace = reset($trace);
190
-		}
191
-		$erreur_p_i_i = array(
192
-			'zbug_parametres_inclus_incorrects',
193
-			array('param' => print_r($trace, true))
194
-		);
195
-		erreur_squelette($erreur_p_i_i, $p);
196
-
197
-		return "''";
198
-	}
199
-	$compil = texte_script(memoriser_contexte_compil($p));
200
-
201
-	if (is_array($_contexte)) {
202
-		// Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
203
-		if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) {
204
-			unset($_contexte['env']);
205
-		}
206
-
207
-		// noter les doublons dans l'appel a public.php
208
-		if (isset($_contexte['doublons'])) {
209
-			$_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'";
210
-		}
211
-
212
-		if ($ajax = isset($_contexte['ajax'])) {
213
-			$ajax = preg_replace(",=>(.*)$,ims", '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
214
-			unset($_contexte['ajax']);
215
-		}
216
-
217
-		$_contexte = join(",\n\t", $_contexte);
218
-	} else {
219
-		return false;
220
-	} // j'aurais voulu toucher le fond ...
221
-
222
-	$contexte = 'array(' . $_contexte . ')';
223
-
224
-	if ($env) {
225
-		$contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
226
-	}
227
-
228
-	// s'il y a une extension .php, ce n'est pas un squelette
229
-	if ($fichier and preg_match('/^.+[.]php$/s', $fichier)) {
230
-		$code = sandbox_composer_inclure_php($fichier, $p, $contexte);
231
-	} else {
232
-		$_options[] = "\"compil\"=>array($compil)";
233
-		if ($ajax) {
234
-			$_options[] = $ajax;
235
-		}
236
-		$code = " ' . argumenter_squelette($code) . '";
237
-		$code = "echo " . sprintf(CODE_RECUPERER_FOND, $code, $contexte, implode(',', $_options),
238
-				"_request(\"connect\")") . ';';
239
-	}
240
-
241
-	return "\n'<'.'" . "?php " . $code . "\n?'." . "'>'";
171
+    $_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
172
+    if (is_string($p->texte)) {
173
+        $fichier = $p->texte;
174
+        $code = "\"".str_replace('"','\"',$fichier)."\"";
175
+
176
+    } else {
177
+        $code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
178
+        if ($code and preg_match("/^'([^']*)'/s", $code, $r)) {
179
+            $fichier = $r[1];
180
+        } else {
181
+            $fichier = '';
182
+        }
183
+    }
184
+    if (!$code or $code === '""' or $code === "''") {
185
+        $trace = $p->fonctions;
186
+        while (is_array($trace)
187
+          and $trace = array_filter($trace)
188
+            and count($trace)==1) {
189
+            $trace = reset($trace);
190
+        }
191
+        $erreur_p_i_i = array(
192
+            'zbug_parametres_inclus_incorrects',
193
+            array('param' => print_r($trace, true))
194
+        );
195
+        erreur_squelette($erreur_p_i_i, $p);
196
+
197
+        return "''";
198
+    }
199
+    $compil = texte_script(memoriser_contexte_compil($p));
200
+
201
+    if (is_array($_contexte)) {
202
+        // Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
203
+        if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) {
204
+            unset($_contexte['env']);
205
+        }
206
+
207
+        // noter les doublons dans l'appel a public.php
208
+        if (isset($_contexte['doublons'])) {
209
+            $_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'";
210
+        }
211
+
212
+        if ($ajax = isset($_contexte['ajax'])) {
213
+            $ajax = preg_replace(",=>(.*)$,ims", '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
214
+            unset($_contexte['ajax']);
215
+        }
216
+
217
+        $_contexte = join(",\n\t", $_contexte);
218
+    } else {
219
+        return false;
220
+    } // j'aurais voulu toucher le fond ...
221
+
222
+    $contexte = 'array(' . $_contexte . ')';
223
+
224
+    if ($env) {
225
+        $contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
226
+    }
227
+
228
+    // s'il y a une extension .php, ce n'est pas un squelette
229
+    if ($fichier and preg_match('/^.+[.]php$/s', $fichier)) {
230
+        $code = sandbox_composer_inclure_php($fichier, $p, $contexte);
231
+    } else {
232
+        $_options[] = "\"compil\"=>array($compil)";
233
+        if ($ajax) {
234
+            $_options[] = $ajax;
235
+        }
236
+        $code = " ' . argumenter_squelette($code) . '";
237
+        $code = "echo " . sprintf(CODE_RECUPERER_FOND, $code, $contexte, implode(',', $_options),
238
+                "_request(\"connect\")") . ';';
239
+    }
240
+
241
+    return "\n'<'.'" . "?php " . $code . "\n?'." . "'>'";
242 242
 }
243 243
 
244 244
 
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
  *     true pour ne tester que le cas publie et ignorer l'eventuel var_mode=preview de la page
257 257
  */
258 258
 function instituer_boucle(&$boucle, $echapper = true, $ignore_previsu = false) {
259
-	/*
259
+    /*
260 260
 	$show['statut'][] = array(
261 261
 		'champ'=>'statut',  // champ de la table sur lequel porte le filtrage par le statut
262 262
 		'publie'=>'publie', // valeur ou liste de valeurs, qui definissent l'objet comme publie.
@@ -280,71 +280,71 @@  discard block
 block discarded – undo
280 280
 	champstatut est alors le champ statut sur la tablen
281 281
 	dans les jointures, clen peut etre un tableau pour une jointure complexe : array('id_objet','id_article','objet','article')
282 282
 */
283
-	$id_table = $boucle->id_table;
284
-	$show = $boucle->show;
285
-	if (isset($show['statut']) and $show['statut']) {
286
-		foreach ($show['statut'] as $k => $s) {
287
-			// Restreindre aux elements publies si pas de {statut} ou autre dans les criteres
288
-			$filtrer = true;
289
-			if (isset($s['exception'])) {
290
-				foreach (is_array($s['exception']) ? $s['exception'] : array($s['exception']) as $m) {
291
-					if (isset($boucle->modificateur[$m]) or isset($boucle->modificateur['criteres'][$m])) {
292
-						$filtrer = false;
293
-						break;
294
-					}
295
-				}
296
-			}
297
-
298
-			if ($filtrer) {
299
-				if (is_array($s['champ'])) {
300
-					$statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite
301
-					$jointures = array();
302
-					// indiquer la description de chaque table dans le tableau de jointures,
303
-					// ce qui permet d'eviter certains GROUP BY inutiles.
304
-					$trouver_table = charger_fonction('trouver_table', 'base');
305
-					foreach ($s['champ'] as $j) {
306
-						$id = reset($j);
307
-						$def = $trouver_table($id);
308
-						$jointures[] = array('', array($id, $def), end($j));
309
-					}
310
-					$jointures[0][0] = $id_table;
311
-					if (!array_search($id, $boucle->from)) {
312
-						include_spip('public/jointures');
313
-						fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper);
314
-					}
315
-					// trouver l'alias de la table d'arrivee qui porte le statut
316
-					$id = array_search($id, $boucle->from);
317
-				} else {
318
-					$id = $id_table;
319
-					$statut = preg_replace(',\W,', '', $s['champ']); // securite
320
-				}
321
-				$mstatut = $id . '.' . $statut;
322
-
323
-				$arg_ignore_previsu = ($ignore_previsu ? ",true" : '');
324
-				include_spip('public/quete');
325
-				if (isset($s['post_date']) and $s['post_date']
326
-					and $GLOBALS['meta']["post_dates"] == 'non'
327
-				) {
328
-					$date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
329
-					array_unshift($boucle->where,
330
-						$echapper ?
331
-							"\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
332
-							:
333
-							quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
334
-					);
335
-				}
336
-				array_unshift($boucle->where,
337
-					$echapper ?
338
-						"\nquete_condition_statut('$mstatut',"
339
-						. _q($s['previsu']) . ","
340
-						. _q($s['publie']) . ","
341
-						. _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
342
-						:
343
-						quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
344
-				);
345
-			}
346
-		}
347
-	}
283
+    $id_table = $boucle->id_table;
284
+    $show = $boucle->show;
285
+    if (isset($show['statut']) and $show['statut']) {
286
+        foreach ($show['statut'] as $k => $s) {
287
+            // Restreindre aux elements publies si pas de {statut} ou autre dans les criteres
288
+            $filtrer = true;
289
+            if (isset($s['exception'])) {
290
+                foreach (is_array($s['exception']) ? $s['exception'] : array($s['exception']) as $m) {
291
+                    if (isset($boucle->modificateur[$m]) or isset($boucle->modificateur['criteres'][$m])) {
292
+                        $filtrer = false;
293
+                        break;
294
+                    }
295
+                }
296
+            }
297
+
298
+            if ($filtrer) {
299
+                if (is_array($s['champ'])) {
300
+                    $statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite
301
+                    $jointures = array();
302
+                    // indiquer la description de chaque table dans le tableau de jointures,
303
+                    // ce qui permet d'eviter certains GROUP BY inutiles.
304
+                    $trouver_table = charger_fonction('trouver_table', 'base');
305
+                    foreach ($s['champ'] as $j) {
306
+                        $id = reset($j);
307
+                        $def = $trouver_table($id);
308
+                        $jointures[] = array('', array($id, $def), end($j));
309
+                    }
310
+                    $jointures[0][0] = $id_table;
311
+                    if (!array_search($id, $boucle->from)) {
312
+                        include_spip('public/jointures');
313
+                        fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper);
314
+                    }
315
+                    // trouver l'alias de la table d'arrivee qui porte le statut
316
+                    $id = array_search($id, $boucle->from);
317
+                } else {
318
+                    $id = $id_table;
319
+                    $statut = preg_replace(',\W,', '', $s['champ']); // securite
320
+                }
321
+                $mstatut = $id . '.' . $statut;
322
+
323
+                $arg_ignore_previsu = ($ignore_previsu ? ",true" : '');
324
+                include_spip('public/quete');
325
+                if (isset($s['post_date']) and $s['post_date']
326
+                    and $GLOBALS['meta']["post_dates"] == 'non'
327
+                ) {
328
+                    $date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
329
+                    array_unshift($boucle->where,
330
+                        $echapper ?
331
+                            "\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
332
+                            :
333
+                            quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
334
+                    );
335
+                }
336
+                array_unshift($boucle->where,
337
+                    $echapper ?
338
+                        "\nquete_condition_statut('$mstatut',"
339
+                        . _q($s['previsu']) . ","
340
+                        . _q($s['publie']) . ","
341
+                        . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
342
+                        :
343
+                        quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
344
+                );
345
+            }
346
+        }
347
+    }
348 348
 }
349 349
 
350 350
 /**
@@ -363,29 +363,29 @@  discard block
 block discarded – undo
363 363
  */
364 364
 function calculer_boucle($id_boucle, &$boucles) {
365 365
 
366
-	$boucle = &$boucles[$id_boucle];
367
-	instituer_boucle($boucle);
368
-	$boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]);
369
-
370
-	// en mode debug memoriser les premiers passages dans la boucle,
371
-	// mais pas tous, sinon ca pete.
372
-	if (_request('var_mode_affiche') != 'resultat') {
373
-		$trace = '';
374
-	} else {
375
-		$_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
376
-		$_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
377
-		$trace = "
366
+    $boucle = &$boucles[$id_boucle];
367
+    instituer_boucle($boucle);
368
+    $boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]);
369
+
370
+    // en mode debug memoriser les premiers passages dans la boucle,
371
+    // mais pas tous, sinon ca pete.
372
+    if (_request('var_mode_affiche') != 'resultat') {
373
+        $trace = '';
374
+    } else {
375
+        $_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
376
+        $_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
377
+        $trace = "
378 378
 		if (empty($_trace)) { 
379 379
 			$_trace = []; 
380 380
 		}
381 381
 		if (count($_trace) < 3) { 
382 382
 			$_trace" . "[] = \$t0; 
383 383
 		}";
384
-	}
384
+    }
385 385
 
386
-	return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF)
387
-		? calculer_boucle_rec($id_boucle, $boucles, $trace)
388
-		: calculer_boucle_nonrec($id_boucle, $boucles, $trace);
386
+    return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF)
387
+        ? calculer_boucle_rec($id_boucle, $boucles, $trace)
388
+        : calculer_boucle_nonrec($id_boucle, $boucles, $trace);
389 389
 }
390 390
 
391 391
 
@@ -408,15 +408,15 @@  discard block
 block discarded – undo
408 408
  *    Code PHP compilé de la boucle récursive
409 409
  **/
410 410
 function calculer_boucle_rec($id_boucle, &$boucles, $trace) {
411
-	$nom = $boucles[$id_boucle]->param[0];
412
-
413
-	return
414
-		// Numrows[$nom] peut ne pas être encore defini
415
-		"\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
416
-		. "\n\t\$t0 = " . $boucles[$id_boucle]->return . ";"
417
-		. "\n\t\$Numrows['$nom'] = (\$save_numrows);"
418
-		. $trace
419
-		. "\n\treturn \$t0;";
411
+    $nom = $boucles[$id_boucle]->param[0];
412
+
413
+    return
414
+        // Numrows[$nom] peut ne pas être encore defini
415
+        "\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
416
+        . "\n\t\$t0 = " . $boucles[$id_boucle]->return . ";"
417
+        . "\n\t\$Numrows['$nom'] = (\$save_numrows);"
418
+        . $trace
419
+        . "\n\treturn \$t0;";
420 420
 }
421 421
 
422 422
 /**
@@ -470,170 +470,170 @@  discard block
 block discarded – undo
470 470
  **/
471 471
 function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) {
472 472
 
473
-	$boucle = &$boucles[$id_boucle];
474
-	$return = $boucle->return;
475
-	$type_boucle = $boucle->type_requete;
476
-	$primary = $boucle->primary;
477
-	$constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return));
478
-	$flag_cpt = $boucle->mode_partie || $boucle->cptrows;
479
-	$corps = '';
480
-
481
-	// faudrait expanser le foreach a la compil, car y en a souvent qu'un 
482
-	// et puis faire un [] plutot qu'un "','."
483
-	if ($boucle->doublons) {
484
-		$corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
485
-			index_pile($id_boucle, $primary, $boucles)
486
-			. "; // doublons\n";
487
-	}
488
-
489
-	// La boucle doit-elle selectionner la langue ?
490
-	// - par defaut, les boucles suivantes le font
491
-	//    (sauf si forcer_lang==true ou si le titre contient <multi>).
492
-	// - a moins d'une demande explicite via {!lang_select}
493
-	if (!$constant && $boucle->lang_select != 'non' &&
494
-		(($boucle->lang_select == 'oui') ||
495
-			in_array($type_boucle, array(
496
-				'articles',
497
-				'rubriques',
498
-				'hierarchie',
499
-				'breves'
500
-			)))
501
-	) {
502
-		// Memoriser la langue avant la boucle et la restituer apres
503
-		// afin que le corps de boucle affecte la globale directement
504
-		$init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t";
505
-		$fin_lang = "lang_select();\n\t";
506
-		$fin_lang_select_public = "\n\t\tlang_select();";
507
-
508
-		$corps .=
509
-			"\n\t\tlang_select_public("
510
-			. index_pile($id_boucle, 'lang', $boucles)
511
-			. ", '" . $boucle->lang_select . "'"
512
-			. (in_array($type_boucle, array(
513
-				'articles',
514
-				'rubriques',
515
-				'hierarchie',
516
-				'breves'
517
-			)) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
518
-			. ');';
519
-	} else {
520
-		$init_lang = '';
521
-		$fin_lang = '';
522
-		$fin_lang_select_public = '';
523
-		// sortir les appels au traducteur (invariants de boucle)
524
-		if (strpos($return, '?php') === false
525
-			and preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r)
526
-		) {
527
-			$i = 1;
528
-			foreach ($r[1] as $t) {
529
-				$init_lang .= "\n\t\$l$i = $t;";
530
-				$return = str_replace($t, "\$l$i", $return);
531
-				$i++;
532
-			}
533
-		}
534
-	}
535
-
536
-	// gestion optimale des separateurs et des boucles constantes
537
-	if (count($boucle->separateur)) {
538
-		$code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
539
-	}
540
-
541
-	$corps .=
542
-		((!$boucle->separateur) ?
543
-			(($constant && !$corps && !$flag_cpt) ? $return :
544
-				(($return === "''") ? '' :
545
-					("\n\t\t" . '$t0 .= ' . $return . ";"))) :
546
-			("\n\t\t\$t1 " .
547
-				((strpos($return, '$t1.') === 0) ?
548
-					(".=" . substr($return, 4)) :
549
-					('= ' . $return)) .
550
-				";\n\t\t" .
551
-				'$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
552
-
553
-	// Calculer les invalideurs si c'est une boucle non constante et si on
554
-	// souhaite invalider ces elements
555
-	if (!$constant and $primary) {
556
-		include_spip('inc/invalideur');
557
-		$corps = calcul_invalideurs($corps, $primary,$boucles, $id_boucle);
558
-	}
559
-
560
-	// gerer le compteur de boucle 
561
-	// avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}...
562
-
563
-	if ($boucle->partie or $boucle->cptrows) {
564
-		$corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;"
565
-			. $boucle->partie
566
-			. $corps;
567
-	}
568
-
569
-	// depiler la lang de la boucle si besoin
570
-	$corps .= $fin_lang_select_public;
571
-
572
-	// si le corps est une constante, ne pas appeler le serveur N fois!
573
-
574
-	if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) {
575
-		if (!isset($r[2]) or (!$r[2])) {
576
-			if (!$boucle->numrows) {
577
-				return "\n\t\$t0 = '';";
578
-			} else {
579
-				$corps = "";
580
-			}
581
-		} else {
582
-			$boucle->numrows = true;
583
-			$corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);";
584
-		}
585
-	} else {
586
-		$corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n	}";
587
-	}
588
-
589
-	$count = '';
590
-	if (!$boucle->select) {
591
-		if (!$boucle->numrows or $boucle->limit or $boucle->mode_partie or $boucle->group) {
592
-			$count = '1';
593
-		} else {
594
-			$count = 'count(*)';
595
-		}
596
-		$boucles[$id_boucle]->select[] = $count;
597
-	}
598
-
599
-	if ($flag_cpt) {
600
-		$nums = "\n\t// COMPTEUR\n\t"
601
-			. "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t";
602
-	} else {
603
-		$nums = '';
604
-	}
605
-
606
-	if ($boucle->numrows or $boucle->mode_partie) {
607
-		$nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t"
608
-			. "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());"
609
-			. $boucle->mode_partie
610
-			. "\n\t";
611
-	}
612
-
613
-	// Ne calculer la requete que maintenant
614
-	// car ce qui precede appelle index_pile qui influe dessus
615
-
616
-	$init = (($init = $boucles[$id_boucle]->doublons)
617
-			? ("\n\t$init = array();") : '')
618
-		. calculer_requete_sql($boucles[$id_boucle]);
619
-
620
-	$contexte = memoriser_contexte_compil($boucle);
621
-
622
-	$a = sprintf(CODE_CORPS_BOUCLE,
623
-		$init,
624
-		$boucle->iterateur,
625
-		"\$command",
626
-		$contexte,
627
-		$nums,
628
-		$init_lang,
629
-		$corps,
630
-		$fin_lang,
631
-		$trace,
632
-		'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
633
-	);
473
+    $boucle = &$boucles[$id_boucle];
474
+    $return = $boucle->return;
475
+    $type_boucle = $boucle->type_requete;
476
+    $primary = $boucle->primary;
477
+    $constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return));
478
+    $flag_cpt = $boucle->mode_partie || $boucle->cptrows;
479
+    $corps = '';
480
+
481
+    // faudrait expanser le foreach a la compil, car y en a souvent qu'un 
482
+    // et puis faire un [] plutot qu'un "','."
483
+    if ($boucle->doublons) {
484
+        $corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
485
+            index_pile($id_boucle, $primary, $boucles)
486
+            . "; // doublons\n";
487
+    }
488
+
489
+    // La boucle doit-elle selectionner la langue ?
490
+    // - par defaut, les boucles suivantes le font
491
+    //    (sauf si forcer_lang==true ou si le titre contient <multi>).
492
+    // - a moins d'une demande explicite via {!lang_select}
493
+    if (!$constant && $boucle->lang_select != 'non' &&
494
+        (($boucle->lang_select == 'oui') ||
495
+            in_array($type_boucle, array(
496
+                'articles',
497
+                'rubriques',
498
+                'hierarchie',
499
+                'breves'
500
+            )))
501
+    ) {
502
+        // Memoriser la langue avant la boucle et la restituer apres
503
+        // afin que le corps de boucle affecte la globale directement
504
+        $init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t";
505
+        $fin_lang = "lang_select();\n\t";
506
+        $fin_lang_select_public = "\n\t\tlang_select();";
507
+
508
+        $corps .=
509
+            "\n\t\tlang_select_public("
510
+            . index_pile($id_boucle, 'lang', $boucles)
511
+            . ", '" . $boucle->lang_select . "'"
512
+            . (in_array($type_boucle, array(
513
+                'articles',
514
+                'rubriques',
515
+                'hierarchie',
516
+                'breves'
517
+            )) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
518
+            . ');';
519
+    } else {
520
+        $init_lang = '';
521
+        $fin_lang = '';
522
+        $fin_lang_select_public = '';
523
+        // sortir les appels au traducteur (invariants de boucle)
524
+        if (strpos($return, '?php') === false
525
+            and preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r)
526
+        ) {
527
+            $i = 1;
528
+            foreach ($r[1] as $t) {
529
+                $init_lang .= "\n\t\$l$i = $t;";
530
+                $return = str_replace($t, "\$l$i", $return);
531
+                $i++;
532
+            }
533
+        }
534
+    }
535
+
536
+    // gestion optimale des separateurs et des boucles constantes
537
+    if (count($boucle->separateur)) {
538
+        $code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
539
+    }
540
+
541
+    $corps .=
542
+        ((!$boucle->separateur) ?
543
+            (($constant && !$corps && !$flag_cpt) ? $return :
544
+                (($return === "''") ? '' :
545
+                    ("\n\t\t" . '$t0 .= ' . $return . ";"))) :
546
+            ("\n\t\t\$t1 " .
547
+                ((strpos($return, '$t1.') === 0) ?
548
+                    (".=" . substr($return, 4)) :
549
+                    ('= ' . $return)) .
550
+                ";\n\t\t" .
551
+                '$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
552
+
553
+    // Calculer les invalideurs si c'est une boucle non constante et si on
554
+    // souhaite invalider ces elements
555
+    if (!$constant and $primary) {
556
+        include_spip('inc/invalideur');
557
+        $corps = calcul_invalideurs($corps, $primary,$boucles, $id_boucle);
558
+    }
559
+
560
+    // gerer le compteur de boucle 
561
+    // avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}...
562
+
563
+    if ($boucle->partie or $boucle->cptrows) {
564
+        $corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;"
565
+            . $boucle->partie
566
+            . $corps;
567
+    }
568
+
569
+    // depiler la lang de la boucle si besoin
570
+    $corps .= $fin_lang_select_public;
571
+
572
+    // si le corps est une constante, ne pas appeler le serveur N fois!
573
+
574
+    if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) {
575
+        if (!isset($r[2]) or (!$r[2])) {
576
+            if (!$boucle->numrows) {
577
+                return "\n\t\$t0 = '';";
578
+            } else {
579
+                $corps = "";
580
+            }
581
+        } else {
582
+            $boucle->numrows = true;
583
+            $corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);";
584
+        }
585
+    } else {
586
+        $corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n	}";
587
+    }
588
+
589
+    $count = '';
590
+    if (!$boucle->select) {
591
+        if (!$boucle->numrows or $boucle->limit or $boucle->mode_partie or $boucle->group) {
592
+            $count = '1';
593
+        } else {
594
+            $count = 'count(*)';
595
+        }
596
+        $boucles[$id_boucle]->select[] = $count;
597
+    }
598
+
599
+    if ($flag_cpt) {
600
+        $nums = "\n\t// COMPTEUR\n\t"
601
+            . "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t";
602
+    } else {
603
+        $nums = '';
604
+    }
605
+
606
+    if ($boucle->numrows or $boucle->mode_partie) {
607
+        $nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t"
608
+            . "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());"
609
+            . $boucle->mode_partie
610
+            . "\n\t";
611
+    }
612
+
613
+    // Ne calculer la requete que maintenant
614
+    // car ce qui precede appelle index_pile qui influe dessus
615
+
616
+    $init = (($init = $boucles[$id_boucle]->doublons)
617
+            ? ("\n\t$init = array();") : '')
618
+        . calculer_requete_sql($boucles[$id_boucle]);
619
+
620
+    $contexte = memoriser_contexte_compil($boucle);
621
+
622
+    $a = sprintf(CODE_CORPS_BOUCLE,
623
+        $init,
624
+        $boucle->iterateur,
625
+        "\$command",
626
+        $contexte,
627
+        $nums,
628
+        $init_lang,
629
+        $corps,
630
+        $fin_lang,
631
+        $trace,
632
+        'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
633
+    );
634 634
 
635 635
 #	var_dump($a);exit;
636
-	return $a;
636
+    return $a;
637 637
 }
638 638
 
639 639
 
@@ -649,43 +649,43 @@  discard block
 block discarded – undo
649 649
  *     Code PHP compilé définissant les informations de requête
650 650
  **/
651 651
 function calculer_requete_sql($boucle) {
652
-	$init = array();
653
-	$init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
654
-	$init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
655
-	# En absence de champ c'est un decompte :
656
-	$init[] = calculer_dec('from', calculer_from($boucle));
657
-	$init[] = calculer_dec('type', calculer_from_type($boucle));
658
-	$init[] = calculer_dec('groupby',
659
-		'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ")");
660
-	$init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . "\")");
661
-	$init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ")");
662
-	$init[] = calculer_dec('where', calculer_dump_array($boucle->where));
663
-	$init[] = calculer_dec('join', calculer_dump_join($boucle->join));
664
-	$init[] = calculer_dec('limit',
665
-		(strpos($boucle->limit, 'intval') === false ?
666
-			"'" . $boucle->limit . "'"
667
-			:
668
-			$boucle->limit));
669
-	$init[] = calculer_dec('having', calculer_dump_array($boucle->having));
670
-	$s = $d = "";
671
-	// l'index 0 de $i indique si l'affectation est statique (contenu)
672
-	// ou recalculée à chaque passage (vide)
673
-	foreach ($init as $i) {
674
-		if (reset($i)) {
675
-			$s .= "\n\t\t" . end($i);
676
-		} # statique
677
-		else {
678
-			$d .= "\n\t" . end($i);
679
-		} # dynamique
680
-	}
681
-
682
-	return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
683
-	. $boucle->in
684
-	. $boucle->hash
685
-	. "\n\t" . 'if (!isset($command[\'table\'])) {'
686
-	. $s
687
-	. "\n\t}"
688
-	. $d;
652
+    $init = array();
653
+    $init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
654
+    $init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
655
+    # En absence de champ c'est un decompte :
656
+    $init[] = calculer_dec('from', calculer_from($boucle));
657
+    $init[] = calculer_dec('type', calculer_from_type($boucle));
658
+    $init[] = calculer_dec('groupby',
659
+        'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ")");
660
+    $init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . "\")");
661
+    $init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ")");
662
+    $init[] = calculer_dec('where', calculer_dump_array($boucle->where));
663
+    $init[] = calculer_dec('join', calculer_dump_join($boucle->join));
664
+    $init[] = calculer_dec('limit',
665
+        (strpos($boucle->limit, 'intval') === false ?
666
+            "'" . $boucle->limit . "'"
667
+            :
668
+            $boucle->limit));
669
+    $init[] = calculer_dec('having', calculer_dump_array($boucle->having));
670
+    $s = $d = "";
671
+    // l'index 0 de $i indique si l'affectation est statique (contenu)
672
+    // ou recalculée à chaque passage (vide)
673
+    foreach ($init as $i) {
674
+        if (reset($i)) {
675
+            $s .= "\n\t\t" . end($i);
676
+        } # statique
677
+        else {
678
+            $d .= "\n\t" . end($i);
679
+        } # dynamique
680
+    }
681
+
682
+    return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
683
+    . $boucle->in
684
+    . $boucle->hash
685
+    . "\n\t" . 'if (!isset($command[\'table\'])) {'
686
+    . $s
687
+    . "\n\t}"
688
+    . $d;
689 689
 }
690 690
 
691 691
 /**
@@ -703,13 +703,13 @@  discard block
 block discarded – undo
703 703
  *     qui peut être utilisé pour la production d'un tableau array()
704 704
  **/
705 705
 function memoriser_contexte_compil($p) {
706
-	return join(',', array(
707
-		_q(isset($p->descr['sourcefile']) ? $p->descr['sourcefile'] : ''),
708
-		_q(isset($p->descr['nom']) ? $p->descr['nom'] : ''),
709
-		_q(isset($p->id_boucle) ? $p->id_boucle : null),
710
-		intval($p->ligne),
711
-		'$GLOBALS[\'spip_lang\']'
712
-	));
706
+    return join(',', array(
707
+        _q(isset($p->descr['sourcefile']) ? $p->descr['sourcefile'] : ''),
708
+        _q(isset($p->descr['nom']) ? $p->descr['nom'] : ''),
709
+        _q(isset($p->id_boucle) ? $p->id_boucle : null),
710
+        intval($p->ligne),
711
+        '$GLOBALS[\'spip_lang\']'
712
+    ));
713 713
 }
714 714
 
715 715
 /**
@@ -727,19 +727,19 @@  discard block
 block discarded – undo
727 727
  *     Objet Contexte
728 728
  **/
729 729
 function reconstruire_contexte_compil($context_compil) {
730
-	if (!is_array($context_compil)) {
731
-		return $context_compil;
732
-	}
733
-	$p = new Contexte;
734
-	$p->descr = array(
735
-		'sourcefile' => $context_compil[0],
736
-		'nom' => $context_compil[1]
737
-	);
738
-	$p->id_boucle = $context_compil[2];
739
-	$p->ligne = $context_compil[3];
740
-	$p->lang = $context_compil[4];
741
-
742
-	return $p;
730
+    if (!is_array($context_compil)) {
731
+        return $context_compil;
732
+    }
733
+    $p = new Contexte;
734
+    $p->descr = array(
735
+        'sourcefile' => $context_compil[0],
736
+        'nom' => $context_compil[1]
737
+    );
738
+    $p->id_boucle = $context_compil[2];
739
+    $p->ligne = $context_compil[3];
740
+    $p->lang = $context_compil[4];
741
+
742
+    return $p;
743 743
 }
744 744
 
745 745
 /**
@@ -765,12 +765,12 @@  discard block
 block discarded – undo
765 765
  *    - index 1 : Code de l'affectation
766 766
  **/
767 767
 function calculer_dec($nom, $val) {
768
-	$static = 'if (!isset($command[\'' . $nom . '\'])) ';
769
-	// si une variable apparait dans le calcul de la clause
770
-	// il faut la re-evaluer a chaque passage
771
-	if (
772
-		strpos($val, '$') !== false
773
-		/*
768
+    $static = 'if (!isset($command[\'' . $nom . '\'])) ';
769
+    // si une variable apparait dans le calcul de la clause
770
+    // il faut la re-evaluer a chaque passage
771
+    if (
772
+        strpos($val, '$') !== false
773
+        /*
774 774
 		OR strpos($val, 'sql_') !== false
775 775
 		OR (
776 776
 			$test = str_replace(array("array(",'\"',"\'"),array("","",""),$val) // supprimer les array( et les echappements de guillemets
@@ -778,11 +778,11 @@  discard block
 block discarded – undo
778 778
 			AND $test = preg_replace(",'[^']*',UimsS","",$test) // supprimer les chaines qui peuvent contenir des fonctions SQL qui ne genent pas
779 779
 			AND preg_match(",\w+\s*\(,UimsS",$test,$regs) // tester la presence de fonctions restantes
780 780
 		)*/
781
-	) {
782
-		$static = "";
783
-	}
781
+    ) {
782
+        $static = "";
783
+    }
784 784
 
785
-	return array($static, '$command[\'' . $nom . '\'] = ' . $val . ';');
785
+    return array($static, '$command[\'' . $nom . '\'] = ' . $val . ';');
786 786
 }
787 787
 
788 788
 /**
@@ -802,33 +802,33 @@  discard block
 block discarded – undo
802 802
  *     Expression PHP décrivant un texte ou un tableau
803 803
  **/
804 804
 function calculer_dump_array($a) {
805
-	if (!is_array($a)) {
806
-		return $a;
807
-	}
808
-	$res = "";
809
-	if ($a and $a[0] == "'?'") {
810
-		return ("(" . calculer_dump_array($a[1]) .
811
-			" ? " . calculer_dump_array($a[2]) .
812
-			" : " . calculer_dump_array($a[3]) .
813
-			")");
814
-	} else {
815
-		foreach ($a as $k => $v) {
816
-			$showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
817
-			$res .= ", " . $showk . calculer_dump_array($v);
818
-		}
819
-
820
-		return "\n\t\t\tarray(" . substr($res, 2) . ')';
821
-	}
805
+    if (!is_array($a)) {
806
+        return $a;
807
+    }
808
+    $res = "";
809
+    if ($a and $a[0] == "'?'") {
810
+        return ("(" . calculer_dump_array($a[1]) .
811
+            " ? " . calculer_dump_array($a[2]) .
812
+            " : " . calculer_dump_array($a[3]) .
813
+            ")");
814
+    } else {
815
+        foreach ($a as $k => $v) {
816
+            $showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
817
+            $res .= ", " . $showk . calculer_dump_array($v);
818
+        }
819
+
820
+        return "\n\t\t\tarray(" . substr($res, 2) . ')';
821
+    }
822 822
 }
823 823
 
824 824
 // https://code.spip.net/@calculer_dump_join
825 825
 function calculer_dump_join($a) {
826
-	$res = "";
827
-	foreach ($a as $k => $v) {
828
-		$res .= ", '$k' => array(" . implode(',', $v) . ")";
829
-	}
826
+    $res = "";
827
+    foreach ($a as $k => $v) {
828
+        $res .= ", '$k' => array(" . implode(',', $v) . ")";
829
+    }
830 830
 
831
-	return 'array(' . substr($res, 2) . ')';
831
+    return 'array(' . substr($res, 2) . ')';
832 832
 }
833 833
 
834 834
 /**
@@ -840,12 +840,12 @@  discard block
 block discarded – undo
840 840
  *     Code PHP construisant un tableau des alias et noms des tables du FROM
841 841
  **/
842 842
 function calculer_from(&$boucle) {
843
-	$res = "";
844
-	foreach ($boucle->from as $k => $v) {
845
-		$res .= ",'$k' => '$v'";
846
-	}
843
+    $res = "";
844
+    foreach ($boucle->from as $k => $v) {
845
+        $res .= ",'$k' => '$v'";
846
+    }
847 847
 
848
-	return 'array(' . substr($res, 1) . ')';
848
+    return 'array(' . substr($res, 1) . ')';
849 849
 }
850 850
 
851 851
 /**
@@ -858,30 +858,30 @@  discard block
 block discarded – undo
858 858
  *     Code PHP construisant un tableau des alias et type de jointure du FROM
859 859
  **/
860 860
 function calculer_from_type(&$boucle) {
861
-	$res = "";
862
-	foreach ($boucle->from_type as $k => $v) {
863
-		$res .= ",'$k' => '$v'";
864
-	}
861
+    $res = "";
862
+    foreach ($boucle->from_type as $k => $v) {
863
+        $res .= ",'$k' => '$v'";
864
+    }
865 865
 
866
-	return 'array(' . substr($res, 1) . ')';
866
+    return 'array(' . substr($res, 1) . ')';
867 867
 }
868 868
 
869 869
 // https://code.spip.net/@calculer_order
870 870
 function calculer_order(&$boucle) {
871
-	if (!$order = $boucle->order
872
-		and !$order = $boucle->default_order
873
-	) {
874
-		$order = array();
875
-	}
871
+    if (!$order = $boucle->order
872
+        and !$order = $boucle->default_order
873
+    ) {
874
+        $order = array();
875
+    }
876 876
 
877
-	/*if (isset($boucle->modificateur['collate'])){
877
+    /*if (isset($boucle->modificateur['collate'])){
878 878
 		$col = "." . $boucle->modificateur['collate'];
879 879
 		foreach($order as $k=>$o)
880 880
 			if (strpos($order[$k],'COLLATE')===false)
881 881
 				$order[$k].= $col;
882 882
 	}*/
883 883
 
884
-	return join(', ', $order);
884
+    return join(', ', $order);
885 885
 }
886 886
 
887 887
 // Production du code PHP a partir de la sequence livree par le phraseur
@@ -891,59 +891,59 @@  discard block
 block discarded – undo
891 891
 
892 892
 // https://code.spip.net/@calculer_liste
893 893
 function calculer_liste($tableau, $descr, &$boucles, $id_boucle = '') {
894
-	if (!$tableau) {
895
-		return "''";
896
-	}
897
-	if (is_string($descr)) {
898
-		if (isset($boucles[$descr])) {
899
-			$idb = $descr;
900
-			$descr = [];
901
-			if (isset($boucles[$idb]->descr['id_mere_contexte'])) {
902
-				$descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte'];
903
-			}
904
-			if (isset($boucles[$idb]->descr['sourcefile'])) {
905
-				$descr['sourcefile'] = $boucles[$idb]->descr['sourcefile'];
906
-			}
907
-		}
908
-		else {
909
-			$descr = array();
910
-		}
911
-	}
912
-	if (!isset($descr['niv'])) {
913
-		$descr['niv'] = 0;
914
-	}
915
-	$codes = compile_cas($tableau, $descr, $boucles, $id_boucle);
916
-	if ($codes === false) {
917
-		return false;
918
-	}
919
-	$n = count($codes);
920
-	if (!$n) {
921
-		return "''";
922
-	}
923
-	$tab = str_repeat("\t", $descr['niv']);
924
-	if (_request('var_mode_affiche') != 'validation') {
925
-		if ($n == 1) {
926
-			return $codes[0];
927
-		} else {
928
-			$res = '';
929
-			foreach ($codes as $code) {
930
-				if (!preg_match("/^'[^']*'$/", $code)
931
-					or substr($res, -1, 1) !== "'"
932
-				) {
933
-					$res .= " .\n$tab$code";
934
-				} else {
935
-					$res = substr($res, 0, -1) . substr($code, 1);
936
-				}
937
-			}
938
-
939
-			return '(' . substr($res, 2 + $descr['niv']) . ')';
940
-		}
941
-	} else {
942
-		$nom = $descr['nom'] . $id_boucle . ($descr['niv'] ? $descr['niv'] : '');
943
-
944
-		return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(" ,\n$tab",
945
-			$codes) . ")))";
946
-	}
894
+    if (!$tableau) {
895
+        return "''";
896
+    }
897
+    if (is_string($descr)) {
898
+        if (isset($boucles[$descr])) {
899
+            $idb = $descr;
900
+            $descr = [];
901
+            if (isset($boucles[$idb]->descr['id_mere_contexte'])) {
902
+                $descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte'];
903
+            }
904
+            if (isset($boucles[$idb]->descr['sourcefile'])) {
905
+                $descr['sourcefile'] = $boucles[$idb]->descr['sourcefile'];
906
+            }
907
+        }
908
+        else {
909
+            $descr = array();
910
+        }
911
+    }
912
+    if (!isset($descr['niv'])) {
913
+        $descr['niv'] = 0;
914
+    }
915
+    $codes = compile_cas($tableau, $descr, $boucles, $id_boucle);
916
+    if ($codes === false) {
917
+        return false;
918
+    }
919
+    $n = count($codes);
920
+    if (!$n) {
921
+        return "''";
922
+    }
923
+    $tab = str_repeat("\t", $descr['niv']);
924
+    if (_request('var_mode_affiche') != 'validation') {
925
+        if ($n == 1) {
926
+            return $codes[0];
927
+        } else {
928
+            $res = '';
929
+            foreach ($codes as $code) {
930
+                if (!preg_match("/^'[^']*'$/", $code)
931
+                    or substr($res, -1, 1) !== "'"
932
+                ) {
933
+                    $res .= " .\n$tab$code";
934
+                } else {
935
+                    $res = substr($res, 0, -1) . substr($code, 1);
936
+                }
937
+            }
938
+
939
+            return '(' . substr($res, 2 + $descr['niv']) . ')';
940
+        }
941
+    } else {
942
+        $nom = $descr['nom'] . $id_boucle . ($descr['niv'] ? $descr['niv'] : '');
943
+
944
+        return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(" ,\n$tab",
945
+            $codes) . ")))";
946
+    }
947 947
 }
948 948
 
949 949
 
@@ -954,203 +954,203 @@  discard block
 block discarded – undo
954 954
 // https://code.spip.net/@compile_cas
955 955
 function compile_cas($tableau, $descr, &$boucles, $id_boucle) {
956 956
 
957
-	$codes = array();
958
-	// cas de la boucle recursive
959
-	if (is_array($id_boucle)) {
960
-		$id_boucle = $id_boucle[0];
961
-	}
962
-	$type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete;
963
-	$tab = str_repeat("\t", ++$descr['niv']);
964
-	$mode = _request('var_mode_affiche');
965
-	$err_e_c = '';
966
-	// chaque commentaire introduit dans le code doit commencer
967
-	// par un caractere distinguant le cas, pour exploitation par debug.
968
-	foreach ($tableau as $p) {
969
-
970
-		switch ($p->type) {
971
-			// texte seul
972
-			case 'texte':
973
-				$code = sandbox_composer_texte($p->texte, $p);
974
-				$commentaire = strlen($p->texte) . " signes";
975
-				$avant = '';
976
-				$apres = '';
977
-				$altern = "''";
978
-				break;
979
-
980
-			case 'polyglotte':
981
-				$code = "";
982
-				foreach ($p->traductions as $k => $v) {
983
-					$code .= ",'" .
984
-						str_replace(array("\\", "'"), array("\\\\", "\\'"), $k) .
985
-						"' => '" .
986
-						str_replace(array("\\", "'"), array("\\\\", "\\'"), $v) .
987
-						"'";
988
-				}
989
-				$code = "choisir_traduction(array(" .
990
-					substr($code, 1) .
991
-					"))";
992
-				$commentaire = '&';
993
-				$avant = '';
994
-				$apres = '';
995
-				$altern = "''";
996
-				break;
997
-
998
-			// inclure
999
-			case 'include':
1000
-				$p->descr = $descr;
1001
-				$code = calculer_inclure($p, $boucles, $id_boucle);
1002
-				if ($code === false) {
1003
-					$err_e_c = true;
1004
-					$code = "''";
1005
-				} else {
1006
-					$commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1007
-					$avant = '';
1008
-					$apres = '';
1009
-					$altern = "''";
1010
-				}
1011
-				break;
1012
-
1013
-			// boucle
1014
-			case TYPE_RECURSIF:
1015
-				$nom = $p->id_boucle;
1016
-				$newdescr = $descr;
1017
-				$newdescr['id_mere'] = $nom;
1018
-				$newdescr['niv']++;
1019
-				$preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle);
1020
-				$avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle);
1021
-				$apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle);
1022
-				$postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle);
1023
-				$newdescr['niv']--;
1024
-				$altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle);
1025
-				if ($preaff === false
1026
-					or $avant === false
1027
-					or $apres === false
1028
-					or $altern === false
1029
-					or $postaff === false) {
1030
-					$err_e_c = true;
1031
-					$code = "''";
1032
-				} else {
1033
-					$code = 'BOUCLE' .
1034
-						str_replace("-", "_", $nom) . $descr['nom'] .
1035
-						'($Cache, $Pile, $doublons, $Numrows, $SP)';
1036
-					$commentaire = "?$nom";
1037
-					if (!$boucles[$nom]->milieu
1038
-						and $boucles[$nom]->type_requete <> TYPE_RECURSIF
1039
-					) {
1040
-						if ($preaff != "''") {
1041
-							$code .= "\n. $preaff";
1042
-						}
1043
-						if ($altern != "''") {
1044
-							$code .= "\n. $altern";
1045
-						}
1046
-						if ($postaff != "''") {
1047
-							$code .= "\n. $postaff";
1048
-						}
1049
-						if ($avant <> "''" or $apres <> "''") {
1050
-							spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]");
1051
-						}
1052
-						$avant = $apres = $altern = "''";
1053
-					} else {
1054
-						if ($preaff != "''") {
1055
-							$avant = compile_concatene_parties_codes($preaff, $avant);
1056
-							$altern = compile_concatene_parties_codes($preaff, $altern);
1057
-						}
1058
-						if ($postaff != "''") {
1059
-							$apres = compile_concatene_parties_codes($apres, $postaff);
1060
-							$altern = compile_concatene_parties_codes($altern, $postaff);
1061
-						}
1062
-						if ($altern != "''") {
1063
-							$altern = "($altern)";
1064
-						}
1065
-					}
1066
-				}
1067
-				break;
1068
-
1069
-			case 'idiome':
1070
-				$l = array();
1071
-				$code = '';
1072
-				foreach ($p->arg as $k => $v) {
1073
-					$_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1074
-					if ($k) {
1075
-						$l[] = _q($k) . ' => ' . $_v;
1076
-					} else {
1077
-						$code = $_v;
1078
-					}
1079
-				}
1080
-				// Si le module n'est pas fourni, l'expliciter sauf si calculé
1081
-				if ($p->module) {
1082
-					$m = $p->module . ':' . $p->nom_champ;
1083
-				} elseif ($p->nom_champ) {
1084
-					$m = MODULES_IDIOMES . ':' . $p->nom_champ;
1085
-				} else {
1086
-					$m = '';
1087
-				}
1088
-
1089
-				$code = (!$code ? "'$m'" :
1090
-						($m ? "'$m' . $code" :
1091
-							("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1092
-					. (!$l ? '' : (", array(" . implode(",\n", $l) . ")"));
1093
-				$code = "_T($code)";
1094
-				if ($p->param) {
1095
-					$p->id_boucle = $id_boucle;
1096
-					$p->boucles = &$boucles;
1097
-					$code = compose_filtres($p, $code);
1098
-				}
1099
-				$commentaire = ":";
1100
-				$avant = '';
1101
-				$apres = '';
1102
-				$altern = "''";
1103
-				break;
1104
-
1105
-			case 'champ':
1106
-
1107
-				// cette structure pourrait etre completee des le phrase' (a faire)
1108
-				$p->id_boucle = $id_boucle;
1109
-				$p->boucles = &$boucles;
1110
-				$p->descr = $descr;
1111
-				#$p->interdire_scripts = true;
1112
-				$p->type_requete = $type;
1113
-
1114
-				$code = calculer_champ($p);
1115
-				$commentaire = '#' . $p->nom_champ . $p->etoile;
1116
-				$avant = calculer_liste($p->avant,
1117
-					$descr, $boucles, $id_boucle);
1118
-				$apres = calculer_liste($p->apres,
1119
-					$descr, $boucles, $id_boucle);
1120
-				$altern = "''";
1121
-				// Si la valeur est destinee a une comparaison a ''
1122
-				// forcer la conversion en une chaine par strval
1123
-				// si ca peut etre autre chose qu'une chaine
1124
-				if (($avant != "''" or $apres != "''")
1125
-					and $code[0] != "'"
957
+    $codes = array();
958
+    // cas de la boucle recursive
959
+    if (is_array($id_boucle)) {
960
+        $id_boucle = $id_boucle[0];
961
+    }
962
+    $type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete;
963
+    $tab = str_repeat("\t", ++$descr['niv']);
964
+    $mode = _request('var_mode_affiche');
965
+    $err_e_c = '';
966
+    // chaque commentaire introduit dans le code doit commencer
967
+    // par un caractere distinguant le cas, pour exploitation par debug.
968
+    foreach ($tableau as $p) {
969
+
970
+        switch ($p->type) {
971
+            // texte seul
972
+            case 'texte':
973
+                $code = sandbox_composer_texte($p->texte, $p);
974
+                $commentaire = strlen($p->texte) . " signes";
975
+                $avant = '';
976
+                $apres = '';
977
+                $altern = "''";
978
+                break;
979
+
980
+            case 'polyglotte':
981
+                $code = "";
982
+                foreach ($p->traductions as $k => $v) {
983
+                    $code .= ",'" .
984
+                        str_replace(array("\\", "'"), array("\\\\", "\\'"), $k) .
985
+                        "' => '" .
986
+                        str_replace(array("\\", "'"), array("\\\\", "\\'"), $v) .
987
+                        "'";
988
+                }
989
+                $code = "choisir_traduction(array(" .
990
+                    substr($code, 1) .
991
+                    "))";
992
+                $commentaire = '&';
993
+                $avant = '';
994
+                $apres = '';
995
+                $altern = "''";
996
+                break;
997
+
998
+            // inclure
999
+            case 'include':
1000
+                $p->descr = $descr;
1001
+                $code = calculer_inclure($p, $boucles, $id_boucle);
1002
+                if ($code === false) {
1003
+                    $err_e_c = true;
1004
+                    $code = "''";
1005
+                } else {
1006
+                    $commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1007
+                    $avant = '';
1008
+                    $apres = '';
1009
+                    $altern = "''";
1010
+                }
1011
+                break;
1012
+
1013
+            // boucle
1014
+            case TYPE_RECURSIF:
1015
+                $nom = $p->id_boucle;
1016
+                $newdescr = $descr;
1017
+                $newdescr['id_mere'] = $nom;
1018
+                $newdescr['niv']++;
1019
+                $preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle);
1020
+                $avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle);
1021
+                $apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle);
1022
+                $postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle);
1023
+                $newdescr['niv']--;
1024
+                $altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle);
1025
+                if ($preaff === false
1026
+                    or $avant === false
1027
+                    or $apres === false
1028
+                    or $altern === false
1029
+                    or $postaff === false) {
1030
+                    $err_e_c = true;
1031
+                    $code = "''";
1032
+                } else {
1033
+                    $code = 'BOUCLE' .
1034
+                        str_replace("-", "_", $nom) . $descr['nom'] .
1035
+                        '($Cache, $Pile, $doublons, $Numrows, $SP)';
1036
+                    $commentaire = "?$nom";
1037
+                    if (!$boucles[$nom]->milieu
1038
+                        and $boucles[$nom]->type_requete <> TYPE_RECURSIF
1039
+                    ) {
1040
+                        if ($preaff != "''") {
1041
+                            $code .= "\n. $preaff";
1042
+                        }
1043
+                        if ($altern != "''") {
1044
+                            $code .= "\n. $altern";
1045
+                        }
1046
+                        if ($postaff != "''") {
1047
+                            $code .= "\n. $postaff";
1048
+                        }
1049
+                        if ($avant <> "''" or $apres <> "''") {
1050
+                            spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]");
1051
+                        }
1052
+                        $avant = $apres = $altern = "''";
1053
+                    } else {
1054
+                        if ($preaff != "''") {
1055
+                            $avant = compile_concatene_parties_codes($preaff, $avant);
1056
+                            $altern = compile_concatene_parties_codes($preaff, $altern);
1057
+                        }
1058
+                        if ($postaff != "''") {
1059
+                            $apres = compile_concatene_parties_codes($apres, $postaff);
1060
+                            $altern = compile_concatene_parties_codes($altern, $postaff);
1061
+                        }
1062
+                        if ($altern != "''") {
1063
+                            $altern = "($altern)";
1064
+                        }
1065
+                    }
1066
+                }
1067
+                break;
1068
+
1069
+            case 'idiome':
1070
+                $l = array();
1071
+                $code = '';
1072
+                foreach ($p->arg as $k => $v) {
1073
+                    $_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1074
+                    if ($k) {
1075
+                        $l[] = _q($k) . ' => ' . $_v;
1076
+                    } else {
1077
+                        $code = $_v;
1078
+                    }
1079
+                }
1080
+                // Si le module n'est pas fourni, l'expliciter sauf si calculé
1081
+                if ($p->module) {
1082
+                    $m = $p->module . ':' . $p->nom_champ;
1083
+                } elseif ($p->nom_champ) {
1084
+                    $m = MODULES_IDIOMES . ':' . $p->nom_champ;
1085
+                } else {
1086
+                    $m = '';
1087
+                }
1088
+
1089
+                $code = (!$code ? "'$m'" :
1090
+                        ($m ? "'$m' . $code" :
1091
+                            ("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1092
+                    . (!$l ? '' : (", array(" . implode(",\n", $l) . ")"));
1093
+                $code = "_T($code)";
1094
+                if ($p->param) {
1095
+                    $p->id_boucle = $id_boucle;
1096
+                    $p->boucles = &$boucles;
1097
+                    $code = compose_filtres($p, $code);
1098
+                }
1099
+                $commentaire = ":";
1100
+                $avant = '';
1101
+                $apres = '';
1102
+                $altern = "''";
1103
+                break;
1104
+
1105
+            case 'champ':
1106
+
1107
+                // cette structure pourrait etre completee des le phrase' (a faire)
1108
+                $p->id_boucle = $id_boucle;
1109
+                $p->boucles = &$boucles;
1110
+                $p->descr = $descr;
1111
+                #$p->interdire_scripts = true;
1112
+                $p->type_requete = $type;
1113
+
1114
+                $code = calculer_champ($p);
1115
+                $commentaire = '#' . $p->nom_champ . $p->etoile;
1116
+                $avant = calculer_liste($p->avant,
1117
+                    $descr, $boucles, $id_boucle);
1118
+                $apres = calculer_liste($p->apres,
1119
+                    $descr, $boucles, $id_boucle);
1120
+                $altern = "''";
1121
+                // Si la valeur est destinee a une comparaison a ''
1122
+                // forcer la conversion en une chaine par strval
1123
+                // si ca peut etre autre chose qu'une chaine
1124
+                if (($avant != "''" or $apres != "''")
1125
+                    and $code[0] != "'"
1126 1126
 #			AND (strpos($code,'interdire_scripts') !== 0)
1127
-					and !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code)
1128
-					and !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code)
1129
-					and !preg_match(_REGEXP_CONCAT_NON_VIDE, $code)
1130
-				) {
1131
-					$code = "strval($code)";
1132
-				}
1133
-				break;
1134
-
1135
-			default:
1136
-				// Erreur de construction de l'arbre de syntaxe abstraite
1137
-				$code = "''";
1138
-				$p->descr = $descr;
1139
-				$err_e_c = _T('zbug_erreur_compilation');
1140
-				erreur_squelette($err_e_c, $p);
1141
-		} // switch
1142
-
1143
-		if ($code != "''") {
1144
-			$code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1145
-			$codes[] = (($mode == 'validation') ?
1146
-				"array($code, '$commentaire', " . $p->ligne . ")"
1147
-				: (($mode == 'code') ?
1148
-					"\n// $commentaire\n$code" :
1149
-					$code));
1150
-		}
1151
-	} // foreach
1152
-
1153
-	return $err_e_c ? false : $codes;
1127
+                    and !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code)
1128
+                    and !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code)
1129
+                    and !preg_match(_REGEXP_CONCAT_NON_VIDE, $code)
1130
+                ) {
1131
+                    $code = "strval($code)";
1132
+                }
1133
+                break;
1134
+
1135
+            default:
1136
+                // Erreur de construction de l'arbre de syntaxe abstraite
1137
+                $code = "''";
1138
+                $p->descr = $descr;
1139
+                $err_e_c = _T('zbug_erreur_compilation');
1140
+                erreur_squelette($err_e_c, $p);
1141
+        } // switch
1142
+
1143
+        if ($code != "''") {
1144
+            $code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1145
+            $codes[] = (($mode == 'validation') ?
1146
+                "array($code, '$commentaire', " . $p->ligne . ")"
1147
+                : (($mode == 'code') ?
1148
+                    "\n// $commentaire\n$code" :
1149
+                    $code));
1150
+        }
1151
+    } // foreach
1152
+
1153
+    return $err_e_c ? false : $codes;
1154 1154
 }
1155 1155
 
1156 1156
 /**
@@ -1160,13 +1160,13 @@  discard block
 block discarded – undo
1160 1160
  * @return string
1161 1161
  */
1162 1162
 function compile_concatene_parties_codes($partie1, $partie2) {
1163
-	if ($partie1 === "''") {
1164
-		return $partie2;
1165
-	}
1166
-	if ($partie2 === "''") {
1167
-		return $partie1;
1168
-	}
1169
-	return "$partie1\n. $partie2";
1163
+    if ($partie1 === "''") {
1164
+        return $partie2;
1165
+    }
1166
+    if ($partie2 === "''") {
1167
+        return $partie1;
1168
+    }
1169
+    return "$partie1\n. $partie2";
1170 1170
 }
1171 1171
 
1172 1172
 
@@ -1191,57 +1191,57 @@  discard block
 block discarded – undo
1191 1191
  * @return mixed|string
1192 1192
  */
1193 1193
 function compile_retour($code, $avant, $apres, $altern, $tab, $n) {
1194
-	if ($avant === "''") {
1195
-		$avant = '';
1196
-	}
1197
-	if ($apres === "''") {
1198
-		$apres = '';
1199
-	}
1200
-	if ($avant or $apres or ($altern !== "''")){
1201
-		if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)){
1202
-			$t = $code;
1203
-			$cond = '';
1204
-		} elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1205
-			$t = $r[2];
1206
-			$cond = '!' . $r[1];
1207
-		} else {
1208
-			if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)){
1209
-				$t = $r[2];
1210
-				$cond = $r[1];
1211
-			} else {
1212
-				$t = '$t' . $n;
1213
-				$cond = "($t = $code)!==''";
1214
-			}
1215
-		}
1216
-
1217
-		$res = (!$avant ? "" : "$avant . ") .
1218
-			$t .
1219
-			(!$apres ? "" : " . $apres");
1220
-
1221
-		if ($res!==$t){
1222
-			$res = "($res)";
1223
-		}
1224
-
1225
-		$code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)");
1226
-	}
1227
-
1228
-	return $code;
1194
+    if ($avant === "''") {
1195
+        $avant = '';
1196
+    }
1197
+    if ($apres === "''") {
1198
+        $apres = '';
1199
+    }
1200
+    if ($avant or $apres or ($altern !== "''")){
1201
+        if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)){
1202
+            $t = $code;
1203
+            $cond = '';
1204
+        } elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1205
+            $t = $r[2];
1206
+            $cond = '!' . $r[1];
1207
+        } else {
1208
+            if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)){
1209
+                $t = $r[2];
1210
+                $cond = $r[1];
1211
+            } else {
1212
+                $t = '$t' . $n;
1213
+                $cond = "($t = $code)!==''";
1214
+            }
1215
+        }
1216
+
1217
+        $res = (!$avant ? "" : "$avant . ") .
1218
+            $t .
1219
+            (!$apres ? "" : " . $apres");
1220
+
1221
+        if ($res!==$t){
1222
+            $res = "($res)";
1223
+        }
1224
+
1225
+        $code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)");
1226
+    }
1227
+
1228
+    return $code;
1229 1229
 
1230 1230
 }
1231 1231
 
1232 1232
 
1233 1233
 function compile_inclure_doublons($lexemes) {
1234
-	foreach ($lexemes as $v) {
1235
-		if ($v->type === 'include' and $v->param) {
1236
-			foreach ($v->param as $r) {
1237
-				if (trim($r[0]) === 'doublons') {
1238
-					return true;
1239
-				}
1240
-			}
1241
-		}
1242
-	}
1243
-
1244
-	return false;
1234
+    foreach ($lexemes as $v) {
1235
+        if ($v->type === 'include' and $v->param) {
1236
+            foreach ($v->param as $r) {
1237
+                if (trim($r[0]) === 'doublons') {
1238
+                    return true;
1239
+                }
1240
+            }
1241
+        }
1242
+    }
1243
+
1244
+    return false;
1245 1245
 }
1246 1246
 
1247 1247
 // Prend en argument le texte d'un squelette, le nom de son fichier d'origine,
@@ -1261,348 +1261,348 @@  discard block
 block discarded – undo
1261 1261
 
1262 1262
 // https://code.spip.net/@public_compiler_dist
1263 1263
 function public_compiler_dist($squelette, $nom, $gram, $sourcefile, $connect = '') {
1264
-	// Pre-traitement : reperer le charset du squelette, et le convertir
1265
-	// Bonus : supprime le BOM
1266
-	include_spip('inc/charsets');
1267
-	$squelette = transcoder_page($squelette);
1268
-
1269
-	// rendre inertes les echappements de #[](){}<>
1270
-	$i = 0;
1271
-	while (false !== strpos($squelette, $inerte = '-INERTE' . $i)) {
1272
-		$i++;
1273
-	}
1274
-	$squelette = preg_replace_callback(',\\\\([#[()\]{}<>]),',
1275
-		function($a) use ($inerte) {
1276
-			return "$inerte-" . ord($a[1]) . '-';
1277
-		},
1278
-		$squelette,
1279
-		-1,
1280
-		$esc
1281
-	);
1282
-
1283
-	$descr = array(
1284
-		'nom' => $nom,
1285
-		'gram' => $gram,
1286
-		'sourcefile' => $sourcefile,
1287
-		'squelette' => $squelette
1288
-	);
1289
-
1290
-	// Phraser le squelette, selon sa grammaire
1291
-
1292
-	$boucles = array();
1293
-	$f = charger_fonction('phraser_' . $gram, 'public');
1294
-
1295
-	$squelette = $f($squelette, '', $boucles, $descr);
1296
-
1297
-	$boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect);
1298
-
1299
-	// restituer les echappements
1300
-	if ($esc) {
1301
-		foreach ($boucles as $i => $boucle) {
1302
-			$boucles[$i]->return = preg_replace_callback(
1303
-				",$inerte-(\d+)-,",
1304
-				function($a) {
1305
-					return chr($a[1]);
1306
-				},
1307
-				$boucle->return
1308
-			);
1309
-			$boucles[$i]->descr['squelette'] = preg_replace_callback(
1310
-				",$inerte-(\d+)-,",
1311
-				function($a) {
1312
-					return "\\\\" . chr($a[1]);
1313
-				},
1314
-				$boucle->descr['squelette']
1315
-			);
1316
-		}
1317
-	}
1318
-
1319
-	$debug = ($boucles and defined('_VAR_MODE') and _VAR_MODE == 'debug');
1320
-	if ($debug) {
1321
-		include_spip('public/decompiler');
1322
-		foreach ($boucles as $id => $boucle) {
1323
-			if ($id) {
1324
-				$decomp = "\n/* BOUCLE " .
1325
-					$boucle->type_requete .
1326
-					" " .
1327
-					str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1328
-					($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1329
-					" */\n";
1330
-			} else {
1331
-				$decomp = ("\n/*\n" .
1332
-					str_replace('*/', '* /', public_decompiler($squelette, $gram))
1333
-					. "\n*/");
1334
-			}
1335
-			$boucles[$id]->return = $decomp . $boucle->return;
1336
-			$GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1337
-		}
1338
-	}
1339
-
1340
-	return $boucles;
1264
+    // Pre-traitement : reperer le charset du squelette, et le convertir
1265
+    // Bonus : supprime le BOM
1266
+    include_spip('inc/charsets');
1267
+    $squelette = transcoder_page($squelette);
1268
+
1269
+    // rendre inertes les echappements de #[](){}<>
1270
+    $i = 0;
1271
+    while (false !== strpos($squelette, $inerte = '-INERTE' . $i)) {
1272
+        $i++;
1273
+    }
1274
+    $squelette = preg_replace_callback(',\\\\([#[()\]{}<>]),',
1275
+        function($a) use ($inerte) {
1276
+            return "$inerte-" . ord($a[1]) . '-';
1277
+        },
1278
+        $squelette,
1279
+        -1,
1280
+        $esc
1281
+    );
1282
+
1283
+    $descr = array(
1284
+        'nom' => $nom,
1285
+        'gram' => $gram,
1286
+        'sourcefile' => $sourcefile,
1287
+        'squelette' => $squelette
1288
+    );
1289
+
1290
+    // Phraser le squelette, selon sa grammaire
1291
+
1292
+    $boucles = array();
1293
+    $f = charger_fonction('phraser_' . $gram, 'public');
1294
+
1295
+    $squelette = $f($squelette, '', $boucles, $descr);
1296
+
1297
+    $boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect);
1298
+
1299
+    // restituer les echappements
1300
+    if ($esc) {
1301
+        foreach ($boucles as $i => $boucle) {
1302
+            $boucles[$i]->return = preg_replace_callback(
1303
+                ",$inerte-(\d+)-,",
1304
+                function($a) {
1305
+                    return chr($a[1]);
1306
+                },
1307
+                $boucle->return
1308
+            );
1309
+            $boucles[$i]->descr['squelette'] = preg_replace_callback(
1310
+                ",$inerte-(\d+)-,",
1311
+                function($a) {
1312
+                    return "\\\\" . chr($a[1]);
1313
+                },
1314
+                $boucle->descr['squelette']
1315
+            );
1316
+        }
1317
+    }
1318
+
1319
+    $debug = ($boucles and defined('_VAR_MODE') and _VAR_MODE == 'debug');
1320
+    if ($debug) {
1321
+        include_spip('public/decompiler');
1322
+        foreach ($boucles as $id => $boucle) {
1323
+            if ($id) {
1324
+                $decomp = "\n/* BOUCLE " .
1325
+                    $boucle->type_requete .
1326
+                    " " .
1327
+                    str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1328
+                    ($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1329
+                    " */\n";
1330
+            } else {
1331
+                $decomp = ("\n/*\n" .
1332
+                    str_replace('*/', '* /', public_decompiler($squelette, $gram))
1333
+                    . "\n*/");
1334
+            }
1335
+            $boucles[$id]->return = $decomp . $boucle->return;
1336
+            $GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1337
+        }
1338
+    }
1339
+
1340
+    return $boucles;
1341 1341
 }
1342 1342
 
1343 1343
 // Point d'entree pour arbre de syntaxe abstraite fourni en premier argument
1344 1344
 // Autres specifications comme ci-dessus
1345 1345
 
1346 1346
 function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect = '') {
1347
-	static $trouver_table;
1348
-	spip_timer('calcul_skel');
1349
-
1350
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
1351
-		$GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
1352
-		$GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;
1353
-
1354
-		if (!isset($GLOBALS['debug_objets']['principal'])) {
1355
-			$GLOBALS['debug_objets']['principal'] = $nom;
1356
-		}
1357
-	}
1358
-	foreach ($boucles as $id => $boucle) {
1359
-		$GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1360
-	}
1361
-	$descr['documents'] = compile_inclure_doublons($squelette);
1362
-
1363
-	// Demander la description des tables une fois pour toutes
1364
-	if (!$trouver_table) {
1365
-		$trouver_table = charger_fonction('trouver_table', 'base');
1366
-	}
1367
-
1368
-	// reperer si les doublons sont demandes
1369
-	// pour un inclure ou une boucle document
1370
-	// c'est utile a la fonction champs_traitements
1371
-	foreach ($boucles as $id => $boucle) {
1372
-		if (!($type = $boucle->type_requete)) {
1373
-			continue;
1374
-		}
1375
-		if (!$descr['documents'] and (
1376
-				(($type == 'documents') and $boucle->doublons) or
1377
-				compile_inclure_doublons($boucle->avant) or
1378
-				compile_inclure_doublons($boucle->apres) or
1379
-				compile_inclure_doublons($boucle->milieu) or
1380
-				compile_inclure_doublons($boucle->altern))
1381
-		) {
1382
-			$descr['documents'] = true;
1383
-		}
1384
-		if ($type != TYPE_RECURSIF) {
1385
-			if (!$boucles[$id]->sql_serveur and $connect) {
1386
-				$boucles[$id]->sql_serveur = $connect;
1387
-			}
1388
-
1389
-			// chercher dans les iterateurs du repertoire iterateur/
1390
-			if ($g = charger_fonction(
1391
-				preg_replace('/\W/', '_', $boucle->type_requete), 'iterateur', true)
1392
-			) {
1393
-				$boucles[$id] = $g($boucle);
1394
-
1395
-				// sinon, en cas de requeteur d'un type predefini,
1396
-				// utiliser les informations donnees par le requeteur
1397
-				// cas "php:xx" et "data:xx".
1398
-			} else {
1399
-				if ($boucle->sql_serveur and $requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true)) {
1400
-					$requeteur($boucles, $boucle, $id);
1401
-
1402
-					// utiliser la description des champs transmis
1403
-				} else {
1404
-					$show = $trouver_table($type, $boucles[$id]->sql_serveur);
1405
-					// si la table n'existe pas avec le connecteur par defaut,
1406
-					// c'est peut etre une table qui necessite son connecteur dedie fourni
1407
-					// permet une ecriture allegee (GEO) -> (geo:GEO)
1408
-					if (!$show
1409
-						and $show = $trouver_table($type, strtolower($type))
1410
-					) {
1411
-						$boucles[$id]->sql_serveur = strtolower($type);
1412
-					}
1413
-					if ($show) {
1414
-						$boucles[$id]->show = $show;
1415
-						// recopie les infos les plus importantes
1416
-						$boucles[$id]->primary = isset($show['key']["PRIMARY KEY"]) ? $show['key']["PRIMARY KEY"] : '';
1417
-						$boucles[$id]->id_table = $x = preg_replace(",^spip_,", "", $show['id_table']);
1418
-						$boucles[$id]->from[$x] = $nom_table = $show['table'];
1419
-						$boucles[$id]->iterateur = 'SQL';
1420
-
1421
-						if (empty($boucles[$id]->descr)) {
1422
-							$boucles[$id]->descr = &$descr;
1423
-						}
1424
-						if ((!$boucles[$id]->jointures)
1425
-							and is_array($show['tables_jointures'])
1426
-							and count($x = $show['tables_jointures'])
1427
-						) {
1428
-							$boucles[$id]->jointures = $x;
1429
-						}
1430
-						if ($boucles[$id]->jointures_explicites) {
1431
-							$jointures = preg_split("/\s+/", $boucles[$id]->jointures_explicites);
1432
-							while ($j = array_pop($jointures)) {
1433
-								array_unshift($boucles[$id]->jointures, $j);
1434
-							}
1435
-						}
1436
-					} else {
1437
-						// Pas une erreur si la table est optionnelle
1438
-						if ($boucles[$id]->table_optionnelle) {
1439
-							$boucles[$id]->type_requete = '';
1440
-						} else {
1441
-							$boucles[$id]->type_requete = false;
1442
-							$boucle = $boucles[$id];
1443
-							$x = (!$boucle->sql_serveur ? '' :
1444
-									($boucle->sql_serveur . ":")) .
1445
-								$type;
1446
-							$msg = array(
1447
-								'zbug_table_inconnue',
1448
-								array('table' => $x)
1449
-							);
1450
-							erreur_squelette($msg, $boucle);
1451
-						}
1452
-					}
1453
-				}
1454
-			}
1455
-		}
1456
-	}
1457
-
1458
-	// Commencer par reperer les boucles appelees explicitement 
1459
-	// car elles indexent les arguments de maniere derogatoire
1460
-	foreach ($boucles as $id => $boucle) {
1461
-		if ($boucle->type_requete == TYPE_RECURSIF and $boucle->param) {
1462
-			$boucles[$id]->descr = &$descr;
1463
-			$rec = &$boucles[$boucle->param[0]];
1464
-			if (!$rec) {
1465
-				$msg = array(
1466
-					'zbug_boucle_recursive_undef',
1467
-					array('nom' => $boucle->param[0])
1468
-				);
1469
-				erreur_squelette($msg, $boucle);
1470
-				$boucles[$id]->type_requete = false;
1471
-			} else {
1472
-				$rec->externe = $id;
1473
-				$descr['id_mere'] = $id;
1474
-				$boucles[$id]->return =
1475
-					calculer_liste(array($rec),
1476
-						$descr,
1477
-						$boucles,
1478
-						$boucle->param);
1479
-			}
1480
-		}
1481
-	}
1482
-	foreach ($boucles as $id => $boucle) {
1483
-		$id = strval($id); // attention au type dans index_pile
1484
-		$type = $boucle->type_requete;
1485
-		if ($type and $type != TYPE_RECURSIF) {
1486
-			$res = '';
1487
-			if ($boucle->param) {
1488
-				// retourne un tableau en cas d'erreur
1489
-				$res = calculer_criteres($id, $boucles);
1490
-			}
1491
-			$descr['id_mere'] = $id;
1492
-			$boucles[$id]->return =
1493
-				calculer_liste($boucle->milieu,
1494
-					$descr,
1495
-					$boucles,
1496
-					$id);
1497
-			// Si les criteres se sont mal compiles
1498
-			// ne pas tenter d'assembler le code final
1499
-			// (mais compiler le corps pour detection d'erreurs)
1500
-			if (is_array($res)) {
1501
-				$boucles[$id]->type_requete = false;
1502
-			}
1503
-		}
1504
-	}
1505
-
1506
-	// idem pour la racine
1507
-	$descr['id_mere'] = '';
1508
-	$corps = calculer_liste($squelette, $descr, $boucles);
1509
-
1510
-
1511
-	// Calcul du corps de toutes les fonctions PHP,
1512
-	// en particulier les requetes SQL et TOTAL_BOUCLE
1513
-	// de'terminables seulement maintenant
1514
-
1515
-	foreach ($boucles as $id => $boucle) {
1516
-		$boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
1517
-		if ($boucle->return === false) {
1518
-			$corps = false;
1519
-			continue;
1520
-		}
1521
-		// appeler la fonction de definition de la boucle
1522
-
1523
-		if ($req = $boucle->type_requete) {
1524
-			// boucle personnalisée ?
1525
-			$table = strtoupper($boucle->type_requete);
1526
-			$serveur = strtolower($boucle->sql_serveur);
1527
-			if (
1528
-				// fonction de boucle avec serveur & table
1529
-				(!$serveur or
1530
-					((!function_exists($f = "boucle_" . $serveur . "_" . $table))
1531
-						and (!function_exists($f = $f . "_dist"))
1532
-					)
1533
-				)
1534
-				// fonction de boucle avec table
1535
-				and (!function_exists($f = "boucle_" . $table))
1536
-				and (!function_exists($f = $f . "_dist"))
1537
-			) {
1538
-				// fonction de boucle standard 
1539
-				if (!function_exists($f = 'boucle_DEFAUT')) {
1540
-					$f = 'boucle_DEFAUT_dist';
1541
-				}
1542
-			}
1543
-
1544
-			$req = "\n\n\tstatic \$command = array();\n\t" .
1545
-				"static \$connect;\n\t" .
1546
-				"\$command['connect'] = \$connect = " .
1547
-				_q($boucle->sql_serveur) .
1548
-				";" .
1549
-				$f($id, $boucles);
1550
-		} else {
1551
-			$req = ("\n\treturn '';");
1552
-		}
1553
-
1554
-		$boucles[$id]->return =
1555
-			"\n\nfunction BOUCLE" . strtr($id, "-", "_") . $nom .
1556
-			'(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1557
-			$req .
1558
-			"\n}\n";
1559
-	}
1560
-
1561
-	// Au final, si le corps ou un critere au moins s'est mal compile
1562
-	// retourner False, sinon inserer leur decompilation
1563
-	if (is_bool($corps)) {
1564
-		return false;
1565
-	}
1566
-
1567
-	$principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1347
+    static $trouver_table;
1348
+    spip_timer('calcul_skel');
1349
+
1350
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
1351
+        $GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
1352
+        $GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;
1353
+
1354
+        if (!isset($GLOBALS['debug_objets']['principal'])) {
1355
+            $GLOBALS['debug_objets']['principal'] = $nom;
1356
+        }
1357
+    }
1358
+    foreach ($boucles as $id => $boucle) {
1359
+        $GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1360
+    }
1361
+    $descr['documents'] = compile_inclure_doublons($squelette);
1362
+
1363
+    // Demander la description des tables une fois pour toutes
1364
+    if (!$trouver_table) {
1365
+        $trouver_table = charger_fonction('trouver_table', 'base');
1366
+    }
1367
+
1368
+    // reperer si les doublons sont demandes
1369
+    // pour un inclure ou une boucle document
1370
+    // c'est utile a la fonction champs_traitements
1371
+    foreach ($boucles as $id => $boucle) {
1372
+        if (!($type = $boucle->type_requete)) {
1373
+            continue;
1374
+        }
1375
+        if (!$descr['documents'] and (
1376
+                (($type == 'documents') and $boucle->doublons) or
1377
+                compile_inclure_doublons($boucle->avant) or
1378
+                compile_inclure_doublons($boucle->apres) or
1379
+                compile_inclure_doublons($boucle->milieu) or
1380
+                compile_inclure_doublons($boucle->altern))
1381
+        ) {
1382
+            $descr['documents'] = true;
1383
+        }
1384
+        if ($type != TYPE_RECURSIF) {
1385
+            if (!$boucles[$id]->sql_serveur and $connect) {
1386
+                $boucles[$id]->sql_serveur = $connect;
1387
+            }
1388
+
1389
+            // chercher dans les iterateurs du repertoire iterateur/
1390
+            if ($g = charger_fonction(
1391
+                preg_replace('/\W/', '_', $boucle->type_requete), 'iterateur', true)
1392
+            ) {
1393
+                $boucles[$id] = $g($boucle);
1394
+
1395
+                // sinon, en cas de requeteur d'un type predefini,
1396
+                // utiliser les informations donnees par le requeteur
1397
+                // cas "php:xx" et "data:xx".
1398
+            } else {
1399
+                if ($boucle->sql_serveur and $requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true)) {
1400
+                    $requeteur($boucles, $boucle, $id);
1401
+
1402
+                    // utiliser la description des champs transmis
1403
+                } else {
1404
+                    $show = $trouver_table($type, $boucles[$id]->sql_serveur);
1405
+                    // si la table n'existe pas avec le connecteur par defaut,
1406
+                    // c'est peut etre une table qui necessite son connecteur dedie fourni
1407
+                    // permet une ecriture allegee (GEO) -> (geo:GEO)
1408
+                    if (!$show
1409
+                        and $show = $trouver_table($type, strtolower($type))
1410
+                    ) {
1411
+                        $boucles[$id]->sql_serveur = strtolower($type);
1412
+                    }
1413
+                    if ($show) {
1414
+                        $boucles[$id]->show = $show;
1415
+                        // recopie les infos les plus importantes
1416
+                        $boucles[$id]->primary = isset($show['key']["PRIMARY KEY"]) ? $show['key']["PRIMARY KEY"] : '';
1417
+                        $boucles[$id]->id_table = $x = preg_replace(",^spip_,", "", $show['id_table']);
1418
+                        $boucles[$id]->from[$x] = $nom_table = $show['table'];
1419
+                        $boucles[$id]->iterateur = 'SQL';
1420
+
1421
+                        if (empty($boucles[$id]->descr)) {
1422
+                            $boucles[$id]->descr = &$descr;
1423
+                        }
1424
+                        if ((!$boucles[$id]->jointures)
1425
+                            and is_array($show['tables_jointures'])
1426
+                            and count($x = $show['tables_jointures'])
1427
+                        ) {
1428
+                            $boucles[$id]->jointures = $x;
1429
+                        }
1430
+                        if ($boucles[$id]->jointures_explicites) {
1431
+                            $jointures = preg_split("/\s+/", $boucles[$id]->jointures_explicites);
1432
+                            while ($j = array_pop($jointures)) {
1433
+                                array_unshift($boucles[$id]->jointures, $j);
1434
+                            }
1435
+                        }
1436
+                    } else {
1437
+                        // Pas une erreur si la table est optionnelle
1438
+                        if ($boucles[$id]->table_optionnelle) {
1439
+                            $boucles[$id]->type_requete = '';
1440
+                        } else {
1441
+                            $boucles[$id]->type_requete = false;
1442
+                            $boucle = $boucles[$id];
1443
+                            $x = (!$boucle->sql_serveur ? '' :
1444
+                                    ($boucle->sql_serveur . ":")) .
1445
+                                $type;
1446
+                            $msg = array(
1447
+                                'zbug_table_inconnue',
1448
+                                array('table' => $x)
1449
+                            );
1450
+                            erreur_squelette($msg, $boucle);
1451
+                        }
1452
+                    }
1453
+                }
1454
+            }
1455
+        }
1456
+    }
1457
+
1458
+    // Commencer par reperer les boucles appelees explicitement 
1459
+    // car elles indexent les arguments de maniere derogatoire
1460
+    foreach ($boucles as $id => $boucle) {
1461
+        if ($boucle->type_requete == TYPE_RECURSIF and $boucle->param) {
1462
+            $boucles[$id]->descr = &$descr;
1463
+            $rec = &$boucles[$boucle->param[0]];
1464
+            if (!$rec) {
1465
+                $msg = array(
1466
+                    'zbug_boucle_recursive_undef',
1467
+                    array('nom' => $boucle->param[0])
1468
+                );
1469
+                erreur_squelette($msg, $boucle);
1470
+                $boucles[$id]->type_requete = false;
1471
+            } else {
1472
+                $rec->externe = $id;
1473
+                $descr['id_mere'] = $id;
1474
+                $boucles[$id]->return =
1475
+                    calculer_liste(array($rec),
1476
+                        $descr,
1477
+                        $boucles,
1478
+                        $boucle->param);
1479
+            }
1480
+        }
1481
+    }
1482
+    foreach ($boucles as $id => $boucle) {
1483
+        $id = strval($id); // attention au type dans index_pile
1484
+        $type = $boucle->type_requete;
1485
+        if ($type and $type != TYPE_RECURSIF) {
1486
+            $res = '';
1487
+            if ($boucle->param) {
1488
+                // retourne un tableau en cas d'erreur
1489
+                $res = calculer_criteres($id, $boucles);
1490
+            }
1491
+            $descr['id_mere'] = $id;
1492
+            $boucles[$id]->return =
1493
+                calculer_liste($boucle->milieu,
1494
+                    $descr,
1495
+                    $boucles,
1496
+                    $id);
1497
+            // Si les criteres se sont mal compiles
1498
+            // ne pas tenter d'assembler le code final
1499
+            // (mais compiler le corps pour detection d'erreurs)
1500
+            if (is_array($res)) {
1501
+                $boucles[$id]->type_requete = false;
1502
+            }
1503
+        }
1504
+    }
1505
+
1506
+    // idem pour la racine
1507
+    $descr['id_mere'] = '';
1508
+    $corps = calculer_liste($squelette, $descr, $boucles);
1509
+
1510
+
1511
+    // Calcul du corps de toutes les fonctions PHP,
1512
+    // en particulier les requetes SQL et TOTAL_BOUCLE
1513
+    // de'terminables seulement maintenant
1514
+
1515
+    foreach ($boucles as $id => $boucle) {
1516
+        $boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
1517
+        if ($boucle->return === false) {
1518
+            $corps = false;
1519
+            continue;
1520
+        }
1521
+        // appeler la fonction de definition de la boucle
1522
+
1523
+        if ($req = $boucle->type_requete) {
1524
+            // boucle personnalisée ?
1525
+            $table = strtoupper($boucle->type_requete);
1526
+            $serveur = strtolower($boucle->sql_serveur);
1527
+            if (
1528
+                // fonction de boucle avec serveur & table
1529
+                (!$serveur or
1530
+                    ((!function_exists($f = "boucle_" . $serveur . "_" . $table))
1531
+                        and (!function_exists($f = $f . "_dist"))
1532
+                    )
1533
+                )
1534
+                // fonction de boucle avec table
1535
+                and (!function_exists($f = "boucle_" . $table))
1536
+                and (!function_exists($f = $f . "_dist"))
1537
+            ) {
1538
+                // fonction de boucle standard 
1539
+                if (!function_exists($f = 'boucle_DEFAUT')) {
1540
+                    $f = 'boucle_DEFAUT_dist';
1541
+                }
1542
+            }
1543
+
1544
+            $req = "\n\n\tstatic \$command = array();\n\t" .
1545
+                "static \$connect;\n\t" .
1546
+                "\$command['connect'] = \$connect = " .
1547
+                _q($boucle->sql_serveur) .
1548
+                ";" .
1549
+                $f($id, $boucles);
1550
+        } else {
1551
+            $req = ("\n\treturn '';");
1552
+        }
1553
+
1554
+        $boucles[$id]->return =
1555
+            "\n\nfunction BOUCLE" . strtr($id, "-", "_") . $nom .
1556
+            '(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1557
+            $req .
1558
+            "\n}\n";
1559
+    }
1560
+
1561
+    // Au final, si le corps ou un critere au moins s'est mal compile
1562
+    // retourner False, sinon inserer leur decompilation
1563
+    if (is_bool($corps)) {
1564
+        return false;
1565
+    }
1566
+
1567
+    $principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1568 1568
 '
1569
-		// reporter de maniere securisee les doublons inclus
1570
-		. '
1569
+        // reporter de maniere securisee les doublons inclus
1570
+        . '
1571 1571
 	if (isset($Pile[0]["doublons"]) AND is_array($Pile[0]["doublons"]))
1572 1572
 		$doublons = nettoyer_env_doublons($Pile[0]["doublons"]);
1573 1573
 
1574 1574
 	$connect = ' .
1575
-		_q($connect) . ';
1575
+        _q($connect) . ';
1576 1576
 	$page = ' .
1577
-		// ATTENTION, le calcul de l'expression $corps affectera $Cache
1578
-		// c'est pourquoi on l'affecte a la variable auxiliaire $page.
1579
-		// avant de referencer $Cache
1580
-		$corps . ";
1577
+        // ATTENTION, le calcul de l'expression $corps affectera $Cache
1578
+        // c'est pourquoi on l'affecte a la variable auxiliaire $page.
1579
+        // avant de referencer $Cache
1580
+        $corps . ";
1581 1581
 
1582 1582
 	return analyse_resultat_skel(" . var_export($nom, true)
1583
-		. ", \$Cache, \$page, " . var_export($sourcefile, true) . ");
1583
+        . ", \$Cache, \$page, " . var_export($sourcefile, true) . ");
1584 1584
 }";
1585 1585
 
1586
-	$secondes = spip_timer('calcul_skel');
1587
-	spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
1588
-	// $connect n'est pas sûr : on nettoie
1589
-	$connect = preg_replace(',[^\w],', '', $connect);
1586
+    $secondes = spip_timer('calcul_skel');
1587
+    spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
1588
+    // $connect n'est pas sûr : on nettoie
1589
+    $connect = preg_replace(',[^\w],', '', $connect);
1590 1590
 
1591
-	// Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple
1592
-	$code = new Boucle;
1593
-	$code->descr = $descr;
1594
-	$code->return = '
1591
+    // Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple
1592
+    $code = new Boucle;
1593
+    $code->descr = $descr;
1594
+    $code->return = '
1595 1595
 //
1596 1596
 // Fonction principale du squelette ' .
1597
-		$sourcefile .
1598
-		($connect ? " pour $connect" : '') .
1599
-		(!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1600
-		"\n//\n" .
1601
-		$principal;
1597
+        $sourcefile .
1598
+        ($connect ? " pour $connect" : '') .
1599
+        (!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1600
+        "\n//\n" .
1601
+        $principal;
1602 1602
 
1603
-	$boucles[''] = $code;
1603
+    $boucles[''] = $code;
1604 1604
 
1605
-	return $boucles;
1605
+    return $boucles;
1606 1606
 }
1607 1607
 
1608 1608
 
@@ -1619,18 +1619,18 @@  discard block
 block discarded – undo
1619 1619
  *
1620 1620
  **/
1621 1621
 function requeteur_php_dist(&$boucles, &$boucle, &$id) {
1622
-	if (class_exists($boucle->type_requete)) {
1623
-		$g = charger_fonction('php', 'iterateur');
1624
-		$boucles[$id] = $g($boucle, $boucle->type_requete);
1625
-	} else {
1626
-		$x = $boucle->type_requete;
1627
-		$boucle->type_requete = false;
1628
-		$msg = array(
1629
-			'zbug_iterateur_inconnu',
1630
-			array('iterateur' => $x)
1631
-		);
1632
-		erreur_squelette($msg, $boucle);
1633
-	}
1622
+    if (class_exists($boucle->type_requete)) {
1623
+        $g = charger_fonction('php', 'iterateur');
1624
+        $boucles[$id] = $g($boucle, $boucle->type_requete);
1625
+    } else {
1626
+        $x = $boucle->type_requete;
1627
+        $boucle->type_requete = false;
1628
+        $msg = array(
1629
+            'zbug_iterateur_inconnu',
1630
+            array('iterateur' => $x)
1631
+        );
1632
+        erreur_squelette($msg, $boucle);
1633
+    }
1634 1634
 }
1635 1635
 
1636 1636
 
@@ -1648,23 +1648,23 @@  discard block
 block discarded – undo
1648 1648
  *
1649 1649
  **/
1650 1650
 function requeteur_data_dist(&$boucles, &$boucle, &$id) {
1651
-	include_spip('iterateur/data');
1652
-	if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1653
-		$g = charger_fonction('data', 'iterateur');
1654
-		$boucles[$id] = $g($boucle);
1655
-		// from[0] stocke le type de data (rss, yql, ...)
1656
-		$boucles[$id]->from[] = $boucle->type_requete;
1657
-
1658
-	} else {
1659
-		$x = $boucle->type_requete;
1660
-		$boucle->type_requete = false;
1661
-		$msg = array(
1662
-			'zbug_requeteur_inconnu',
1663
-			array(
1664
-				'requeteur' => 'data',
1665
-				'type' => $x
1666
-			)
1667
-		);
1668
-		erreur_squelette($msg, $boucle);
1669
-	}
1651
+    include_spip('iterateur/data');
1652
+    if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1653
+        $g = charger_fonction('data', 'iterateur');
1654
+        $boucles[$id] = $g($boucle);
1655
+        // from[0] stocke le type de data (rss, yql, ...)
1656
+        $boucles[$id]->from[] = $boucle->type_requete;
1657
+
1658
+    } else {
1659
+        $x = $boucle->type_requete;
1660
+        $boucle->type_requete = false;
1661
+        $msg = array(
1662
+            'zbug_requeteur_inconnu',
1663
+            array(
1664
+                'requeteur' => 'data',
1665
+                'type' => $x
1666
+            )
1667
+        );
1668
+        erreur_squelette($msg, $boucle);
1669
+    }
1670 1670
 }
Please login to merge, or discard this patch.
Spacing   +115 added lines, -123 removed lines patch added patch discarded remove patch
@@ -97,7 +97,7 @@  discard block
 block discarded – undo
97 97
 				preg_match(",^([^=]*)(=?)(.*)$,m", $var->texte, $m);
98 98
 				$m = array_pad($m, 3, null);
99 99
 				$var = $m[1];
100
-				$auto = false;;
100
+				$auto = false; ;
101 101
 				if ($m[2]) {
102 102
 					$v = $m[3];
103 103
 					if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) {
@@ -121,7 +121,7 @@  discard block
 block discarded – undo
121 121
 						: calculer_liste($val, $p->descr, $boucles, $id_boucle);
122 122
 					if ($var !== 1) {
123 123
 						$val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
124
-							. $val . ($echap ? ") . '" : " ");
124
+							. $val.($echap ? ") . '" : " ");
125 125
 					} else {
126 126
 						$val = $echap ? "'.$val.'" : $val;
127 127
 					}
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
 	if (!$lang) {
143 143
 		$lang = '$GLOBALS["spip_lang"]';
144 144
 	}
145
-	$l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : " ");
145
+	$l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ").$lang.($echap ? ") . '" : " ");
146 146
 
147 147
 	return $l;
148 148
 }
@@ -171,7 +171,7 @@  discard block
 block discarded – undo
171 171
 	$_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
172 172
 	if (is_string($p->texte)) {
173 173
 		$fichier = $p->texte;
174
-		$code = "\"".str_replace('"','\"',$fichier)."\"";
174
+		$code = "\"".str_replace('"', '\"', $fichier)."\"";
175 175
 
176 176
 	} else {
177 177
 		$code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
@@ -185,7 +185,7 @@  discard block
 block discarded – undo
185 185
 		$trace = $p->fonctions;
186 186
 		while (is_array($trace)
187 187
 		  and $trace = array_filter($trace)
188
-			and count($trace)==1) {
188
+			and count($trace) == 1) {
189 189
 			$trace = reset($trace);
190 190
 		}
191 191
 		$erreur_p_i_i = array(
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
 		return false;
220 220
 	} // j'aurais voulu toucher le fond ...
221 221
 
222
-	$contexte = 'array(' . $_contexte . ')';
222
+	$contexte = 'array('.$_contexte.')';
223 223
 
224 224
 	if ($env) {
225 225
 		$contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
@@ -234,11 +234,11 @@  discard block
 block discarded – undo
234 234
 			$_options[] = $ajax;
235 235
 		}
236 236
 		$code = " ' . argumenter_squelette($code) . '";
237
-		$code = "echo " . sprintf(CODE_RECUPERER_FOND, $code, $contexte, implode(',', $_options),
238
-				"_request(\"connect\")") . ';';
237
+		$code = "echo ".sprintf(CODE_RECUPERER_FOND, $code, $contexte, implode(',', $_options),
238
+				"_request(\"connect\")").';';
239 239
 	}
240 240
 
241
-	return "\n'<'.'" . "?php " . $code . "\n?'." . "'>'";
241
+	return "\n'<'.'"."?php ".$code."\n?'."."'>'";
242 242
 }
243 243
 
244 244
 
@@ -318,17 +318,17 @@  discard block
 block discarded – undo
318 318
 					$id = $id_table;
319 319
 					$statut = preg_replace(',\W,', '', $s['champ']); // securite
320 320
 				}
321
-				$mstatut = $id . '.' . $statut;
321
+				$mstatut = $id.'.'.$statut;
322 322
 
323 323
 				$arg_ignore_previsu = ($ignore_previsu ? ",true" : '');
324 324
 				include_spip('public/quete');
325 325
 				if (isset($s['post_date']) and $s['post_date']
326 326
 					and $GLOBALS['meta']["post_dates"] == 'non'
327 327
 				) {
328
-					$date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
328
+					$date = $id.'.'.preg_replace(',\W,', '', $s['post_date']); // securite
329 329
 					array_unshift($boucle->where,
330 330
 						$echapper ?
331
-							"\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
331
+							"\nquete_condition_postdates('$date',"._q($boucle->sql_serveur)."$arg_ignore_previsu)"
332 332
 							:
333 333
 							quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
334 334
 					);
@@ -336,9 +336,9 @@  discard block
 block discarded – undo
336 336
 				array_unshift($boucle->where,
337 337
 					$echapper ?
338 338
 						"\nquete_condition_statut('$mstatut',"
339
-						. _q($s['previsu']) . ","
340
-						. _q($s['publie']) . ","
341
-						. _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
339
+						. _q($s['previsu']).","
340
+						. _q($s['publie']).","
341
+						. _q($boucle->sql_serveur)."$arg_ignore_previsu)"
342 342
 						:
343 343
 						quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
344 344
 				);
@@ -372,14 +372,14 @@  discard block
 block discarded – undo
372 372
 	if (_request('var_mode_affiche') != 'resultat') {
373 373
 		$trace = '';
374 374
 	} else {
375
-		$_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
375
+		$_trace = $boucles[$id_boucle]->descr['nom'].$id_boucle;
376 376
 		$_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
377 377
 		$trace = "
378 378
 		if (empty($_trace)) { 
379 379
 			$_trace = []; 
380 380
 		}
381 381
 		if (count($_trace) < 3) { 
382
-			$_trace" . "[] = \$t0; 
382
+			$_trace"."[] = \$t0; 
383 383
 		}";
384 384
 	}
385 385
 
@@ -413,7 +413,7 @@  discard block
 block discarded – undo
413 413
 	return
414 414
 		// Numrows[$nom] peut ne pas être encore defini
415 415
 		"\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
416
-		. "\n\t\$t0 = " . $boucles[$id_boucle]->return . ";"
416
+		. "\n\t\$t0 = ".$boucles[$id_boucle]->return.";"
417 417
 		. "\n\t\$Numrows['$nom'] = (\$save_numrows);"
418 418
 		. $trace
419 419
 		. "\n\treturn \$t0;";
@@ -481,7 +481,7 @@  discard block
 block discarded – undo
481 481
 	// faudrait expanser le foreach a la compil, car y en a souvent qu'un 
482 482
 	// et puis faire un [] plutot qu'un "','."
483 483
 	if ($boucle->doublons) {
484
-		$corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
484
+		$corps .= "\n\t\t\tforeach(".$boucle->doublons.' as $k) $doublons[$k] .= "," . '.
485 485
 			index_pile($id_boucle, $primary, $boucles)
486 486
 			. "; // doublons\n";
487 487
 	}
@@ -508,13 +508,13 @@  discard block
 block discarded – undo
508 508
 		$corps .=
509 509
 			"\n\t\tlang_select_public("
510 510
 			. index_pile($id_boucle, 'lang', $boucles)
511
-			. ", '" . $boucle->lang_select . "'"
511
+			. ", '".$boucle->lang_select."'"
512 512
 			. (in_array($type_boucle, array(
513 513
 				'articles',
514 514
 				'rubriques',
515 515
 				'hierarchie',
516 516
 				'breves'
517
-			)) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
517
+			)) ? ', '.index_pile($id_boucle, 'titre', $boucles) : '')
518 518
 			. ');';
519 519
 	} else {
520 520
 		$init_lang = '';
@@ -535,26 +535,22 @@  discard block
 block discarded – undo
535 535
 
536 536
 	// gestion optimale des separateurs et des boucles constantes
537 537
 	if (count($boucle->separateur)) {
538
-		$code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
538
+		$code_sep = ("'".str_replace("'", "\'", join('', $boucle->separateur))."'");
539 539
 	}
540 540
 
541 541
 	$corps .=
542 542
 		((!$boucle->separateur) ?
543
-			(($constant && !$corps && !$flag_cpt) ? $return :
544
-				(($return === "''") ? '' :
545
-					("\n\t\t" . '$t0 .= ' . $return . ";"))) :
546
-			("\n\t\t\$t1 " .
543
+			(($constant && !$corps && !$flag_cpt) ? $return : (($return === "''") ? '' : ("\n\t\t".'$t0 .= '.$return.";"))) : ("\n\t\t\$t1 ".
547 544
 				((strpos($return, '$t1.') === 0) ?
548
-					(".=" . substr($return, 4)) :
549
-					('= ' . $return)) .
550
-				";\n\t\t" .
551
-				'$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
545
+					(".=".substr($return, 4)) : ('= '.$return)).
546
+				";\n\t\t".
547
+				'$t0 .= ((strlen($t1) && strlen($t0)) ? '.$code_sep." : '') . \$t1;"));
552 548
 
553 549
 	// Calculer les invalideurs si c'est une boucle non constante et si on
554 550
 	// souhaite invalider ces elements
555 551
 	if (!$constant and $primary) {
556 552
 		include_spip('inc/invalideur');
557
-		$corps = calcul_invalideurs($corps, $primary,$boucles, $id_boucle);
553
+		$corps = calcul_invalideurs($corps, $primary, $boucles, $id_boucle);
558 554
 	}
559 555
 
560 556
 	// gerer le compteur de boucle 
@@ -629,7 +625,7 @@  discard block
 block discarded – undo
629 625
 		$corps,
630 626
 		$fin_lang,
631 627
 		$trace,
632
-		'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
628
+		'BOUCLE'.$id_boucle.' @ '.($boucle->descr['sourcefile'])
633 629
 	);
634 630
 
635 631
 #	var_dump($a);exit;
@@ -650,20 +646,20 @@  discard block
 block discarded – undo
650 646
  **/
651 647
 function calculer_requete_sql($boucle) {
652 648
 	$init = array();
653
-	$init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
654
-	$init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
649
+	$init[] = calculer_dec('table', "'".$boucle->id_table."'");
650
+	$init[] = calculer_dec('id', "'".$boucle->id_boucle."'");
655 651
 	# En absence de champ c'est un decompte :
656 652
 	$init[] = calculer_dec('from', calculer_from($boucle));
657 653
 	$init[] = calculer_dec('type', calculer_from_type($boucle));
658 654
 	$init[] = calculer_dec('groupby',
659
-		'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ")");
660
-	$init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . "\")");
661
-	$init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ")");
655
+		'array('.(($g = join("\",\n\t\t\"", $boucle->group)) ? '"'.$g.'"' : '').")");
656
+	$init[] = calculer_dec('select', 'array("'.join("\",\n\t\t\"", $boucle->select)."\")");
657
+	$init[] = calculer_dec('orderby', 'array('.calculer_order($boucle).")");
662 658
 	$init[] = calculer_dec('where', calculer_dump_array($boucle->where));
663 659
 	$init[] = calculer_dec('join', calculer_dump_join($boucle->join));
664 660
 	$init[] = calculer_dec('limit',
665 661
 		(strpos($boucle->limit, 'intval') === false ?
666
-			"'" . $boucle->limit . "'"
662
+			"'".$boucle->limit."'"
667 663
 			:
668 664
 			$boucle->limit));
669 665
 	$init[] = calculer_dec('having', calculer_dump_array($boucle->having));
@@ -672,17 +668,17 @@  discard block
 block discarded – undo
672 668
 	// ou recalculée à chaque passage (vide)
673 669
 	foreach ($init as $i) {
674 670
 		if (reset($i)) {
675
-			$s .= "\n\t\t" . end($i);
671
+			$s .= "\n\t\t".end($i);
676 672
 		} # statique
677 673
 		else {
678
-			$d .= "\n\t" . end($i);
674
+			$d .= "\n\t".end($i);
679 675
 		} # dynamique
680 676
 	}
681 677
 
682 678
 	return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
683 679
 	. $boucle->in
684 680
 	. $boucle->hash
685
-	. "\n\t" . 'if (!isset($command[\'table\'])) {'
681
+	. "\n\t".'if (!isset($command[\'table\'])) {'
686 682
 	. $s
687 683
 	. "\n\t}"
688 684
 	. $d;
@@ -765,7 +761,7 @@  discard block
 block discarded – undo
765 761
  *    - index 1 : Code de l'affectation
766 762
  **/
767 763
 function calculer_dec($nom, $val) {
768
-	$static = 'if (!isset($command[\'' . $nom . '\'])) ';
764
+	$static = 'if (!isset($command[\''.$nom.'\'])) ';
769 765
 	// si une variable apparait dans le calcul de la clause
770 766
 	// il faut la re-evaluer a chaque passage
771 767
 	if (
@@ -782,7 +778,7 @@  discard block
 block discarded – undo
782 778
 		$static = "";
783 779
 	}
784 780
 
785
-	return array($static, '$command[\'' . $nom . '\'] = ' . $val . ';');
781
+	return array($static, '$command[\''.$nom.'\'] = '.$val.';');
786 782
 }
787 783
 
788 784
 /**
@@ -807,17 +803,17 @@  discard block
 block discarded – undo
807 803
 	}
808 804
 	$res = "";
809 805
 	if ($a and $a[0] == "'?'") {
810
-		return ("(" . calculer_dump_array($a[1]) .
811
-			" ? " . calculer_dump_array($a[2]) .
812
-			" : " . calculer_dump_array($a[3]) .
806
+		return ("(".calculer_dump_array($a[1]).
807
+			" ? ".calculer_dump_array($a[2]).
808
+			" : ".calculer_dump_array($a[3]).
813 809
 			")");
814 810
 	} else {
815 811
 		foreach ($a as $k => $v) {
816
-			$showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
817
-			$res .= ", " . $showk . calculer_dump_array($v);
812
+			$showk = (is_numeric($k) ? '' : sql_quote($k).' => ');
813
+			$res .= ", ".$showk.calculer_dump_array($v);
818 814
 		}
819 815
 
820
-		return "\n\t\t\tarray(" . substr($res, 2) . ')';
816
+		return "\n\t\t\tarray(".substr($res, 2).')';
821 817
 	}
822 818
 }
823 819
 
@@ -825,10 +821,10 @@  discard block
 block discarded – undo
825 821
 function calculer_dump_join($a) {
826 822
 	$res = "";
827 823
 	foreach ($a as $k => $v) {
828
-		$res .= ", '$k' => array(" . implode(',', $v) . ")";
824
+		$res .= ", '$k' => array(".implode(',', $v).")";
829 825
 	}
830 826
 
831
-	return 'array(' . substr($res, 2) . ')';
827
+	return 'array('.substr($res, 2).')';
832 828
 }
833 829
 
834 830
 /**
@@ -845,7 +841,7 @@  discard block
 block discarded – undo
845 841
 		$res .= ",'$k' => '$v'";
846 842
 	}
847 843
 
848
-	return 'array(' . substr($res, 1) . ')';
844
+	return 'array('.substr($res, 1).')';
849 845
 }
850 846
 
851 847
 /**
@@ -863,7 +859,7 @@  discard block
 block discarded – undo
863 859
 		$res .= ",'$k' => '$v'";
864 860
 	}
865 861
 
866
-	return 'array(' . substr($res, 1) . ')';
862
+	return 'array('.substr($res, 1).')';
867 863
 }
868 864
 
869 865
 // https://code.spip.net/@calculer_order
@@ -932,17 +928,17 @@  discard block
 block discarded – undo
932 928
 				) {
933 929
 					$res .= " .\n$tab$code";
934 930
 				} else {
935
-					$res = substr($res, 0, -1) . substr($code, 1);
931
+					$res = substr($res, 0, -1).substr($code, 1);
936 932
 				}
937 933
 			}
938 934
 
939
-			return '(' . substr($res, 2 + $descr['niv']) . ')';
935
+			return '('.substr($res, 2 + $descr['niv']).')';
940 936
 		}
941 937
 	} else {
942
-		$nom = $descr['nom'] . $id_boucle . ($descr['niv'] ? $descr['niv'] : '');
938
+		$nom = $descr['nom'].$id_boucle.($descr['niv'] ? $descr['niv'] : '');
943 939
 
944
-		return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(" ,\n$tab",
945
-			$codes) . ")))";
940
+		return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(".join(" ,\n$tab",
941
+			$codes).")))";
946 942
 	}
947 943
 }
948 944
 
@@ -971,7 +967,7 @@  discard block
 block discarded – undo
971 967
 			// texte seul
972 968
 			case 'texte':
973 969
 				$code = sandbox_composer_texte($p->texte, $p);
974
-				$commentaire = strlen($p->texte) . " signes";
970
+				$commentaire = strlen($p->texte)." signes";
975 971
 				$avant = '';
976 972
 				$apres = '';
977 973
 				$altern = "''";
@@ -980,14 +976,14 @@  discard block
 block discarded – undo
980 976
 			case 'polyglotte':
981 977
 				$code = "";
982 978
 				foreach ($p->traductions as $k => $v) {
983
-					$code .= ",'" .
984
-						str_replace(array("\\", "'"), array("\\\\", "\\'"), $k) .
985
-						"' => '" .
986
-						str_replace(array("\\", "'"), array("\\\\", "\\'"), $v) .
979
+					$code .= ",'".
980
+						str_replace(array("\\", "'"), array("\\\\", "\\'"), $k).
981
+						"' => '".
982
+						str_replace(array("\\", "'"), array("\\\\", "\\'"), $v).
987 983
 						"'";
988 984
 				}
989
-				$code = "choisir_traduction(array(" .
990
-					substr($code, 1) .
985
+				$code = "choisir_traduction(array(".
986
+					substr($code, 1).
991 987
 					"))";
992 988
 				$commentaire = '&';
993 989
 				$avant = '';
@@ -1003,7 +999,7 @@  discard block
 block discarded – undo
1003 999
 					$err_e_c = true;
1004 1000
 					$code = "''";
1005 1001
 				} else {
1006
-					$commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1002
+					$commentaire = '<INCLURE '.addslashes(str_replace("\n", ' ', $code)).'>';
1007 1003
 					$avant = '';
1008 1004
 					$apres = '';
1009 1005
 					$altern = "''";
@@ -1030,8 +1026,8 @@  discard block
 block discarded – undo
1030 1026
 					$err_e_c = true;
1031 1027
 					$code = "''";
1032 1028
 				} else {
1033
-					$code = 'BOUCLE' .
1034
-						str_replace("-", "_", $nom) . $descr['nom'] .
1029
+					$code = 'BOUCLE'.
1030
+						str_replace("-", "_", $nom).$descr['nom'].
1035 1031
 						'($Cache, $Pile, $doublons, $Numrows, $SP)';
1036 1032
 					$commentaire = "?$nom";
1037 1033
 					if (!$boucles[$nom]->milieu
@@ -1072,24 +1068,22 @@  discard block
 block discarded – undo
1072 1068
 				foreach ($p->arg as $k => $v) {
1073 1069
 					$_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1074 1070
 					if ($k) {
1075
-						$l[] = _q($k) . ' => ' . $_v;
1071
+						$l[] = _q($k).' => '.$_v;
1076 1072
 					} else {
1077 1073
 						$code = $_v;
1078 1074
 					}
1079 1075
 				}
1080 1076
 				// Si le module n'est pas fourni, l'expliciter sauf si calculé
1081 1077
 				if ($p->module) {
1082
-					$m = $p->module . ':' . $p->nom_champ;
1078
+					$m = $p->module.':'.$p->nom_champ;
1083 1079
 				} elseif ($p->nom_champ) {
1084
-					$m = MODULES_IDIOMES . ':' . $p->nom_champ;
1080
+					$m = MODULES_IDIOMES.':'.$p->nom_champ;
1085 1081
 				} else {
1086 1082
 					$m = '';
1087 1083
 				}
1088 1084
 
1089
-				$code = (!$code ? "'$m'" :
1090
-						($m ? "'$m' . $code" :
1091
-							("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1092
-					. (!$l ? '' : (", array(" . implode(",\n", $l) . ")"));
1085
+				$code = (!$code ? "'$m'" : ($m ? "'$m' . $code" : ("(strpos(\$x=$code, ':') ? \$x : ('".MODULES_IDIOMES.":' . \$x))")))
1086
+					. (!$l ? '' : (", array(".implode(",\n", $l).")"));
1093 1087
 				$code = "_T($code)";
1094 1088
 				if ($p->param) {
1095 1089
 					$p->id_boucle = $id_boucle;
@@ -1112,7 +1106,7 @@  discard block
 block discarded – undo
1112 1106
 				$p->type_requete = $type;
1113 1107
 
1114 1108
 				$code = calculer_champ($p);
1115
-				$commentaire = '#' . $p->nom_champ . $p->etoile;
1109
+				$commentaire = '#'.$p->nom_champ.$p->etoile;
1116 1110
 				$avant = calculer_liste($p->avant,
1117 1111
 					$descr, $boucles, $id_boucle);
1118 1112
 				$apres = calculer_liste($p->apres,
@@ -1143,10 +1137,9 @@  discard block
 block discarded – undo
1143 1137
 		if ($code != "''") {
1144 1138
 			$code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1145 1139
 			$codes[] = (($mode == 'validation') ?
1146
-				"array($code, '$commentaire', " . $p->ligne . ")"
1140
+				"array($code, '$commentaire', ".$p->ligne.")"
1147 1141
 				: (($mode == 'code') ?
1148
-					"\n// $commentaire\n$code" :
1149
-					$code));
1142
+					"\n// $commentaire\n$code" : $code));
1150 1143
 		}
1151 1144
 	} // foreach
1152 1145
 
@@ -1197,28 +1190,28 @@  discard block
 block discarded – undo
1197 1190
 	if ($apres === "''") {
1198 1191
 		$apres = '';
1199 1192
 	}
1200
-	if ($avant or $apres or ($altern !== "''")){
1201
-		if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)){
1193
+	if ($avant or $apres or ($altern !== "''")) {
1194
+		if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)) {
1202 1195
 			$t = $code;
1203 1196
 			$cond = '';
1204 1197
 		} elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1205 1198
 			$t = $r[2];
1206
-			$cond = '!' . $r[1];
1199
+			$cond = '!'.$r[1];
1207 1200
 		} else {
1208
-			if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)){
1201
+			if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) {
1209 1202
 				$t = $r[2];
1210 1203
 				$cond = $r[1];
1211 1204
 			} else {
1212
-				$t = '$t' . $n;
1205
+				$t = '$t'.$n;
1213 1206
 				$cond = "($t = $code)!==''";
1214 1207
 			}
1215 1208
 		}
1216 1209
 
1217
-		$res = (!$avant ? "" : "$avant . ") .
1218
-			$t .
1210
+		$res = (!$avant ? "" : "$avant . ").
1211
+			$t.
1219 1212
 			(!$apres ? "" : " . $apres");
1220 1213
 
1221
-		if ($res!==$t){
1214
+		if ($res !== $t) {
1222 1215
 			$res = "($res)";
1223 1216
 		}
1224 1217
 
@@ -1268,12 +1261,12 @@  discard block
 block discarded – undo
1268 1261
 
1269 1262
 	// rendre inertes les echappements de #[](){}<>
1270 1263
 	$i = 0;
1271
-	while (false !== strpos($squelette, $inerte = '-INERTE' . $i)) {
1264
+	while (false !== strpos($squelette, $inerte = '-INERTE'.$i)) {
1272 1265
 		$i++;
1273 1266
 	}
1274 1267
 	$squelette = preg_replace_callback(',\\\\([#[()\]{}<>]),',
1275 1268
 		function($a) use ($inerte) {
1276
-			return "$inerte-" . ord($a[1]) . '-';
1269
+			return "$inerte-".ord($a[1]).'-';
1277 1270
 		},
1278 1271
 		$squelette,
1279 1272
 		-1,
@@ -1290,7 +1283,7 @@  discard block
 block discarded – undo
1290 1283
 	// Phraser le squelette, selon sa grammaire
1291 1284
 
1292 1285
 	$boucles = array();
1293
-	$f = charger_fonction('phraser_' . $gram, 'public');
1286
+	$f = charger_fonction('phraser_'.$gram, 'public');
1294 1287
 
1295 1288
 	$squelette = $f($squelette, '', $boucles, $descr);
1296 1289
 
@@ -1309,7 +1302,7 @@  discard block
 block discarded – undo
1309 1302
 			$boucles[$i]->descr['squelette'] = preg_replace_callback(
1310 1303
 				",$inerte-(\d+)-,",
1311 1304
 				function($a) {
1312
-					return "\\\\" . chr($a[1]);
1305
+					return "\\\\".chr($a[1]);
1313 1306
 				},
1314 1307
 				$boucle->descr['squelette']
1315 1308
 			);
@@ -1321,19 +1314,19 @@  discard block
 block discarded – undo
1321 1314
 		include_spip('public/decompiler');
1322 1315
 		foreach ($boucles as $id => $boucle) {
1323 1316
 			if ($id) {
1324
-				$decomp = "\n/* BOUCLE " .
1325
-					$boucle->type_requete .
1326
-					" " .
1327
-					str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1328
-					($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1317
+				$decomp = "\n/* BOUCLE ".
1318
+					$boucle->type_requete.
1319
+					" ".
1320
+					str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')).
1321
+					($boucle->debug ? "\n *\n * ".implode("\n * ", $boucle->debug)."\n" : '').
1329 1322
 					" */\n";
1330 1323
 			} else {
1331
-				$decomp = ("\n/*\n" .
1324
+				$decomp = ("\n/*\n".
1332 1325
 					str_replace('*/', '* /', public_decompiler($squelette, $gram))
1333 1326
 					. "\n*/");
1334 1327
 			}
1335
-			$boucles[$id]->return = $decomp . $boucle->return;
1336
-			$GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1328
+			$boucles[$id]->return = $decomp.$boucle->return;
1329
+			$GLOBALS['debug_objets']['code'][$nom.$id] = $boucle->return;
1337 1330
 		}
1338 1331
 	}
1339 1332
 
@@ -1356,7 +1349,7 @@  discard block
 block discarded – undo
1356 1349
 		}
1357 1350
 	}
1358 1351
 	foreach ($boucles as $id => $boucle) {
1359
-		$GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1352
+		$GLOBALS['debug_objets']['boucle'][$nom.$id] = $boucle;
1360 1353
 	}
1361 1354
 	$descr['documents'] = compile_inclure_doublons($squelette);
1362 1355
 
@@ -1440,8 +1433,7 @@  discard block
 block discarded – undo
1440 1433
 						} else {
1441 1434
 							$boucles[$id]->type_requete = false;
1442 1435
 							$boucle = $boucles[$id];
1443
-							$x = (!$boucle->sql_serveur ? '' :
1444
-									($boucle->sql_serveur . ":")) .
1436
+							$x = (!$boucle->sql_serveur ? '' : ($boucle->sql_serveur.":")).
1445 1437
 								$type;
1446 1438
 							$msg = array(
1447 1439
 								'zbug_table_inconnue',
@@ -1527,13 +1519,13 @@  discard block
 block discarded – undo
1527 1519
 			if (
1528 1520
 				// fonction de boucle avec serveur & table
1529 1521
 				(!$serveur or
1530
-					((!function_exists($f = "boucle_" . $serveur . "_" . $table))
1531
-						and (!function_exists($f = $f . "_dist"))
1522
+					((!function_exists($f = "boucle_".$serveur."_".$table))
1523
+						and (!function_exists($f = $f."_dist"))
1532 1524
 					)
1533 1525
 				)
1534 1526
 				// fonction de boucle avec table
1535
-				and (!function_exists($f = "boucle_" . $table))
1536
-				and (!function_exists($f = $f . "_dist"))
1527
+				and (!function_exists($f = "boucle_".$table))
1528
+				and (!function_exists($f = $f."_dist"))
1537 1529
 			) {
1538 1530
 				// fonction de boucle standard 
1539 1531
 				if (!function_exists($f = 'boucle_DEFAUT')) {
@@ -1541,20 +1533,20 @@  discard block
 block discarded – undo
1541 1533
 				}
1542 1534
 			}
1543 1535
 
1544
-			$req = "\n\n\tstatic \$command = array();\n\t" .
1545
-				"static \$connect;\n\t" .
1546
-				"\$command['connect'] = \$connect = " .
1547
-				_q($boucle->sql_serveur) .
1548
-				";" .
1536
+			$req = "\n\n\tstatic \$command = array();\n\t".
1537
+				"static \$connect;\n\t".
1538
+				"\$command['connect'] = \$connect = ".
1539
+				_q($boucle->sql_serveur).
1540
+				";".
1549 1541
 				$f($id, $boucles);
1550 1542
 		} else {
1551 1543
 			$req = ("\n\treturn '';");
1552 1544
 		}
1553 1545
 
1554 1546
 		$boucles[$id]->return =
1555
-			"\n\nfunction BOUCLE" . strtr($id, "-", "_") . $nom .
1556
-			'(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1557
-			$req .
1547
+			"\n\nfunction BOUCLE".strtr($id, "-", "_").$nom.
1548
+			'(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {'.
1549
+			$req.
1558 1550
 			"\n}\n";
1559 1551
 	}
1560 1552
 
@@ -1564,7 +1556,7 @@  discard block
 block discarded – undo
1564 1556
 		return false;
1565 1557
 	}
1566 1558
 
1567
-	$principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1559
+	$principal = "\nfunction ".$nom.'($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1568 1560
 '
1569 1561
 		// reporter de maniere securisee les doublons inclus
1570 1562
 		. '
@@ -1572,15 +1564,15 @@  discard block
 block discarded – undo
1572 1564
 		$doublons = nettoyer_env_doublons($Pile[0]["doublons"]);
1573 1565
 
1574 1566
 	$connect = ' .
1575
-		_q($connect) . ';
1567
+		_q($connect).';
1576 1568
 	$page = ' .
1577 1569
 		// ATTENTION, le calcul de l'expression $corps affectera $Cache
1578 1570
 		// c'est pourquoi on l'affecte a la variable auxiliaire $page.
1579 1571
 		// avant de referencer $Cache
1580
-		$corps . ";
1572
+		$corps.";
1581 1573
 
1582 1574
 	return analyse_resultat_skel(" . var_export($nom, true)
1583
-		. ", \$Cache, \$page, " . var_export($sourcefile, true) . ");
1575
+		. ", \$Cache, \$page, ".var_export($sourcefile, true).");
1584 1576
 }";
1585 1577
 
1586 1578
 	$secondes = spip_timer('calcul_skel');
@@ -1594,10 +1586,10 @@  discard block
 block discarded – undo
1594 1586
 	$code->return = '
1595 1587
 //
1596 1588
 // Fonction principale du squelette ' .
1597
-		$sourcefile .
1598
-		($connect ? " pour $connect" : '') .
1599
-		(!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1600
-		"\n//\n" .
1589
+		$sourcefile.
1590
+		($connect ? " pour $connect" : '').
1591
+		(!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes").
1592
+		"\n//\n".
1601 1593
 		$principal;
1602 1594
 
1603 1595
 	$boucles[''] = $code;
@@ -1649,7 +1641,7 @@  discard block
 block discarded – undo
1649 1641
  **/
1650 1642
 function requeteur_data_dist(&$boucles, &$boucle, &$id) {
1651 1643
 	include_spip('iterateur/data');
1652
-	if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1644
+	if ($h = charger_fonction($boucle->type_requete.'_to_array', 'inc', true)) {
1653 1645
 		$g = charger_fonction('data', 'iterateur');
1654 1646
 		$boucles[$id] = $g($boucle);
1655 1647
 		// from[0] stocke le type de data (rss, yql, ...)
Please login to merge, or discard this patch.
ecrire/public/composer.php 1 patch
Indentation   +707 added lines, -707 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  **/
19 19
 
20 20
 if (!defined('_ECRIRE_INC_VERSION')) {
21
-	return;
21
+    return;
22 22
 }
23 23
 
24 24
 include_spip('inc/texte');
@@ -43,239 +43,239 @@  discard block
 block discarded – undo
43 43
 // https://code.spip.net/@public_composer_dist
44 44
 function public_composer_dist($squelette, $mime_type, $gram, $source, $connect = '') {
45 45
 
46
-	$nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect);
47
-
48
-	//  si deja en memoire (INCLURE  a repetition) c'est bon.
49
-	if (function_exists($nom)) {
50
-		return $nom;
51
-	}
52
-
53
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
54
-		$GLOBALS['debug_objets']['courant'] = $nom;
55
-	}
56
-
57
-	$phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php';
58
-
59
-	// si squelette est deja compile et perenne, le charger
60
-	if (!squelette_obsolete($phpfile, $source)) {
61
-		include_once $phpfile;
62
-		#if (!squelette_obsolete($phpfile, $source)
63
-		#  AND lire_fichier ($phpfile, $skel_code,
64
-		#  array('critique' => 'oui', 'phpcheck' => 'oui'))){
65
-		## eval('?'.'>'.$skel_code);
66
-		#	 spip_log($skel_code, 'comp')
67
-		#}
68
-	}
69
-
70
-	if (file_exists($lib = $squelette . '_fonctions' . '.php')) {
71
-		include_once $lib;
72
-	}
73
-
74
-	// tester si le eval ci-dessus a mis le squelette en memoire
75
-
76
-	if (function_exists($nom)) {
77
-		return $nom;
78
-	}
79
-
80
-	// charger le source, si possible, et compiler 
81
-	$skel_code = '';
82
-	if (lire_fichier($source, $skel)) {
83
-		$compiler = charger_fonction('compiler', 'public');
84
-		$skel_code = $compiler($skel, $nom, $gram, $source, $connect);
85
-	}
86
-
87
-	// Ne plus rien faire si le compilateur n'a pas pu operer.
88
-	if (!$skel_code) {
89
-		return false;
90
-	}
91
-
92
-	foreach ($skel_code as $id => $boucle) {
93
-		$f = $boucle->return;
94
-		try {
95
-			// @todo : a remplacer quand _PHP_MIN >= 7
96
-			// eval("return true; $f ;");
97
-			// PHP 5.x compat
98
-			if ($ok = @eval("return true; $f ;") === false) {
99
-				// Code syntaxiquement faux (critere etc mal programme')
100
-				$msg = _T('zbug_erreur_compilation');
101
-				erreur_squelette($msg, $boucle);
102
-				// continuer pour trouver d'autres fautes eventuelles
103
-				// mais prevenir que c'est mort
104
-				$nom = '';
105
-			}
106
-		} catch (\ParseError $e) {
107
-			// Code syntaxiquement faux (critere etc mal programme')
108
-			$msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage();
109
-			erreur_squelette($msg, $boucle);
110
-			// continuer pour trouver d'autres fautes eventuelles
111
-			// mais prevenir que c'est mort
112
-			$nom = '';
113
-		}
114
-
115
-		// Contexte de compil inutile a present
116
-		// (mais la derniere valeur de $boucle est utilisee ci-dessous)
117
-		$skel_code[$id] = $f;
118
-	}
119
-
120
-	$code = '';
121
-	if ($nom) {
122
-		// Si le code est bon, concatener et mettre en cache
123
-		if (function_exists($nom)) {
124
-			$code = squelette_traduit($skel, $source, $phpfile, $skel_code);
125
-		} else {
126
-			// code semantiquement faux: bug du compilateur
127
-			// $boucle est en fait ici la fct principale du squelette
128
-			$msg = _T('zbug_erreur_compilation');
129
-			erreur_squelette($msg, $boucle);
130
-			$nom = '';
131
-		}
132
-	}
133
-
134
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
135
-
136
-		// Tracer ce qui vient d'etre compile
137
-		$GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code;
138
-
139
-		// si c'est ce que demande le debusqueur, lui passer la main
140
-		if ($GLOBALS['debug_objets']['sourcefile']
141
-			and (_request('var_mode_objet') == $nom)
142
-			and (_request('var_mode_affiche') == 'code')
143
-		) {
144
-			erreur_squelette();
145
-		}
146
-	}
147
-
148
-	return $nom ? $nom : false;
46
+    $nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect);
47
+
48
+    //  si deja en memoire (INCLURE  a repetition) c'est bon.
49
+    if (function_exists($nom)) {
50
+        return $nom;
51
+    }
52
+
53
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
54
+        $GLOBALS['debug_objets']['courant'] = $nom;
55
+    }
56
+
57
+    $phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php';
58
+
59
+    // si squelette est deja compile et perenne, le charger
60
+    if (!squelette_obsolete($phpfile, $source)) {
61
+        include_once $phpfile;
62
+        #if (!squelette_obsolete($phpfile, $source)
63
+        #  AND lire_fichier ($phpfile, $skel_code,
64
+        #  array('critique' => 'oui', 'phpcheck' => 'oui'))){
65
+        ## eval('?'.'>'.$skel_code);
66
+        #	 spip_log($skel_code, 'comp')
67
+        #}
68
+    }
69
+
70
+    if (file_exists($lib = $squelette . '_fonctions' . '.php')) {
71
+        include_once $lib;
72
+    }
73
+
74
+    // tester si le eval ci-dessus a mis le squelette en memoire
75
+
76
+    if (function_exists($nom)) {
77
+        return $nom;
78
+    }
79
+
80
+    // charger le source, si possible, et compiler 
81
+    $skel_code = '';
82
+    if (lire_fichier($source, $skel)) {
83
+        $compiler = charger_fonction('compiler', 'public');
84
+        $skel_code = $compiler($skel, $nom, $gram, $source, $connect);
85
+    }
86
+
87
+    // Ne plus rien faire si le compilateur n'a pas pu operer.
88
+    if (!$skel_code) {
89
+        return false;
90
+    }
91
+
92
+    foreach ($skel_code as $id => $boucle) {
93
+        $f = $boucle->return;
94
+        try {
95
+            // @todo : a remplacer quand _PHP_MIN >= 7
96
+            // eval("return true; $f ;");
97
+            // PHP 5.x compat
98
+            if ($ok = @eval("return true; $f ;") === false) {
99
+                // Code syntaxiquement faux (critere etc mal programme')
100
+                $msg = _T('zbug_erreur_compilation');
101
+                erreur_squelette($msg, $boucle);
102
+                // continuer pour trouver d'autres fautes eventuelles
103
+                // mais prevenir que c'est mort
104
+                $nom = '';
105
+            }
106
+        } catch (\ParseError $e) {
107
+            // Code syntaxiquement faux (critere etc mal programme')
108
+            $msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage();
109
+            erreur_squelette($msg, $boucle);
110
+            // continuer pour trouver d'autres fautes eventuelles
111
+            // mais prevenir que c'est mort
112
+            $nom = '';
113
+        }
114
+
115
+        // Contexte de compil inutile a present
116
+        // (mais la derniere valeur de $boucle est utilisee ci-dessous)
117
+        $skel_code[$id] = $f;
118
+    }
119
+
120
+    $code = '';
121
+    if ($nom) {
122
+        // Si le code est bon, concatener et mettre en cache
123
+        if (function_exists($nom)) {
124
+            $code = squelette_traduit($skel, $source, $phpfile, $skel_code);
125
+        } else {
126
+            // code semantiquement faux: bug du compilateur
127
+            // $boucle est en fait ici la fct principale du squelette
128
+            $msg = _T('zbug_erreur_compilation');
129
+            erreur_squelette($msg, $boucle);
130
+            $nom = '';
131
+        }
132
+    }
133
+
134
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
135
+
136
+        // Tracer ce qui vient d'etre compile
137
+        $GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code;
138
+
139
+        // si c'est ce que demande le debusqueur, lui passer la main
140
+        if ($GLOBALS['debug_objets']['sourcefile']
141
+            and (_request('var_mode_objet') == $nom)
142
+            and (_request('var_mode_affiche') == 'code')
143
+        ) {
144
+            erreur_squelette();
145
+        }
146
+    }
147
+
148
+    return $nom ? $nom : false;
149 149
 }
150 150
 
151 151
 function squelette_traduit($squelette, $sourcefile, $phpfile, $boucles) {
152 152
 
153
-	// Le dernier index est '' (fonction principale)
154
-	$noms = substr(join(', ', array_keys($boucles)), 0, -2);
155
-	if (CODE_COMMENTE) {
156
-		$code = "
153
+    // Le dernier index est '' (fonction principale)
154
+    $noms = substr(join(', ', array_keys($boucles)), 0, -2);
155
+    if (CODE_COMMENTE) {
156
+        $code = "
157 157
 /*
158 158
  * Squelette : $sourcefile
159 159
  * Date :      " . gmdate("D, d M Y H:i:s", @filemtime($sourcefile)) . " GMT
160 160
  * Compile :   " . gmdate("D, d M Y H:i:s", time()) . " GMT
161 161
  * " . (!$boucles ? "Pas de boucle" : ("Boucles :   " . $noms)) . "
162 162
  */ ";
163
-	}
163
+    }
164 164
 
165
-	$code = '<' . "?php\n" . $code . join('', $boucles) . "\n?" . '>';
166
-	if (!defined('_VAR_NOCACHE') or !_VAR_NOCACHE) {
167
-		ecrire_fichier($phpfile, $code);
168
-	}
165
+    $code = '<' . "?php\n" . $code . join('', $boucles) . "\n?" . '>';
166
+    if (!defined('_VAR_NOCACHE') or !_VAR_NOCACHE) {
167
+        ecrire_fichier($phpfile, $code);
168
+    }
169 169
 
170
-	return $code;
170
+    return $code;
171 171
 }
172 172
 
173 173
 // Le squelette compile est-il trop vieux ?
174 174
 // https://code.spip.net/@squelette_obsolete
175 175
 function squelette_obsolete($skel, $squelette) {
176
-	static $date_change = null;
177
-	// ne verifier la date de mes_fonctions et mes_options qu'une seule fois
178
-	// par hit
179
-	if (is_null($date_change)) {
180
-		if (@file_exists($fonc = 'mes_fonctions.php')) {
181
-			$date_change = @filemtime($fonc);
182
-		} # compatibilite
183
-		if (defined('_FILE_OPTIONS')) {
184
-			$date_change = max($date_change, @filemtime(_FILE_OPTIONS));
185
-		}
186
-	}
187
-
188
-	return (
189
-		(defined('_VAR_MODE') and in_array(_VAR_MODE, array('recalcul', 'preview', 'debug')))
190
-		or !@file_exists($skel)
191
-		or ((@file_exists($squelette) ? @filemtime($squelette) : 0)
192
-			> ($date = @filemtime($skel)))
193
-		or ($date_change > $date)
194
-	);
176
+    static $date_change = null;
177
+    // ne verifier la date de mes_fonctions et mes_options qu'une seule fois
178
+    // par hit
179
+    if (is_null($date_change)) {
180
+        if (@file_exists($fonc = 'mes_fonctions.php')) {
181
+            $date_change = @filemtime($fonc);
182
+        } # compatibilite
183
+        if (defined('_FILE_OPTIONS')) {
184
+            $date_change = max($date_change, @filemtime(_FILE_OPTIONS));
185
+        }
186
+    }
187
+
188
+    return (
189
+        (defined('_VAR_MODE') and in_array(_VAR_MODE, array('recalcul', 'preview', 'debug')))
190
+        or !@file_exists($skel)
191
+        or ((@file_exists($squelette) ? @filemtime($squelette) : 0)
192
+            > ($date = @filemtime($skel)))
193
+        or ($date_change > $date)
194
+    );
195 195
 }
196 196
 
197 197
 // Activer l'invalideur de session
198 198
 // https://code.spip.net/@invalideur_session
199 199
 function invalideur_session(&$Cache, $code = null) {
200
-	$Cache['session'] = spip_session();
200
+    $Cache['session'] = spip_session();
201 201
 
202
-	return $code;
202
+    return $code;
203 203
 }
204 204
 
205 205
 
206 206
 // https://code.spip.net/@analyse_resultat_skel
207 207
 function analyse_resultat_skel($nom, $cache, $corps, $source = '') {
208
-	static $filtres = array();
209
-	$headers = array();
210
-
211
-	// Recupere les < ?php header('Xx: y'); ? > pour $page['headers']
212
-	// note: on essaie d'attrapper aussi certains de ces entetes codes
213
-	// "a la main" dans les squelettes, mais evidemment sans exhaustivite
214
-	if (stripos($corps, 'header') !== false
215
-		and preg_match_all(
216
-			'/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims',
217
-			$corps, $regs, PREG_SET_ORDER)
218
-	) {
219
-		foreach ($regs as $r) {
220
-			$corps = str_replace($r[0], '', $corps);
221
-			# $j = Content-Type, et pas content-TYPE.
222
-			$j = join('-', array_map('ucwords', explode('-', strtolower($r[2]))));
223
-
224
-			if ($j == 'X-Spip-Filtre' and isset($headers[$j])) {
225
-				$headers[$j] .= "|" . $r[3];
226
-			} else {
227
-				$headers[$j] = $r[3];
228
-			}
229
-		}
230
-	}
231
-	// S'agit-il d'un resultat constant ou contenant du code php
232
-	$process_ins = (
233
-		strpos($corps, '<' . '?') === false
234
-		or
235
-		(strpos($corps, '<' . '?xml') !== false and
236
-			strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
237
-	)
238
-		? 'html'
239
-		: 'php';
240
-
241
-	$skel = array(
242
-		'squelette' => $nom,
243
-		'source' => $source,
244
-		'process_ins' => $process_ins,
245
-		'invalideurs' => $cache,
246
-		'entetes' => $headers,
247
-		'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0
248
-	);
249
-
250
-	// traiter #FILTRE{} et filtres
251
-	if (!isset($filtres[$nom])) {
252
-		$filtres[$nom] = pipeline('declarer_filtres_squelettes', array('args' => $skel, 'data' => array()));
253
-	}
254
-	$filtres_headers = array();
255
-	if (isset($headers['X-Spip-Filtre']) and strlen($headers['X-Spip-Filtre'])) {
256
-		$filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre']));
257
-		unset($headers['X-Spip-Filtre']);
258
-	}
259
-	if (count($filtres[$nom]) or count($filtres_headers)) {
260
-		include_spip('public/sandbox');
261
-		$corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]);
262
-
263
-		if ($process_ins == 'html') {
264
-			$skel['process_ins'] = (
265
-				strpos($corps, '<' . '?') === false
266
-				or
267
-				(strpos($corps, '<' . '?xml') !== false and
268
-					strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
269
-			)
270
-				? 'html'
271
-				: 'php';
272
-		}
273
-	}
274
-
275
-	$skel['entetes'] = $headers;
276
-	$skel['texte'] = $corps;
277
-
278
-	return $skel;
208
+    static $filtres = array();
209
+    $headers = array();
210
+
211
+    // Recupere les < ?php header('Xx: y'); ? > pour $page['headers']
212
+    // note: on essaie d'attrapper aussi certains de ces entetes codes
213
+    // "a la main" dans les squelettes, mais evidemment sans exhaustivite
214
+    if (stripos($corps, 'header') !== false
215
+        and preg_match_all(
216
+            '/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims',
217
+            $corps, $regs, PREG_SET_ORDER)
218
+    ) {
219
+        foreach ($regs as $r) {
220
+            $corps = str_replace($r[0], '', $corps);
221
+            # $j = Content-Type, et pas content-TYPE.
222
+            $j = join('-', array_map('ucwords', explode('-', strtolower($r[2]))));
223
+
224
+            if ($j == 'X-Spip-Filtre' and isset($headers[$j])) {
225
+                $headers[$j] .= "|" . $r[3];
226
+            } else {
227
+                $headers[$j] = $r[3];
228
+            }
229
+        }
230
+    }
231
+    // S'agit-il d'un resultat constant ou contenant du code php
232
+    $process_ins = (
233
+        strpos($corps, '<' . '?') === false
234
+        or
235
+        (strpos($corps, '<' . '?xml') !== false and
236
+            strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
237
+    )
238
+        ? 'html'
239
+        : 'php';
240
+
241
+    $skel = array(
242
+        'squelette' => $nom,
243
+        'source' => $source,
244
+        'process_ins' => $process_ins,
245
+        'invalideurs' => $cache,
246
+        'entetes' => $headers,
247
+        'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0
248
+    );
249
+
250
+    // traiter #FILTRE{} et filtres
251
+    if (!isset($filtres[$nom])) {
252
+        $filtres[$nom] = pipeline('declarer_filtres_squelettes', array('args' => $skel, 'data' => array()));
253
+    }
254
+    $filtres_headers = array();
255
+    if (isset($headers['X-Spip-Filtre']) and strlen($headers['X-Spip-Filtre'])) {
256
+        $filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre']));
257
+        unset($headers['X-Spip-Filtre']);
258
+    }
259
+    if (count($filtres[$nom]) or count($filtres_headers)) {
260
+        include_spip('public/sandbox');
261
+        $corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]);
262
+
263
+        if ($process_ins == 'html') {
264
+            $skel['process_ins'] = (
265
+                strpos($corps, '<' . '?') === false
266
+                or
267
+                (strpos($corps, '<' . '?xml') !== false and
268
+                    strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
269
+            )
270
+                ? 'html'
271
+                : 'php';
272
+        }
273
+    }
274
+
275
+    $skel['entetes'] = $headers;
276
+    $skel['texte'] = $corps;
277
+
278
+    return $skel;
279 279
 }
280 280
 
281 281
 //
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
 inserer_balise_dynamique(balise_%s_dyn(%s), array(%s));
290 290
 if ($lang_select) lang_select();
291 291
 ?'
292
-	. '>');
292
+    . '>');
293 293
 
294 294
 /**
295 295
  * Synthétise une balise dynamique : crée l'appel à l'inclusion
@@ -309,29 +309,29 @@  discard block
 block discarded – undo
309 309
  *     Code PHP pour inclure le squelette de la balise dynamique
310 310
  **/
311 311
 function synthetiser_balise_dynamique($nom, $args, $file, $context_compil) {
312
-	if (strncmp($file, "/", 1) !== 0) {
313
-		$file = './" . _DIR_RACINE . "' . $file;
314
-	}
315
-
316
-	$lang = $context_compil[4];
317
-	if (preg_match(",\W,", $lang)) {
318
-		$lang = '';
319
-	}
320
-
321
-	$args = array_map('argumenter_squelette', $args);
322
-	if (!empty($context_compil['appel_php_depuis_modele'])) {
323
-		$args[0] = 'arguments_balise_dyn_depuis_modele('.$args[0].')';
324
-	}
325
-	$args = join(', ', $args);
326
-
327
-	$r = sprintf(CODE_INCLURE_BALISE,
328
-		$file,
329
-		$lang,
330
-		$nom,
331
-		$args,
332
-		join(', ', array_map('_q', $context_compil)));
333
-
334
-	return $r;
312
+    if (strncmp($file, "/", 1) !== 0) {
313
+        $file = './" . _DIR_RACINE . "' . $file;
314
+    }
315
+
316
+    $lang = $context_compil[4];
317
+    if (preg_match(",\W,", $lang)) {
318
+        $lang = '';
319
+    }
320
+
321
+    $args = array_map('argumenter_squelette', $args);
322
+    if (!empty($context_compil['appel_php_depuis_modele'])) {
323
+        $args[0] = 'arguments_balise_dyn_depuis_modele('.$args[0].')';
324
+    }
325
+    $args = join(', ', $args);
326
+
327
+    $r = sprintf(CODE_INCLURE_BALISE,
328
+        $file,
329
+        $lang,
330
+        $nom,
331
+        $args,
332
+        join(', ', array_map('_q', $context_compil)));
333
+
334
+    return $r;
335 335
 }
336 336
 
337 337
 /**
@@ -349,21 +349,21 @@  discard block
 block discarded – undo
349 349
  **/
350 350
 function argumenter_squelette($v) {
351 351
 
352
-	if (is_object($v)) {
353
-		if (PHP_VERSION_ID < 73000 and $v instanceof \stdClass) {
354
-			return "(object) " . var_export((array) $v, true);
355
-		}
356
-		return var_export($v, true);
357
-	} elseif (!is_array($v)) {
358
-		return "'" . texte_script($v) . "'";
359
-	} else {
360
-		$out = array();
361
-		foreach ($v as $k => $val) {
362
-			$out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val);
363
-		}
364
-
365
-		return 'array(' . join(", ", $out) . ')';
366
-	}
352
+    if (is_object($v)) {
353
+        if (PHP_VERSION_ID < 73000 and $v instanceof \stdClass) {
354
+            return "(object) " . var_export((array) $v, true);
355
+        }
356
+        return var_export($v, true);
357
+    } elseif (!is_array($v)) {
358
+        return "'" . texte_script($v) . "'";
359
+    } else {
360
+        $out = array();
361
+        foreach ($v as $k => $val) {
362
+            $out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val);
363
+        }
364
+
365
+        return 'array(' . join(", ", $out) . ')';
366
+    }
367 367
 }
368 368
 
369 369
 
@@ -394,82 +394,82 @@  discard block
 block discarded – undo
394 394
  *     Code PHP d'exécutant l'inclusion du squelette (ou texte) de la balise dynamique
395 395
  **/
396 396
 function executer_balise_dynamique($nom, $args, $context_compil) {
397
-	$nomfonction = $nom;
398
-	$nomfonction_generique = "";
399
-
400
-	$appel_php_depuis_modele = false;
401
-	if (is_array($context_compil)
402
-	  and !is_numeric($context_compil[3])
403
-	  and empty($context_compil[0])
404
-		and empty($context_compil[1])
405
-		and empty($context_compil[2])
406
-		and empty($context_compil[3])) {
407
-		$appel_php_depuis_modele = true;
408
-	}
409
-
410
-	// Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article')
411
-	if (false !== ($p = strpos($nom, "_"))) {
412
-		$nomfonction_generique = substr($nom, 0, $p + 1);
413
-	}
414
-
415
-	if (!$fonction_balise = charger_fonction($nomfonction, 'balise', true)) {
416
-		if ($nomfonction_generique and $fonction_balise = charger_fonction($nomfonction_generique, 'balise', true)) {
417
-			// et injecter en premier arg le nom de la balise 
418
-			array_unshift($args, $nom);
419
-			$nomfonction = $nomfonction_generique;
420
-		}
421
-	}
422
-
423
-	if (!$fonction_balise) {
424
-		$msg = array('zbug_balise_inexistante', array('from' => 'CVT', 'balise' => $nom));
425
-		erreur_squelette($msg, $context_compil);
426
-
427
-		return '';
428
-	}
429
-
430
-	// retrouver le fichier qui a déclaré la fonction
431
-	// même si la fonction dynamique est déclarée dans un fichier de fonctions.
432
-	// Attention sous windows, getFileName() retourne un antislash. 
433
-	$reflector = new ReflectionFunction($fonction_balise);
434
-	$file = str_replace('\\', '/', $reflector->getFileName());
435
-	if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) {
436
-		$file = substr($file, strlen(_ROOT_RACINE));
437
-	}
438
-
439
-	// Y a-t-il une fonction de traitement des arguments ?
440
-	$f = 'balise_' . $nomfonction . '_stat';
441
-
442
-	$r = !function_exists($f) ? $args : $f($args, $context_compil);
443
-
444
-	if (!is_array($r)) {
445
-		return $r;
446
-	}
447
-
448
-	// verifier que la fonction dyn est la, 
449
-	// sinon se replier sur la generique si elle existe
450
-	if (!function_exists('balise_' . $nomfonction . '_dyn')) {
451
-		if ($nomfonction_generique
452
-			and $file = include_spip("balise/" . strtolower($nomfonction_generique))
453
-			and function_exists('balise_' . $nomfonction_generique . '_dyn')
454
-		) {
455
-			// et lui injecter en premier arg le nom de la balise 
456
-			array_unshift($r, $nom);
457
-			$nomfonction = $nomfonction_generique;
458
-			if (!_DIR_RESTREINT) {
459
-				$file = _DIR_RESTREINT_ABS . $file;
460
-			}
461
-		} else {
462
-			$msg = array('zbug_balise_inexistante', array('from' => 'CVT', 'balise' => $nom));
463
-			erreur_squelette($msg, $context_compil);
464
-
465
-			return '';
466
-		}
467
-	}
468
-
469
-	if ($appel_php_depuis_modele) {
470
-		$context_compil['appel_php_depuis_modele'] = true;
471
-	}
472
-	return synthetiser_balise_dynamique($nomfonction, $r, $file, $context_compil);
397
+    $nomfonction = $nom;
398
+    $nomfonction_generique = "";
399
+
400
+    $appel_php_depuis_modele = false;
401
+    if (is_array($context_compil)
402
+      and !is_numeric($context_compil[3])
403
+      and empty($context_compil[0])
404
+        and empty($context_compil[1])
405
+        and empty($context_compil[2])
406
+        and empty($context_compil[3])) {
407
+        $appel_php_depuis_modele = true;
408
+    }
409
+
410
+    // Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article')
411
+    if (false !== ($p = strpos($nom, "_"))) {
412
+        $nomfonction_generique = substr($nom, 0, $p + 1);
413
+    }
414
+
415
+    if (!$fonction_balise = charger_fonction($nomfonction, 'balise', true)) {
416
+        if ($nomfonction_generique and $fonction_balise = charger_fonction($nomfonction_generique, 'balise', true)) {
417
+            // et injecter en premier arg le nom de la balise 
418
+            array_unshift($args, $nom);
419
+            $nomfonction = $nomfonction_generique;
420
+        }
421
+    }
422
+
423
+    if (!$fonction_balise) {
424
+        $msg = array('zbug_balise_inexistante', array('from' => 'CVT', 'balise' => $nom));
425
+        erreur_squelette($msg, $context_compil);
426
+
427
+        return '';
428
+    }
429
+
430
+    // retrouver le fichier qui a déclaré la fonction
431
+    // même si la fonction dynamique est déclarée dans un fichier de fonctions.
432
+    // Attention sous windows, getFileName() retourne un antislash. 
433
+    $reflector = new ReflectionFunction($fonction_balise);
434
+    $file = str_replace('\\', '/', $reflector->getFileName());
435
+    if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) {
436
+        $file = substr($file, strlen(_ROOT_RACINE));
437
+    }
438
+
439
+    // Y a-t-il une fonction de traitement des arguments ?
440
+    $f = 'balise_' . $nomfonction . '_stat';
441
+
442
+    $r = !function_exists($f) ? $args : $f($args, $context_compil);
443
+
444
+    if (!is_array($r)) {
445
+        return $r;
446
+    }
447
+
448
+    // verifier que la fonction dyn est la, 
449
+    // sinon se replier sur la generique si elle existe
450
+    if (!function_exists('balise_' . $nomfonction . '_dyn')) {
451
+        if ($nomfonction_generique
452
+            and $file = include_spip("balise/" . strtolower($nomfonction_generique))
453
+            and function_exists('balise_' . $nomfonction_generique . '_dyn')
454
+        ) {
455
+            // et lui injecter en premier arg le nom de la balise 
456
+            array_unshift($r, $nom);
457
+            $nomfonction = $nomfonction_generique;
458
+            if (!_DIR_RESTREINT) {
459
+                $file = _DIR_RESTREINT_ABS . $file;
460
+            }
461
+        } else {
462
+            $msg = array('zbug_balise_inexistante', array('from' => 'CVT', 'balise' => $nom));
463
+            erreur_squelette($msg, $context_compil);
464
+
465
+            return '';
466
+        }
467
+    }
468
+
469
+    if ($appel_php_depuis_modele) {
470
+        $context_compil['appel_php_depuis_modele'] = true;
471
+    }
472
+    return synthetiser_balise_dynamique($nomfonction, $r, $file, $context_compil);
473 473
 
474 474
 }
475 475
 
@@ -494,27 +494,27 @@  discard block
 block discarded – undo
494 494
  * @return null;
495 495
  **/
496 496
 function lang_select_public($lang, $lang_select, $titre = null) {
497
-	// Cas 1. forcer_lang = true et pas de critere {lang_select}
498
-	if (isset($GLOBALS['forcer_lang']) and $GLOBALS['forcer_lang']
499
-		and $lang_select !== 'oui'
500
-	) {
501
-		$lang = $GLOBALS['spip_lang'];
502
-	} // Cas 2. l'objet n'a pas de langue definie (ou definie a '')
503
-	elseif (!strlen($lang)) {
504
-		$lang = $GLOBALS['spip_lang'];
505
-	} // Cas 3. l'objet est multilingue !
506
-	elseif ($lang_select !== 'oui'
507
-		and strlen($titre) > 10
508
-		and strpos($titre, '<multi>') !== false
509
-		and strpos(echappe_html($titre), '<multi>') !== false
510
-	) {
511
-		$lang = $GLOBALS['spip_lang'];
512
-	}
513
-
514
-	// faire un lang_select() eventuellement sur la langue inchangee
515
-	lang_select($lang);
516
-
517
-	return;
497
+    // Cas 1. forcer_lang = true et pas de critere {lang_select}
498
+    if (isset($GLOBALS['forcer_lang']) and $GLOBALS['forcer_lang']
499
+        and $lang_select !== 'oui'
500
+    ) {
501
+        $lang = $GLOBALS['spip_lang'];
502
+    } // Cas 2. l'objet n'a pas de langue definie (ou definie a '')
503
+    elseif (!strlen($lang)) {
504
+        $lang = $GLOBALS['spip_lang'];
505
+    } // Cas 3. l'objet est multilingue !
506
+    elseif ($lang_select !== 'oui'
507
+        and strlen($titre) > 10
508
+        and strpos($titre, '<multi>') !== false
509
+        and strpos(echappe_html($titre), '<multi>') !== false
510
+    ) {
511
+        $lang = $GLOBALS['spip_lang'];
512
+    }
513
+
514
+    // faire un lang_select() eventuellement sur la langue inchangee
515
+    lang_select($lang);
516
+
517
+    return;
518 518
 }
519 519
 
520 520
 
@@ -522,21 +522,21 @@  discard block
 block discarded – undo
522 522
 // il faut le nettoyer car il pourrait etre injecte en SQL
523 523
 // https://code.spip.net/@nettoyer_env_doublons
524 524
 function nettoyer_env_doublons($envd) {
525
-	foreach ($envd as $table => $liste) {
526
-		$n = '';
527
-		foreach (explode(',', $liste) as $val) {
528
-			if ($a = intval($val) and $val === strval($a)) {
529
-				$n .= ',' . $val;
530
-			}
531
-		}
532
-		if (strlen($n)) {
533
-			$envd[$table] = $n;
534
-		} else {
535
-			unset($envd[$table]);
536
-		}
537
-	}
538
-
539
-	return $envd;
525
+    foreach ($envd as $table => $liste) {
526
+        $n = '';
527
+        foreach (explode(',', $liste) as $val) {
528
+            if ($a = intval($val) and $val === strval($a)) {
529
+                $n .= ',' . $val;
530
+            }
531
+        }
532
+        if (strlen($n)) {
533
+            $envd[$table] = $n;
534
+        } else {
535
+            unset($envd[$table]);
536
+        }
537
+    }
538
+
539
+    return $envd;
540 540
 }
541 541
 
542 542
 /**
@@ -555,21 +555,21 @@  discard block
 block discarded – undo
555 555
  *     Opérateur trouvé (SELF ou SUBSELECT) sinon false.
556 556
  **/
557 557
 function match_self($w) {
558
-	if (is_string($w)) {
559
-		return false;
560
-	}
561
-	if (is_array($w)) {
562
-		if (in_array(reset($w), array("SELF", "SUBSELECT"))) {
563
-			return $w;
564
-		}
565
-		foreach (array_filter($w, 'is_array') as $sw) {
566
-			if ($m = match_self($sw)) {
567
-				return $m;
568
-			}
569
-		}
570
-	}
571
-
572
-	return false;
558
+    if (is_string($w)) {
559
+        return false;
560
+    }
561
+    if (is_array($w)) {
562
+        if (in_array(reset($w), array("SELF", "SUBSELECT"))) {
563
+            return $w;
564
+        }
565
+        foreach (array_filter($w, 'is_array') as $sw) {
566
+            if ($m = match_self($sw)) {
567
+                return $m;
568
+            }
569
+        }
570
+    }
571
+
572
+    return false;
573 573
 }
574 574
 
575 575
 /**
@@ -585,16 +585,16 @@  discard block
 block discarded – undo
585 585
  *     est remplacée par son code.
586 586
  **/
587 587
 function remplace_sous_requete($w, $sousrequete) {
588
-	if (is_array($w)) {
589
-		if (in_array(reset($w), array("SELF", "SUBSELECT"))) {
590
-			return $sousrequete;
591
-		}
592
-		foreach ($w as $k => $sw) {
593
-			$w[$k] = remplace_sous_requete($sw, $sousrequete);
594
-		}
595
-	}
596
-
597
-	return $w;
588
+    if (is_array($w)) {
589
+        if (in_array(reset($w), array("SELF", "SUBSELECT"))) {
590
+            return $sousrequete;
591
+        }
592
+        foreach ($w as $k => $sw) {
593
+            $w[$k] = remplace_sous_requete($sw, $sousrequete);
594
+        }
595
+    }
596
+
597
+    return $w;
598 598
 }
599 599
 
600 600
 /**
@@ -608,17 +608,17 @@  discard block
 block discarded – undo
608 608
  *     - Conditions avec des sous requêtes
609 609
  **/
610 610
 function trouver_sous_requetes($where) {
611
-	$where_simples = array();
612
-	$where_sous = array();
613
-	foreach ($where as $k => $w) {
614
-		if (match_self($w)) {
615
-			$where_sous[$k] = $w;
616
-		} else {
617
-			$where_simples[$k] = $w;
618
-		}
619
-	}
620
-
621
-	return array($where_simples, $where_sous);
611
+    $where_simples = array();
612
+    $where_sous = array();
613
+    foreach ($where as $k => $w) {
614
+        if (match_self($w)) {
615
+            $where_sous[$k] = $w;
616
+        } else {
617
+            $where_simples[$k] = $w;
618
+        }
619
+    }
620
+
621
+    return array($where_simples, $where_sous);
622 622
 }
623 623
 
624 624
 
@@ -644,263 +644,263 @@  discard block
 block discarded – undo
644 644
  * @return resource
645 645
  */
646 646
 function calculer_select(
647
-	$select = array(),
648
-	$from = array(),
649
-	$from_type = array(),
650
-	$where = array(),
651
-	$join = array(),
652
-	$groupby = array(),
653
-	$orderby = array(),
654
-	$limit = '',
655
-	$having = array(),
656
-	$table = '',
657
-	$id = '',
658
-	$serveur = '',
659
-	$requeter = true
647
+    $select = array(),
648
+    $from = array(),
649
+    $from_type = array(),
650
+    $where = array(),
651
+    $join = array(),
652
+    $groupby = array(),
653
+    $orderby = array(),
654
+    $limit = '',
655
+    $having = array(),
656
+    $table = '',
657
+    $id = '',
658
+    $serveur = '',
659
+    $requeter = true
660 660
 ) {
661 661
 
662
-	// retirer les criteres vides:
663
-	// {X ?} avec X absent de l'URL
664
-	// {par #ENV{X}} avec X absent de l'URL
665
-	// IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil)
666
-	$menage = false;
667
-	foreach ($where as $k => $v) {
668
-		if (is_array($v)) {
669
-			if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) {
670
-				$op = false;
671
-			} elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) {
672
-				$op = false;
673
-			} else {
674
-				$op = $v[0] ? $v[0] : $v;
675
-			}
676
-		} else {
677
-			$op = $v;
678
-		}
679
-		if ((!$op) or ($op == 1) or ($op == '0=0')) {
680
-			unset($where[$k]);
681
-			$menage = true;
682
-		}
683
-	}
684
-
685
-	// evacuer les eventuels groupby vide issus d'un calcul dynamique
686
-	$groupby = array_diff($groupby, array(''));
687
-
688
-	// remplacer les sous requetes recursives au calcul
689
-	list($where_simples, $where_sous) = trouver_sous_requetes($where);
690
-	foreach ($where_sous as $k => $w) {
691
-		$menage = true;
692
-		// on recupere la sous requete 
693
-		$sous = match_self($w);
694
-		if ($sous[0] == 'SELF') {
695
-			// c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where)
696
-			array_push($where_simples, $sous[2]);
697
-			$wheresub = array(
698
-				$sous[2],
699
-				'0=0'
700
-			); // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where
701
-			$jsub = $join;
702
-			// trouver les jointures utiles a
703
-			// reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees
704
-			// ie L1.objet='article'
705
-			// on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction
706
-			$i = 0;
707
-			do {
708
-				$where[$k] = remplace_sous_requete($w, "(" . calculer_select(
709
-						array($sous[1] . " AS id"),
710
-						$from,
711
-						$from_type,
712
-						$wheresub,
713
-						$jsub,
714
-						array(), array(), '',
715
-						$having, $table, $id, $serveur, false) . ")");
716
-				if (!$i) {
717
-					$i = 1;
718
-					$wherestring = calculer_where_to_string($where[$k]);
719
-					foreach ($join as $cle => $wj) {
720
-						if (count($wj) == 4
721
-							and strpos($wherestring, "{$cle}.") !== false
722
-						) {
723
-							$i = 0;
724
-							$wheresub[] = $wj[3];
725
-							unset($jsub[$cle][3]);
726
-						}
727
-					}
728
-				}
729
-			} while ($i++ < 1);
730
-		}
731
-		if ($sous[0] == 'SUBSELECT') {
732
-			// c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having)
733
-			array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ?
734
-			$where[$k] = remplace_sous_requete($w, "(" . calculer_select(
735
-					$sous[1], # select
736
-					$sous[2], #from
737
-					array(), #from_type
738
-					$sous[3] ? (is_array($sous[3]) ? $sous[3] : array($sous[3])) : array(),
739
-					#where, qui peut etre de la forme string comme dans sql_select
740
-					array(), #join
741
-					$sous[4] ? $sous[4] : array(), #groupby
742
-					$sous[5] ? $sous[5] : array(), #orderby
743
-					$sous[6], #limit
744
-					$sous[7] ? $sous[7] : array(), #having
745
-					$table, $id, $serveur, false
746
-				) . ")");
747
-		}
748
-		array_pop($where_simples);
749
-	}
750
-
751
-	foreach ($having as $k => $v) {
752
-		if ((!$v) or ($v == 1) or ($v == '0=0')) {
753
-			unset($having[$k]);
754
-		}
755
-	}
756
-
757
-	// Installer les jointures.
758
-	// Retirer celles seulement utiles aux criteres finalement absents mais
759
-	// parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln
760
-	// si elle est seulement utile a Ln+1 elle meme inutile
761
-
762
-	$afrom = array();
763
-	$equiv = array();
764
-	$k = count($join);
765
-	foreach (array_reverse($join, true) as $cledef => $j) {
766
-		$cle = $cledef;
767
-		// le format de join est :
768
-		// array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]])
769
-		$join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber
770
-		if (count($join[$cle]) == 2) {
771
-			$join[$cle][] = $join[$cle][1];
772
-		}
773
-		if (count($join[$cle]) == 3) {
774
-			$join[$cle][] = '';
775
-		}
776
-		list($t, $c, $carr, $and) = $join[$cle];
777
-		// si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste
778
-		// pour compat avec ancienne convention
779
-		if (is_numeric($cle)) {
780
-			$cle = "L$k";
781
-		}
782
-		$cle_where_lie = "JOIN-$cle";
783
-		if (!$menage
784
-			or isset($afrom[$cle])
785
-			or calculer_jointnul($cle, $select)
786
-			or calculer_jointnul($cle, array_diff_key($join, array($cle => $join[$cle])))
787
-			or calculer_jointnul($cle, $having)
788
-			or calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => '']))
789
-		) {
790
-			// corriger les references non explicites dans select
791
-			// ou groupby
792
-			foreach ($select as $i => $s) {
793
-				if ($s == $c) {
794
-					$select[$i] = "$cle.$c AS $c";
795
-					break;
796
-				}
797
-			}
798
-			foreach ($groupby as $i => $g) {
799
-				if ($g == $c) {
800
-					$groupby[$i] = "$cle.$c";
801
-					break;
802
-				}
803
-			}
804
-			// on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin
805
-			// sans recours a preg_match
806
-			// un implode(' ',..) est fait dans reinjecte_joint un peu plus bas
807
-			$afrom[$t][$cle] = array(
808
-				"\n" .
809
-				(isset($from_type[$cle]) ? $from_type[$cle] : "INNER") . " JOIN",
810
-				$from[$cle],
811
-				"AS $cle",
812
-				"ON (",
813
-				"$cle.$c",
814
-				"=",
815
-				"$t.$carr",
816
-				($and ? "AND " . $and : "") .
817
-				")"
818
-			);
819
-			if (isset($afrom[$cle])) {
820
-				$afrom[$t] = $afrom[$t] + $afrom[$cle];
821
-				unset($afrom[$cle]);
822
-			}
823
-			$equiv[] = $carr;
824
-		} else {
825
-			unset($join[$cledef]);
826
-			if (isset($where_simples[$cle_where_lie])) {
827
-				unset($where_simples[$cle_where_lie]);
828
-				unset($where[$cle_where_lie]);
829
-			}
830
-		}
831
-		unset($from[$cle]);
832
-		$k--;
833
-	}
834
-
835
-	if (count($afrom)) {
836
-		// Regarder si la table principale ne sert finalement a rien comme dans
837
-		//<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3>
838
-		//<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2>
839
-		//<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5>
840
-		// ou dans
841
-		//<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8>
842
-		// qui comporte plusieurs jointures
843
-		// ou dans
844
-		// <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6>
845
-		// <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7>
846
-		// penser a regarder aussi la clause orderby pour ne pas simplifier abusivement
847
-		// <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9>
848
-		// penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement
849
-		// <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10>
850
-
851
-		$t = key($from);
852
-		$c = current($from);
853
-		reset($from);
854
-		$e = '/\b(' . "$t\\." . join("|" . $t . '\.', $equiv) . ')\b/';
855
-		if (!(strpos($t, ' ') or // jointure des le depart cf boucle_doc
856
-				calculer_jointnul($t, $select, $e) or
857
-				calculer_jointnul($t, $join, $e) or
858
-				calculer_jointnul($t, $where, $e) or
859
-				calculer_jointnul($t, $orderby, $e) or
860
-				calculer_jointnul($t, $groupby, $e) or
861
-				calculer_jointnul($t, $having, $e))
862
-			&& count($afrom[$t])
863
-		) {
864
-			$nfrom = reset($afrom[$t]);
865
-			$nt = key($afrom[$t]);
866
-			unset($from[$t]);
867
-			$from[$nt] = $nfrom[1];
868
-			unset($afrom[$t][$nt]);
869
-			$afrom[$nt] = $afrom[$t];
870
-			unset($afrom[$t]);
871
-			$e = '/\b' . preg_quote($nfrom[6]) . '\b/';
872
-			$t = $nfrom[4];
873
-			$alias = "";
874
-			// verifier que les deux cles sont homonymes, sinon installer un alias dans le select
875
-			$oldcle = explode('.', $nfrom[6]);
876
-			$oldcle = end($oldcle);
877
-			$newcle = explode('.', $nfrom[4]);
878
-			$newcle = end($newcle);
879
-			if ($newcle != $oldcle) {
880
-				// si l'ancienne cle etait deja dans le select avec un AS
881
-				// reprendre simplement ce AS
882
-				$as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/';
883
-				if (preg_match($as, implode(',', $select), $m)) {
884
-					$alias = "";
885
-				} else {
886
-					$alias = ", " . $nfrom[4] . " AS $oldcle";
887
-				}
888
-			}
889
-			$select = remplacer_jointnul($t . $alias, $select, $e);
890
-			$join = remplacer_jointnul($t, $join, $e);
891
-			$where = remplacer_jointnul($t, $where, $e);
892
-			$having = remplacer_jointnul($t, $having, $e);
893
-			$groupby = remplacer_jointnul($t, $groupby, $e);
894
-			$orderby = remplacer_jointnul($t, $orderby, $e);
895
-		}
896
-		$from = reinjecte_joint($afrom, $from);
897
-	}
898
-	$GLOBALS['debug']['aucasou'] = array($table, $id, $serveur, $requeter);
899
-	$r = sql_select($select, $from, $where,
900
-		$groupby, array_filter($orderby), $limit, $having, $serveur, $requeter);
901
-	unset($GLOBALS['debug']['aucasou']);
902
-
903
-	return $r;
662
+    // retirer les criteres vides:
663
+    // {X ?} avec X absent de l'URL
664
+    // {par #ENV{X}} avec X absent de l'URL
665
+    // IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil)
666
+    $menage = false;
667
+    foreach ($where as $k => $v) {
668
+        if (is_array($v)) {
669
+            if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) {
670
+                $op = false;
671
+            } elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) {
672
+                $op = false;
673
+            } else {
674
+                $op = $v[0] ? $v[0] : $v;
675
+            }
676
+        } else {
677
+            $op = $v;
678
+        }
679
+        if ((!$op) or ($op == 1) or ($op == '0=0')) {
680
+            unset($where[$k]);
681
+            $menage = true;
682
+        }
683
+    }
684
+
685
+    // evacuer les eventuels groupby vide issus d'un calcul dynamique
686
+    $groupby = array_diff($groupby, array(''));
687
+
688
+    // remplacer les sous requetes recursives au calcul
689
+    list($where_simples, $where_sous) = trouver_sous_requetes($where);
690
+    foreach ($where_sous as $k => $w) {
691
+        $menage = true;
692
+        // on recupere la sous requete 
693
+        $sous = match_self($w);
694
+        if ($sous[0] == 'SELF') {
695
+            // c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where)
696
+            array_push($where_simples, $sous[2]);
697
+            $wheresub = array(
698
+                $sous[2],
699
+                '0=0'
700
+            ); // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where
701
+            $jsub = $join;
702
+            // trouver les jointures utiles a
703
+            // reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees
704
+            // ie L1.objet='article'
705
+            // on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction
706
+            $i = 0;
707
+            do {
708
+                $where[$k] = remplace_sous_requete($w, "(" . calculer_select(
709
+                        array($sous[1] . " AS id"),
710
+                        $from,
711
+                        $from_type,
712
+                        $wheresub,
713
+                        $jsub,
714
+                        array(), array(), '',
715
+                        $having, $table, $id, $serveur, false) . ")");
716
+                if (!$i) {
717
+                    $i = 1;
718
+                    $wherestring = calculer_where_to_string($where[$k]);
719
+                    foreach ($join as $cle => $wj) {
720
+                        if (count($wj) == 4
721
+                            and strpos($wherestring, "{$cle}.") !== false
722
+                        ) {
723
+                            $i = 0;
724
+                            $wheresub[] = $wj[3];
725
+                            unset($jsub[$cle][3]);
726
+                        }
727
+                    }
728
+                }
729
+            } while ($i++ < 1);
730
+        }
731
+        if ($sous[0] == 'SUBSELECT') {
732
+            // c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having)
733
+            array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ?
734
+            $where[$k] = remplace_sous_requete($w, "(" . calculer_select(
735
+                    $sous[1], # select
736
+                    $sous[2], #from
737
+                    array(), #from_type
738
+                    $sous[3] ? (is_array($sous[3]) ? $sous[3] : array($sous[3])) : array(),
739
+                    #where, qui peut etre de la forme string comme dans sql_select
740
+                    array(), #join
741
+                    $sous[4] ? $sous[4] : array(), #groupby
742
+                    $sous[5] ? $sous[5] : array(), #orderby
743
+                    $sous[6], #limit
744
+                    $sous[7] ? $sous[7] : array(), #having
745
+                    $table, $id, $serveur, false
746
+                ) . ")");
747
+        }
748
+        array_pop($where_simples);
749
+    }
750
+
751
+    foreach ($having as $k => $v) {
752
+        if ((!$v) or ($v == 1) or ($v == '0=0')) {
753
+            unset($having[$k]);
754
+        }
755
+    }
756
+
757
+    // Installer les jointures.
758
+    // Retirer celles seulement utiles aux criteres finalement absents mais
759
+    // parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln
760
+    // si elle est seulement utile a Ln+1 elle meme inutile
761
+
762
+    $afrom = array();
763
+    $equiv = array();
764
+    $k = count($join);
765
+    foreach (array_reverse($join, true) as $cledef => $j) {
766
+        $cle = $cledef;
767
+        // le format de join est :
768
+        // array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]])
769
+        $join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber
770
+        if (count($join[$cle]) == 2) {
771
+            $join[$cle][] = $join[$cle][1];
772
+        }
773
+        if (count($join[$cle]) == 3) {
774
+            $join[$cle][] = '';
775
+        }
776
+        list($t, $c, $carr, $and) = $join[$cle];
777
+        // si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste
778
+        // pour compat avec ancienne convention
779
+        if (is_numeric($cle)) {
780
+            $cle = "L$k";
781
+        }
782
+        $cle_where_lie = "JOIN-$cle";
783
+        if (!$menage
784
+            or isset($afrom[$cle])
785
+            or calculer_jointnul($cle, $select)
786
+            or calculer_jointnul($cle, array_diff_key($join, array($cle => $join[$cle])))
787
+            or calculer_jointnul($cle, $having)
788
+            or calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => '']))
789
+        ) {
790
+            // corriger les references non explicites dans select
791
+            // ou groupby
792
+            foreach ($select as $i => $s) {
793
+                if ($s == $c) {
794
+                    $select[$i] = "$cle.$c AS $c";
795
+                    break;
796
+                }
797
+            }
798
+            foreach ($groupby as $i => $g) {
799
+                if ($g == $c) {
800
+                    $groupby[$i] = "$cle.$c";
801
+                    break;
802
+                }
803
+            }
804
+            // on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin
805
+            // sans recours a preg_match
806
+            // un implode(' ',..) est fait dans reinjecte_joint un peu plus bas
807
+            $afrom[$t][$cle] = array(
808
+                "\n" .
809
+                (isset($from_type[$cle]) ? $from_type[$cle] : "INNER") . " JOIN",
810
+                $from[$cle],
811
+                "AS $cle",
812
+                "ON (",
813
+                "$cle.$c",
814
+                "=",
815
+                "$t.$carr",
816
+                ($and ? "AND " . $and : "") .
817
+                ")"
818
+            );
819
+            if (isset($afrom[$cle])) {
820
+                $afrom[$t] = $afrom[$t] + $afrom[$cle];
821
+                unset($afrom[$cle]);
822
+            }
823
+            $equiv[] = $carr;
824
+        } else {
825
+            unset($join[$cledef]);
826
+            if (isset($where_simples[$cle_where_lie])) {
827
+                unset($where_simples[$cle_where_lie]);
828
+                unset($where[$cle_where_lie]);
829
+            }
830
+        }
831
+        unset($from[$cle]);
832
+        $k--;
833
+    }
834
+
835
+    if (count($afrom)) {
836
+        // Regarder si la table principale ne sert finalement a rien comme dans
837
+        //<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3>
838
+        //<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2>
839
+        //<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5>
840
+        // ou dans
841
+        //<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8>
842
+        // qui comporte plusieurs jointures
843
+        // ou dans
844
+        // <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6>
845
+        // <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7>
846
+        // penser a regarder aussi la clause orderby pour ne pas simplifier abusivement
847
+        // <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9>
848
+        // penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement
849
+        // <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10>
850
+
851
+        $t = key($from);
852
+        $c = current($from);
853
+        reset($from);
854
+        $e = '/\b(' . "$t\\." . join("|" . $t . '\.', $equiv) . ')\b/';
855
+        if (!(strpos($t, ' ') or // jointure des le depart cf boucle_doc
856
+                calculer_jointnul($t, $select, $e) or
857
+                calculer_jointnul($t, $join, $e) or
858
+                calculer_jointnul($t, $where, $e) or
859
+                calculer_jointnul($t, $orderby, $e) or
860
+                calculer_jointnul($t, $groupby, $e) or
861
+                calculer_jointnul($t, $having, $e))
862
+            && count($afrom[$t])
863
+        ) {
864
+            $nfrom = reset($afrom[$t]);
865
+            $nt = key($afrom[$t]);
866
+            unset($from[$t]);
867
+            $from[$nt] = $nfrom[1];
868
+            unset($afrom[$t][$nt]);
869
+            $afrom[$nt] = $afrom[$t];
870
+            unset($afrom[$t]);
871
+            $e = '/\b' . preg_quote($nfrom[6]) . '\b/';
872
+            $t = $nfrom[4];
873
+            $alias = "";
874
+            // verifier que les deux cles sont homonymes, sinon installer un alias dans le select
875
+            $oldcle = explode('.', $nfrom[6]);
876
+            $oldcle = end($oldcle);
877
+            $newcle = explode('.', $nfrom[4]);
878
+            $newcle = end($newcle);
879
+            if ($newcle != $oldcle) {
880
+                // si l'ancienne cle etait deja dans le select avec un AS
881
+                // reprendre simplement ce AS
882
+                $as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/';
883
+                if (preg_match($as, implode(',', $select), $m)) {
884
+                    $alias = "";
885
+                } else {
886
+                    $alias = ", " . $nfrom[4] . " AS $oldcle";
887
+                }
888
+            }
889
+            $select = remplacer_jointnul($t . $alias, $select, $e);
890
+            $join = remplacer_jointnul($t, $join, $e);
891
+            $where = remplacer_jointnul($t, $where, $e);
892
+            $having = remplacer_jointnul($t, $having, $e);
893
+            $groupby = remplacer_jointnul($t, $groupby, $e);
894
+            $orderby = remplacer_jointnul($t, $orderby, $e);
895
+        }
896
+        $from = reinjecte_joint($afrom, $from);
897
+    }
898
+    $GLOBALS['debug']['aucasou'] = array($table, $id, $serveur, $requeter);
899
+    $r = sql_select($select, $from, $where,
900
+        $groupby, array_filter($orderby), $limit, $having, $serveur, $requeter);
901
+    unset($GLOBALS['debug']['aucasou']);
902
+
903
+    return $r;
904 904
 }
905 905
 
906 906
 /**
@@ -911,20 +911,20 @@  discard block
 block discarded – undo
911 911
  * @return string
912 912
  */
913 913
 function calculer_where_to_string($v, $join = 'AND') {
914
-	if (empty($v)) {
915
-		return '';
916
-	}
917
-
918
-	if (!is_array($v)) {
919
-		return $v;
920
-	} else {
921
-		$exp = "";
922
-		if (strtoupper($join) === 'AND') {
923
-			return $exp . join(" $join ", array_map('calculer_where_to_string', $v));
924
-		} else {
925
-			return $exp . join($join, $v);
926
-		}
927
-	}
914
+    if (empty($v)) {
915
+        return '';
916
+    }
917
+
918
+    if (!is_array($v)) {
919
+        return $v;
920
+    } else {
921
+        $exp = "";
922
+        if (strtoupper($join) === 'AND') {
923
+            return $exp . join(" $join ", array_map('calculer_where_to_string', $v));
924
+        } else {
925
+            return $exp . join($join, $v);
926
+        }
927
+    }
928 928
 }
929 929
 
930 930
 
@@ -932,62 +932,62 @@  discard block
 block discarded – undo
932 932
 
933 933
 // https://code.spip.net/@calculer_jointnul
934 934
 function calculer_jointnul($cle, $exp, $equiv = '') {
935
-	if (!is_array($exp)) {
936
-		if ($equiv) {
937
-			$exp = preg_replace($equiv, '', $exp);
938
-		}
939
-
940
-		return preg_match("/\\b$cle\\./", $exp);
941
-	} else {
942
-		foreach ($exp as $v) {
943
-			if (calculer_jointnul($cle, $v, $equiv)) {
944
-				return true;
945
-			}
946
-		}
947
-
948
-		return false;
949
-	}
935
+    if (!is_array($exp)) {
936
+        if ($equiv) {
937
+            $exp = preg_replace($equiv, '', $exp);
938
+        }
939
+
940
+        return preg_match("/\\b$cle\\./", $exp);
941
+    } else {
942
+        foreach ($exp as $v) {
943
+            if (calculer_jointnul($cle, $v, $equiv)) {
944
+                return true;
945
+            }
946
+        }
947
+
948
+        return false;
949
+    }
950 950
 }
951 951
 
952 952
 // https://code.spip.net/@reinjecte_joint
953 953
 function reinjecte_joint($afrom, $from) {
954
-	$from_synth = array();
955
-	foreach ($from as $k => $v) {
956
-		$from_synth[$k] = $from[$k];
957
-		if (isset($afrom[$k])) {
958
-			foreach ($afrom[$k] as $kk => $vv) {
959
-				$afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]);
960
-			}
961
-			$from_synth["$k@"] = implode(' ', $afrom[$k]);
962
-			unset($afrom[$k]);
963
-		}
964
-	}
965
-
966
-	return $from_synth;
954
+    $from_synth = array();
955
+    foreach ($from as $k => $v) {
956
+        $from_synth[$k] = $from[$k];
957
+        if (isset($afrom[$k])) {
958
+            foreach ($afrom[$k] as $kk => $vv) {
959
+                $afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]);
960
+            }
961
+            $from_synth["$k@"] = implode(' ', $afrom[$k]);
962
+            unset($afrom[$k]);
963
+        }
964
+    }
965
+
966
+    return $from_synth;
967 967
 }
968 968
 
969 969
 // https://code.spip.net/@remplacer_jointnul
970 970
 function remplacer_jointnul($cle, $exp, $equiv = '') {
971
-	if (!is_array($exp)) {
972
-		return preg_replace($equiv, $cle, $exp);
973
-	} else {
974
-		foreach ($exp as $k => $v) {
975
-			$exp[$k] = remplacer_jointnul($cle, $v, $equiv);
976
-		}
977
-
978
-		return $exp;
979
-	}
971
+    if (!is_array($exp)) {
972
+        return preg_replace($equiv, $cle, $exp);
973
+    } else {
974
+        foreach ($exp as $k => $v) {
975
+            $exp[$k] = remplacer_jointnul($cle, $v, $equiv);
976
+        }
977
+
978
+        return $exp;
979
+    }
980 980
 }
981 981
 
982 982
 // calcul du nom du squelette
983 983
 // https://code.spip.net/@calculer_nom_fonction_squel
984 984
 function calculer_nom_fonction_squel($skel, $mime_type = 'html', $connect = '') {
985
-	// ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine
986
-	if ($l = strlen(_DIR_RACINE) and strncmp($skel, _DIR_RACINE, $l) == 0) {
987
-		$skel = substr($skel, strlen(_DIR_RACINE));
988
-	}
989
-
990
-	return $mime_type
991
-	. (!$connect ? '' : preg_replace('/\W/', "_", $connect)) . '_'
992
-	. md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : ''));
985
+    // ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine
986
+    if ($l = strlen(_DIR_RACINE) and strncmp($skel, _DIR_RACINE, $l) == 0) {
987
+        $skel = substr($skel, strlen(_DIR_RACINE));
988
+    }
989
+
990
+    return $mime_type
991
+    . (!$connect ? '' : preg_replace('/\W/', "_", $connect)) . '_'
992
+    . md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : ''));
993 993
 }
Please login to merge, or discard this patch.
ecrire/public/jointures.php 2 patches
Indentation   +379 added lines, -379 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
 
@@ -33,11 +33,11 @@  discard block
 block discarded – undo
33 33
  *     Chaine sinon : le nom du champ (non décomposable donc)
34 34
  */
35 35
 function decompose_champ_id_objet($champ) {
36
-	if (($champ !== 'id_objet') and preg_match(',^id_([a-z_]+)$,', $champ, $regs)) {
37
-		return array('id_objet', 'objet', objet_type($regs[1]));
38
-	}
36
+    if (($champ !== 'id_objet') and preg_match(',^id_([a-z_]+)$,', $champ, $regs)) {
37
+        return array('id_objet', 'objet', objet_type($regs[1]));
38
+    }
39 39
 
40
-	return $champ;
40
+    return $champ;
41 41
 }
42 42
 
43 43
 /**
@@ -56,20 +56,20 @@  discard block
 block discarded – undo
56 56
  *     - array(id_objet, objet), si le champ n'existe pas mais qu'on peut décomposer
57 57
  */
58 58
 function trouver_champs_decomposes($champ, $desc) {
59
-	if (!is_array($desc) // on ne se risque pas en conjectures si on ne connait pas la table
60
-		or array_key_exists($champ, $desc['field'])
61
-	) {
62
-		return array($champ);
63
-	}
64
-	// si le champ se décompose, tester que les colonnes décomposées sont présentes
65
-	if (is_array($decompose = decompose_champ_id_objet($champ))) {
66
-		array_pop($decompose);
67
-		if (count(array_intersect($decompose, array_keys($desc['field']))) == count($decompose)) {
68
-			return $decompose;
69
-		}
70
-	}
71
-
72
-	return array($champ);
59
+    if (!is_array($desc) // on ne se risque pas en conjectures si on ne connait pas la table
60
+        or array_key_exists($champ, $desc['field'])
61
+    ) {
62
+        return array($champ);
63
+    }
64
+    // si le champ se décompose, tester que les colonnes décomposées sont présentes
65
+    if (is_array($decompose = decompose_champ_id_objet($champ))) {
66
+        array_pop($decompose);
67
+        if (count(array_intersect($decompose, array_keys($desc['field']))) == count($decompose)) {
68
+            return $decompose;
69
+        }
70
+    }
71
+
72
+    return array($champ);
73 73
 }
74 74
 
75 75
 
@@ -99,23 +99,23 @@  discard block
 block discarded – undo
99 99
  *     Alias de la table de jointure (Lx)
100 100
  */
101 101
 function calculer_jointure(&$boucle, $depart, $arrivee, $col = '', $cond = false, $max_liens = 5) {
102
-	// les jointures minimales sont optimales :
103
-	// on contraint le nombre d'etapes en l'augmentant
104
-	// jusqu'a ce qu'on trouve une jointure ou qu'on atteigne la limite maxi 
105
-	$max = 1;
106
-	$res = false;
107
-	$milieu_exclus = ($col ? $col : array());
108
-	while ($max <= $max_liens and !$res) {
109
-		$res = calculer_chaine_jointures($boucle, $depart, $arrivee, array(), $milieu_exclus, $max);
110
-		$max++;
111
-	}
112
-	if (!$res) {
113
-		return "";
114
-	}
115
-
116
-	list($nom, $desc) = $depart;
117
-
118
-	return fabrique_jointures($boucle, $res, $cond, $desc, $nom, $col);
102
+    // les jointures minimales sont optimales :
103
+    // on contraint le nombre d'etapes en l'augmentant
104
+    // jusqu'a ce qu'on trouve une jointure ou qu'on atteigne la limite maxi 
105
+    $max = 1;
106
+    $res = false;
107
+    $milieu_exclus = ($col ? $col : array());
108
+    while ($max <= $max_liens and !$res) {
109
+        $res = calculer_chaine_jointures($boucle, $depart, $arrivee, array(), $milieu_exclus, $max);
110
+        $max++;
111
+    }
112
+    if (!$res) {
113
+        return "";
114
+    }
115
+
116
+    list($nom, $desc) = $depart;
117
+
118
+    return fabrique_jointures($boucle, $res, $cond, $desc, $nom, $col);
119 119
 }
120 120
 
121 121
 /**
@@ -154,74 +154,74 @@  discard block
 block discarded – undo
154 154
  *     Alias de la table de jointure (Lx)
155 155
  */
156 156
 function fabrique_jointures(&$boucle, $res, $cond = false, $desc = array(), $nom = '', $col = '', $echap = true) {
157
-	static $num = array();
158
-	$id_table = "";
159
-	$cpt = &$num[$boucle->descr['nom']][$boucle->descr['gram']][$boucle->id_boucle];
160
-	foreach ($res as $cle => $r) {
161
-		list($d, $a, $j) = $r;
162
-		if (!$id_table) {
163
-			$id_table = $d;
164
-		}
165
-		$n = ++$cpt;
166
-		if (is_array($j)) { // c'est un lien sur un champ du type id_objet,objet,'article'
167
-			list($j1, $j2, $obj, $type) = $j;
168
-			// trouver de quel cote est (id_objet,objet)
169
-			if ($j1 == "id_$obj") {
170
-				$obj = "$id_table.$obj";
171
-			} else {
172
-				$obj = "L$n.$obj";
173
-			}
174
-			// le where complementaire est envoye dans la jointure et dans le where
175
-			// on utilise une clé qui le relie a la jointure pour que l'optimiseur
176
-			// sache qu'il peut enlever ce where si il enleve la jointure
177
-			$boucle->where["JOIN-L$n"] = array("'='","'$obj'","sql_quote('$type')");
178
-			$boucle->join["L$n"] =
179
-				$echap ?
180
-					array("'$id_table'", "'$j2'", "'$j1'", "'$obj='.sql_quote('$type')")
181
-					:
182
-					array($id_table, $j2, $j1, "$obj=" . sql_quote($type));
183
-		} else {
184
-			$boucle->join["L$n"] = $echap ? array("'$id_table'", "'$j'") : array($id_table, $j);
185
-		}
186
-		$boucle->from[$id_table = "L$n"] = $a[0];
187
-	}
188
-
189
-
190
-	// pas besoin de group by
191
-	// (cf http://article.gmane.org/gmane.comp.web.spip.devel/30555)
192
-	// si une seule jointure et sur une table avec primary key formee
193
-	// de l'index principal et de l'index de jointure (non conditionnel! [6031])
194
-	// et operateur d'egalite (https://core.spip.net/issues/477)
195
-
196
-	if ($pk = (isset($a[1]) && (count($boucle->from) == 2) && !$cond)) {
197
-		$pk = nogroupby_if($desc, $a[1], $col);
198
-	}
199
-
200
-	// pas de group by 
201
-	// si une seule jointure
202
-	// et si l'index de jointure est une primary key a l'arrivee !
203
-	if (!$pk
204
-		and (count($boucle->from) == 2)
205
-		and isset($a[1]['key']['PRIMARY KEY'])
206
-		and ($j == $a[1]['key']['PRIMARY KEY'])
207
-	) {
208
-		$pk = true;
209
-	}
210
-
211
-	// la clause Group by est en conflit avec ORDER BY, a completer
212
-	$groups = liste_champs_jointures($nom, $desc, true);
213
-	if (!$pk) {
214
-		foreach ($groups as $id_prim) {
215
-			$id_field = $nom . '.' . $id_prim;
216
-			if (!in_array($id_field, $boucle->group)) {
217
-				$boucle->group[] = $id_field;
218
-			}
219
-		}
220
-	}
221
-
222
-	$boucle->modificateur['lien'] = true;
223
-
224
-	return "L$n";
157
+    static $num = array();
158
+    $id_table = "";
159
+    $cpt = &$num[$boucle->descr['nom']][$boucle->descr['gram']][$boucle->id_boucle];
160
+    foreach ($res as $cle => $r) {
161
+        list($d, $a, $j) = $r;
162
+        if (!$id_table) {
163
+            $id_table = $d;
164
+        }
165
+        $n = ++$cpt;
166
+        if (is_array($j)) { // c'est un lien sur un champ du type id_objet,objet,'article'
167
+            list($j1, $j2, $obj, $type) = $j;
168
+            // trouver de quel cote est (id_objet,objet)
169
+            if ($j1 == "id_$obj") {
170
+                $obj = "$id_table.$obj";
171
+            } else {
172
+                $obj = "L$n.$obj";
173
+            }
174
+            // le where complementaire est envoye dans la jointure et dans le where
175
+            // on utilise une clé qui le relie a la jointure pour que l'optimiseur
176
+            // sache qu'il peut enlever ce where si il enleve la jointure
177
+            $boucle->where["JOIN-L$n"] = array("'='","'$obj'","sql_quote('$type')");
178
+            $boucle->join["L$n"] =
179
+                $echap ?
180
+                    array("'$id_table'", "'$j2'", "'$j1'", "'$obj='.sql_quote('$type')")
181
+                    :
182
+                    array($id_table, $j2, $j1, "$obj=" . sql_quote($type));
183
+        } else {
184
+            $boucle->join["L$n"] = $echap ? array("'$id_table'", "'$j'") : array($id_table, $j);
185
+        }
186
+        $boucle->from[$id_table = "L$n"] = $a[0];
187
+    }
188
+
189
+
190
+    // pas besoin de group by
191
+    // (cf http://article.gmane.org/gmane.comp.web.spip.devel/30555)
192
+    // si une seule jointure et sur une table avec primary key formee
193
+    // de l'index principal et de l'index de jointure (non conditionnel! [6031])
194
+    // et operateur d'egalite (https://core.spip.net/issues/477)
195
+
196
+    if ($pk = (isset($a[1]) && (count($boucle->from) == 2) && !$cond)) {
197
+        $pk = nogroupby_if($desc, $a[1], $col);
198
+    }
199
+
200
+    // pas de group by 
201
+    // si une seule jointure
202
+    // et si l'index de jointure est une primary key a l'arrivee !
203
+    if (!$pk
204
+        and (count($boucle->from) == 2)
205
+        and isset($a[1]['key']['PRIMARY KEY'])
206
+        and ($j == $a[1]['key']['PRIMARY KEY'])
207
+    ) {
208
+        $pk = true;
209
+    }
210
+
211
+    // la clause Group by est en conflit avec ORDER BY, a completer
212
+    $groups = liste_champs_jointures($nom, $desc, true);
213
+    if (!$pk) {
214
+        foreach ($groups as $id_prim) {
215
+            $id_field = $nom . '.' . $id_prim;
216
+            if (!in_array($id_field, $boucle->group)) {
217
+                $boucle->group[] = $id_field;
218
+            }
219
+        }
220
+    }
221
+
222
+    $boucle->modificateur['lien'] = true;
223
+
224
+    return "L$n";
225 225
 }
226 226
 
227 227
 /**
@@ -236,16 +236,16 @@  discard block
 block discarded – undo
236 236
  * @return bool
237 237
  */
238 238
 function nogroupby_if($depart, $arrivee, $col) {
239
-	$pk = $arrivee['key']['PRIMARY KEY'];
240
-	if (!$pk) {
241
-		return false;
242
-	}
243
-	$id_primary = $depart['key']['PRIMARY KEY'];
244
-	if (is_array($col)) {
245
-		$col = implode(', *', $col);
246
-	} // cas id_objet, objet
247
-	return (preg_match("/^$id_primary, *$col$/", $pk) or
248
-		preg_match("/^$col, *$id_primary$/", $pk));
239
+    $pk = $arrivee['key']['PRIMARY KEY'];
240
+    if (!$pk) {
241
+        return false;
242
+    }
243
+    $id_primary = $depart['key']['PRIMARY KEY'];
244
+    if (is_array($col)) {
245
+        $col = implode(', *', $col);
246
+    } // cas id_objet, objet
247
+    return (preg_match("/^$id_primary, *$col$/", $pk) or
248
+        preg_match("/^$col, *$id_primary$/", $pk));
249 249
 }
250 250
 
251 251
 /**
@@ -263,46 +263,46 @@  discard block
 block discarded – undo
263 263
  */
264 264
 function liste_champs_jointures($nom, $desc, $primary = false) {
265 265
 
266
-	static $nojoin = array('idx', 'maj', 'date', 'statut');
266
+    static $nojoin = array('idx', 'maj', 'date', 'statut');
267 267
 
268
-	// si cle primaire demandee, la privilegier
269
-	if ($primary && isset($desc['key']['PRIMARY KEY'])) {
270
-		return split_key($desc['key']['PRIMARY KEY']);
271
-	}
268
+    // si cle primaire demandee, la privilegier
269
+    if ($primary && isset($desc['key']['PRIMARY KEY'])) {
270
+        return split_key($desc['key']['PRIMARY KEY']);
271
+    }
272 272
 
273
-	// les champs declares explicitement pour les jointures
274
-	if (isset($desc['join'])) {
275
-		return $desc['join'];
276
-	}
277
-	/*elseif (isset($GLOBALS['tables_principales'][$nom]['join'])) return $GLOBALS['tables_principales'][$nom]['join'];
273
+    // les champs declares explicitement pour les jointures
274
+    if (isset($desc['join'])) {
275
+        return $desc['join'];
276
+    }
277
+    /*elseif (isset($GLOBALS['tables_principales'][$nom]['join'])) return $GLOBALS['tables_principales'][$nom]['join'];
278 278
 	elseif (isset($GLOBALS['tables_auxiliaires'][$nom]['join'])) return $GLOBALS['tables_auxiliaires'][$nom]['join'];*/
279 279
 
280
-	// si pas de cle, c'est fichu
281
-	if (!isset($desc['key'])) {
282
-		return array();
283
-	}
284
-
285
-	// si cle primaire
286
-	if (isset($desc['key']['PRIMARY KEY'])) {
287
-		return split_key($desc['key']['PRIMARY KEY']);
288
-	}
289
-
290
-	// ici on se rabat sur les cles secondaires, 
291
-	// en eliminant celles qui sont pas pertinentes (idx, maj)
292
-	// si jamais le resultat n'est pas pertinent pour une table donnee,
293
-	// il faut declarer explicitement le champ 'join' de sa description
294
-
295
-	$join = array();
296
-	foreach ($desc['key'] as $v) {
297
-		$join = split_key($v, $join);
298
-	}
299
-	foreach ($join as $k) {
300
-		if (in_array($k, $nojoin)) {
301
-			unset($join[$k]);
302
-		}
303
-	}
304
-
305
-	return $join;
280
+    // si pas de cle, c'est fichu
281
+    if (!isset($desc['key'])) {
282
+        return array();
283
+    }
284
+
285
+    // si cle primaire
286
+    if (isset($desc['key']['PRIMARY KEY'])) {
287
+        return split_key($desc['key']['PRIMARY KEY']);
288
+    }
289
+
290
+    // ici on se rabat sur les cles secondaires, 
291
+    // en eliminant celles qui sont pas pertinentes (idx, maj)
292
+    // si jamais le resultat n'est pas pertinent pour une table donnee,
293
+    // il faut declarer explicitement le champ 'join' de sa description
294
+
295
+    $join = array();
296
+    foreach ($desc['key'] as $v) {
297
+        $join = split_key($v, $join);
298
+    }
299
+    foreach ($join as $k) {
300
+        if (in_array($k, $nojoin)) {
301
+            unset($join[$k]);
302
+        }
303
+    }
304
+
305
+    return $join;
306 306
 }
307 307
 
308 308
 /**
@@ -313,14 +313,14 @@  discard block
 block discarded – undo
313 313
  * @return array
314 314
  */
315 315
 function split_key($v, $join = array()) {
316
-	foreach (preg_split('/,\s*/', $v) as $k) {
317
-		if (strpos($k, '(') !== false) {
318
-			$k = explode('(', $k);
319
-			$k = trim(reset($k));
320
-		}
321
-		$join[$k] = $k;
322
-	}
323
-	return $join;
316
+    foreach (preg_split('/,\s*/', $v) as $k) {
317
+        if (strpos($k, '(') !== false) {
318
+            $k = explode('(', $k);
319
+            $k = trim(reset($k));
320
+        }
321
+        $join[$k] = $k;
322
+    }
323
+    return $join;
324 324
 }
325 325
 
326 326
 /**
@@ -343,126 +343,126 @@  discard block
 block discarded – undo
343 343
  * @return array
344 344
  */
345 345
 function calculer_chaine_jointures(
346
-	&$boucle,
347
-	$depart,
348
-	$arrivee,
349
-	$vu = array(),
350
-	$milieu_exclus = array(),
351
-	$max_liens = 5
346
+    &$boucle,
347
+    $depart,
348
+    $arrivee,
349
+    $vu = array(),
350
+    $milieu_exclus = array(),
351
+    $max_liens = 5
352 352
 ) {
353
-	static $trouver_table;
354
-	if (!$trouver_table) {
355
-		$trouver_table = charger_fonction('trouver_table', 'base');
356
-	}
357
-
358
-	if (is_string($milieu_exclus)) {
359
-		$milieu_exclus = array($milieu_exclus);
360
-	}
361
-	// quand on a exclus id_objet comme cle de jointure, il faut aussi exclure objet
362
-	// faire une jointure sur objet tout seul n'a pas de sens
363
-	if (in_array('id_objet', $milieu_exclus) and !in_array('objet', $milieu_exclus)) {
364
-		$milieu_exclus[] = 'objet';
365
-	}
366
-
367
-	list($dnom, $ddesc) = $depart;
368
-	list($anom, $adesc) = $arrivee;
369
-	if (!count($vu)) {
370
-		$vu[] = $dnom; // ne pas oublier la table de depart
371
-		$vu[] = $anom; // ne pas oublier la table d'arrivee
372
-	}
373
-
374
-	$akeys = array();
375
-	foreach ($adesc['key'] as $k) {
376
-		// respecter l'ordre de $adesc['key'] pour ne pas avoir id_trad en premier entre autres...
377
-		$akeys = array_merge($akeys, preg_split('/,\s*/', $k));
378
-	}
379
-
380
-	// enlever les cles d'arrivee exclues par l'appel
381
-	$akeys = array_diff($akeys, $milieu_exclus);
382
-
383
-	// cles candidates au depart
384
-	$keys = liste_champs_jointures($dnom, $ddesc);
385
-	// enlever les cles dde depart exclues par l'appel
386
-	$keys = array_diff($keys, $milieu_exclus);
387
-
388
-	$v = !$keys ? false : array_intersect(array_values($keys), $akeys);
389
-
390
-	if ($v) {
391
-		return array(array($dnom, array($adesc['table'], $adesc), array_shift($v)));
392
-	}
393
-
394
-	// regarder si l'on a (id_objet,objet) au depart et si on peut le mapper sur un id_xx
395
-	if (count(array_intersect(array('id_objet', 'objet'), $keys)) == 2) {
396
-		// regarder si l'une des cles d'arrivee peut se decomposer en 
397
-		// id_objet,objet
398
-		// si oui on la prend
399
-		foreach ($akeys as $key) {
400
-			$v = decompose_champ_id_objet($key);
401
-			if (is_array($v)) {
402
-				$objet = array_shift($v); // objet,'article'
403
-				array_unshift($v, $key); // id_article,objet,'article'
404
-				array_unshift($v, $objet); // id_objet,id_article,objet,'article'
405
-				return array(array($dnom, array($adesc['table'], $adesc), $v));
406
-			}
407
-		}
408
-	} else {
409
-		// regarder si l'une des cles de depart peut se decomposer en 
410
-		// id_objet,objet a l'arrivee
411
-		// si oui on la prend
412
-		foreach ($keys as $key) {
413
-			if (count($v = trouver_champs_decomposes($key, $adesc)) > 1) {
414
-				if (count($v) == count(array_intersect($v, $akeys))) {
415
-					$v = decompose_champ_id_objet($key); // id_objet,objet,'article'
416
-					array_unshift($v, $key); // id_article,id_objet,objet,'article'
417
-					return array(array($dnom, array($adesc['table'], $adesc), $v));
418
-				}
419
-			}
420
-		}
421
-	}
422
-	// si l'on voulait une jointure direct, c'est rate !
423
-	if ($max_liens <= 1) {
424
-		return array();
425
-	}
426
-
427
-	// sinon essayer de passer par une autre table
428
-	$new = $vu;
429
-	foreach ($boucle->jointures as $v) {
430
-		if ($v
431
-			and !in_array($v, $vu)
432
-			and $def = $trouver_table($v, $boucle->sql_serveur)
433
-			and !in_array($def['table_sql'], $vu)
434
-		) {
435
-			// ne pas tester les cles qui sont exclues a l'appel
436
-			// ie la cle de la jointure precedente
437
-			$test_cles = $milieu_exclus;
438
-			$new[] = $v;
439
-			$max_iter = 50; // securite
440
-			while (count($jointure_directe_possible = calculer_chaine_jointures($boucle, $depart, array($v, $def), $vu,
441
-					$test_cles, 1))
442
-				and $max_iter--) {
443
-				$jointure_directe_possible = reset($jointure_directe_possible);
444
-				$milieu = end($jointure_directe_possible);
445
-				$exclure_fin = $milieu_exclus;
446
-				if (is_string($milieu)) {
447
-					$exclure_fin[] = $milieu;
448
-					$test_cles[] = $milieu;
449
-				} else {
450
-					$exclure_fin = array_merge($exclure_fin, $milieu);
451
-					$test_cles = array_merge($test_cles, $milieu);
452
-				}
453
-				// essayer de rejoindre l'arrivee a partir de cette etape intermediaire
454
-				// sans repasser par la meme cle milieu, ni une cle deja vue !
455
-				$r = calculer_chaine_jointures($boucle, array($v, $def), $arrivee, $new, $exclure_fin, $max_liens - 1);
456
-				if ($r) {
457
-					array_unshift($r, $jointure_directe_possible);
458
-
459
-					return $r;
460
-				}
461
-			}
462
-		}
463
-	}
464
-
465
-	return array();
353
+    static $trouver_table;
354
+    if (!$trouver_table) {
355
+        $trouver_table = charger_fonction('trouver_table', 'base');
356
+    }
357
+
358
+    if (is_string($milieu_exclus)) {
359
+        $milieu_exclus = array($milieu_exclus);
360
+    }
361
+    // quand on a exclus id_objet comme cle de jointure, il faut aussi exclure objet
362
+    // faire une jointure sur objet tout seul n'a pas de sens
363
+    if (in_array('id_objet', $milieu_exclus) and !in_array('objet', $milieu_exclus)) {
364
+        $milieu_exclus[] = 'objet';
365
+    }
366
+
367
+    list($dnom, $ddesc) = $depart;
368
+    list($anom, $adesc) = $arrivee;
369
+    if (!count($vu)) {
370
+        $vu[] = $dnom; // ne pas oublier la table de depart
371
+        $vu[] = $anom; // ne pas oublier la table d'arrivee
372
+    }
373
+
374
+    $akeys = array();
375
+    foreach ($adesc['key'] as $k) {
376
+        // respecter l'ordre de $adesc['key'] pour ne pas avoir id_trad en premier entre autres...
377
+        $akeys = array_merge($akeys, preg_split('/,\s*/', $k));
378
+    }
379
+
380
+    // enlever les cles d'arrivee exclues par l'appel
381
+    $akeys = array_diff($akeys, $milieu_exclus);
382
+
383
+    // cles candidates au depart
384
+    $keys = liste_champs_jointures($dnom, $ddesc);
385
+    // enlever les cles dde depart exclues par l'appel
386
+    $keys = array_diff($keys, $milieu_exclus);
387
+
388
+    $v = !$keys ? false : array_intersect(array_values($keys), $akeys);
389
+
390
+    if ($v) {
391
+        return array(array($dnom, array($adesc['table'], $adesc), array_shift($v)));
392
+    }
393
+
394
+    // regarder si l'on a (id_objet,objet) au depart et si on peut le mapper sur un id_xx
395
+    if (count(array_intersect(array('id_objet', 'objet'), $keys)) == 2) {
396
+        // regarder si l'une des cles d'arrivee peut se decomposer en 
397
+        // id_objet,objet
398
+        // si oui on la prend
399
+        foreach ($akeys as $key) {
400
+            $v = decompose_champ_id_objet($key);
401
+            if (is_array($v)) {
402
+                $objet = array_shift($v); // objet,'article'
403
+                array_unshift($v, $key); // id_article,objet,'article'
404
+                array_unshift($v, $objet); // id_objet,id_article,objet,'article'
405
+                return array(array($dnom, array($adesc['table'], $adesc), $v));
406
+            }
407
+        }
408
+    } else {
409
+        // regarder si l'une des cles de depart peut se decomposer en 
410
+        // id_objet,objet a l'arrivee
411
+        // si oui on la prend
412
+        foreach ($keys as $key) {
413
+            if (count($v = trouver_champs_decomposes($key, $adesc)) > 1) {
414
+                if (count($v) == count(array_intersect($v, $akeys))) {
415
+                    $v = decompose_champ_id_objet($key); // id_objet,objet,'article'
416
+                    array_unshift($v, $key); // id_article,id_objet,objet,'article'
417
+                    return array(array($dnom, array($adesc['table'], $adesc), $v));
418
+                }
419
+            }
420
+        }
421
+    }
422
+    // si l'on voulait une jointure direct, c'est rate !
423
+    if ($max_liens <= 1) {
424
+        return array();
425
+    }
426
+
427
+    // sinon essayer de passer par une autre table
428
+    $new = $vu;
429
+    foreach ($boucle->jointures as $v) {
430
+        if ($v
431
+            and !in_array($v, $vu)
432
+            and $def = $trouver_table($v, $boucle->sql_serveur)
433
+            and !in_array($def['table_sql'], $vu)
434
+        ) {
435
+            // ne pas tester les cles qui sont exclues a l'appel
436
+            // ie la cle de la jointure precedente
437
+            $test_cles = $milieu_exclus;
438
+            $new[] = $v;
439
+            $max_iter = 50; // securite
440
+            while (count($jointure_directe_possible = calculer_chaine_jointures($boucle, $depart, array($v, $def), $vu,
441
+                    $test_cles, 1))
442
+                and $max_iter--) {
443
+                $jointure_directe_possible = reset($jointure_directe_possible);
444
+                $milieu = end($jointure_directe_possible);
445
+                $exclure_fin = $milieu_exclus;
446
+                if (is_string($milieu)) {
447
+                    $exclure_fin[] = $milieu;
448
+                    $test_cles[] = $milieu;
449
+                } else {
450
+                    $exclure_fin = array_merge($exclure_fin, $milieu);
451
+                    $test_cles = array_merge($test_cles, $milieu);
452
+                }
453
+                // essayer de rejoindre l'arrivee a partir de cette etape intermediaire
454
+                // sans repasser par la meme cle milieu, ni une cle deja vue !
455
+                $r = calculer_chaine_jointures($boucle, array($v, $def), $arrivee, $new, $exclure_fin, $max_liens - 1);
456
+                if ($r) {
457
+                    array_unshift($r, $jointure_directe_possible);
458
+
459
+                    return $r;
460
+                }
461
+            }
462
+        }
463
+    }
464
+
465
+    return array();
466 466
 }
467 467
 
468 468
 /**
@@ -473,18 +473,18 @@  discard block
 block discarded – undo
473 473
  * @return array
474 474
  */
475 475
 function trouver_cles_table($keys) {
476
-	$res = array();
477
-	foreach ($keys as $v) {
478
-		if (!strpos($v, ",")) {
479
-			$res[$v] = 1;
480
-		} else {
481
-			foreach (preg_split("/\s*,\s*/", $v) as $k) {
482
-				$res[$k] = 1;
483
-			}
484
-		}
485
-	}
486
-
487
-	return array_keys($res);
476
+    $res = array();
477
+    foreach ($keys as $v) {
478
+        if (!strpos($v, ",")) {
479
+            $res[$v] = 1;
480
+        } else {
481
+            foreach (preg_split("/\s*,\s*/", $v) as $k) {
482
+                $res[$k] = 1;
483
+            }
484
+        }
485
+    }
486
+
487
+    return array_keys($res);
488 488
 }
489 489
 
490 490
 
@@ -511,33 +511,33 @@  discard block
 block discarded – undo
511 511
  *     - 'alias' : alias utilisé pour la table (si pertinent. ie: avec `$boucle->from` transmis par exemple)
512 512
  */
513 513
 function chercher_champ_dans_tables($cle, $tables, $connect, $checkarrivee = false) {
514
-	static $trouver_table = '';
515
-	if (!$trouver_table) {
516
-		$trouver_table = charger_fonction('trouver_table', 'base');
517
-	}
518
-
519
-	if (!is_array($cle)) {
520
-		$cle = array($cle);
521
-	}
522
-
523
-	foreach ($tables as $k => $table) {
524
-		if ($table && $desc = $trouver_table($table, $connect)) {
525
-			if (isset($desc['field'])
526
-				// verifier que toutes les cles cherchees sont la
527
-				and (count(array_intersect($cle, array_keys($desc['field']))) == count($cle))
528
-				// si on sait ou on veut arriver, il faut que ca colle
529
-				and ($checkarrivee == false || $checkarrivee == $desc['table'])
530
-			) {
531
-				return array(
532
-					'desc' => $desc,
533
-					'table' => $desc['table'],
534
-					'alias' => $k,
535
-				);
536
-			}
537
-		}
538
-	}
539
-
540
-	return false;
514
+    static $trouver_table = '';
515
+    if (!$trouver_table) {
516
+        $trouver_table = charger_fonction('trouver_table', 'base');
517
+    }
518
+
519
+    if (!is_array($cle)) {
520
+        $cle = array($cle);
521
+    }
522
+
523
+    foreach ($tables as $k => $table) {
524
+        if ($table && $desc = $trouver_table($table, $connect)) {
525
+            if (isset($desc['field'])
526
+                // verifier que toutes les cles cherchees sont la
527
+                and (count(array_intersect($cle, array_keys($desc['field']))) == count($cle))
528
+                // si on sait ou on veut arriver, il faut que ca colle
529
+                and ($checkarrivee == false || $checkarrivee == $desc['table'])
530
+            ) {
531
+                return array(
532
+                    'desc' => $desc,
533
+                    'table' => $desc['table'],
534
+                    'alias' => $k,
535
+                );
536
+            }
537
+        }
538
+    }
539
+
540
+    return false;
541 541
 }
542 542
 
543 543
 /**
@@ -563,52 +563,52 @@  discard block
 block discarded – undo
563 563
  */
564 564
 function trouver_champ_exterieur($cle, $joints, &$boucle, $checkarrivee = false) {
565 565
 
566
-	// support de la recherche multi champ :
567
-	// si en seconde etape on a decompose le champ id_xx en id_objet,objet
568
-	// on reentre ici soit en cherchant une table les 2 champs id_objet,objet
569
-	// soit une table avec les 3 champs id_xx, id_objet, objet
570
-	if (!is_array($cle)) {
571
-		$cle = array($cle);
572
-	}
573
-
574
-	if ($infos = chercher_champ_dans_tables($cle, $joints, $boucle->sql_serveur, $checkarrivee)) {
575
-		return array($infos['table'], $infos['desc'], $cle);
576
-	}
577
-
578
-	// au premier coup, on essaye de decomposer, si possible
579
-	if (count($cle) == 1
580
-		and $c = reset($cle)
581
-		and is_array($decompose = decompose_champ_id_objet($c))
582
-	) {
583
-
584
-		$desc = $boucle->show;
585
-
586
-		// cas 1 : la cle id_xx est dans la table de depart
587
-		// -> on cherche uniquement id_objet,objet a l'arrivee
588
-		if (isset($desc['field'][$c])) {
589
-			$cle = array();
590
-			$cle[] = array_shift($decompose); // id_objet
591
-			$cle[] = array_shift($decompose); // objet
592
-			return trouver_champ_exterieur($cle, $joints, $boucle, $checkarrivee);
593
-		}
594
-		// cas 2 : la cle id_xx n'est pas dans la table de depart
595
-		// -> il faut trouver une cle de depart zzz telle que
596
-		// id_objet,objet,zzz soit a l'arrivee
597
-		else {
598
-			$depart = liste_champs_jointures((isset($desc['table']) ? $desc['table'] : ''), $desc);
599
-			foreach ($depart as $d) {
600
-				$cle = array();
601
-				$cle[] = array_shift($decompose); // id_objet
602
-				$cle[] = array_shift($decompose); // objet
603
-				$cle[] = $d;
604
-				if ($ext = trouver_champ_exterieur($cle, $joints, $boucle, $checkarrivee)) {
605
-					return $ext;
606
-				}
607
-			}
608
-		}
609
-	}
610
-
611
-	return "";
566
+    // support de la recherche multi champ :
567
+    // si en seconde etape on a decompose le champ id_xx en id_objet,objet
568
+    // on reentre ici soit en cherchant une table les 2 champs id_objet,objet
569
+    // soit une table avec les 3 champs id_xx, id_objet, objet
570
+    if (!is_array($cle)) {
571
+        $cle = array($cle);
572
+    }
573
+
574
+    if ($infos = chercher_champ_dans_tables($cle, $joints, $boucle->sql_serveur, $checkarrivee)) {
575
+        return array($infos['table'], $infos['desc'], $cle);
576
+    }
577
+
578
+    // au premier coup, on essaye de decomposer, si possible
579
+    if (count($cle) == 1
580
+        and $c = reset($cle)
581
+        and is_array($decompose = decompose_champ_id_objet($c))
582
+    ) {
583
+
584
+        $desc = $boucle->show;
585
+
586
+        // cas 1 : la cle id_xx est dans la table de depart
587
+        // -> on cherche uniquement id_objet,objet a l'arrivee
588
+        if (isset($desc['field'][$c])) {
589
+            $cle = array();
590
+            $cle[] = array_shift($decompose); // id_objet
591
+            $cle[] = array_shift($decompose); // objet
592
+            return trouver_champ_exterieur($cle, $joints, $boucle, $checkarrivee);
593
+        }
594
+        // cas 2 : la cle id_xx n'est pas dans la table de depart
595
+        // -> il faut trouver une cle de depart zzz telle que
596
+        // id_objet,objet,zzz soit a l'arrivee
597
+        else {
598
+            $depart = liste_champs_jointures((isset($desc['table']) ? $desc['table'] : ''), $desc);
599
+            foreach ($depart as $d) {
600
+                $cle = array();
601
+                $cle[] = array_shift($decompose); // id_objet
602
+                $cle[] = array_shift($decompose); // objet
603
+                $cle[] = $d;
604
+                if ($ext = trouver_champ_exterieur($cle, $joints, $boucle, $checkarrivee)) {
605
+                    return $ext;
606
+                }
607
+            }
608
+        }
609
+    }
610
+
611
+    return "";
612 612
 }
613 613
 
614 614
 /**
@@ -640,21 +640,21 @@  discard block
 block discarded – undo
640 640
  * @return string
641 641
  */
642 642
 function trouver_jointure_champ($champ, &$boucle, $jointures = false, $cond = false, $checkarrivee = false) {
643
-	if ($jointures === false) {
644
-		$jointures = $boucle->jointures;
645
-	}
646
-	// TODO : aberration, on utilise $jointures pour trouver le champ
647
-	// mais pas poour construire la jointure ensuite
648
-	$arrivee = trouver_champ_exterieur($champ, $jointures, $boucle, $checkarrivee);
649
-	if ($arrivee) {
650
-		$desc = $boucle->show;
651
-		array_pop($arrivee); // enlever la cle en 3eme argument
652
-		$cle = calculer_jointure($boucle, array($desc['id_table'], $desc), $arrivee, '', $cond);
653
-		if ($cle) {
654
-			return $cle;
655
-		}
656
-	}
657
-	spip_log("trouver_jointure_champ: $champ inconnu");
658
-
659
-	return '';
643
+    if ($jointures === false) {
644
+        $jointures = $boucle->jointures;
645
+    }
646
+    // TODO : aberration, on utilise $jointures pour trouver le champ
647
+    // mais pas poour construire la jointure ensuite
648
+    $arrivee = trouver_champ_exterieur($champ, $jointures, $boucle, $checkarrivee);
649
+    if ($arrivee) {
650
+        $desc = $boucle->show;
651
+        array_pop($arrivee); // enlever la cle en 3eme argument
652
+        $cle = calculer_jointure($boucle, array($desc['id_table'], $desc), $arrivee, '', $cond);
653
+        if ($cle) {
654
+            return $cle;
655
+        }
656
+    }
657
+    spip_log("trouver_jointure_champ: $champ inconnu");
658
+
659
+    return '';
660 660
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -174,12 +174,12 @@  discard block
 block discarded – undo
174 174
 			// le where complementaire est envoye dans la jointure et dans le where
175 175
 			// on utilise une clé qui le relie a la jointure pour que l'optimiseur
176 176
 			// sache qu'il peut enlever ce where si il enleve la jointure
177
-			$boucle->where["JOIN-L$n"] = array("'='","'$obj'","sql_quote('$type')");
177
+			$boucle->where["JOIN-L$n"] = array("'='", "'$obj'", "sql_quote('$type')");
178 178
 			$boucle->join["L$n"] =
179 179
 				$echap ?
180 180
 					array("'$id_table'", "'$j2'", "'$j1'", "'$obj='.sql_quote('$type')")
181 181
 					:
182
-					array($id_table, $j2, $j1, "$obj=" . sql_quote($type));
182
+					array($id_table, $j2, $j1, "$obj=".sql_quote($type));
183 183
 		} else {
184 184
 			$boucle->join["L$n"] = $echap ? array("'$id_table'", "'$j'") : array($id_table, $j);
185 185
 		}
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
 	$groups = liste_champs_jointures($nom, $desc, true);
213 213
 	if (!$pk) {
214 214
 		foreach ($groups as $id_prim) {
215
-			$id_field = $nom . '.' . $id_prim;
215
+			$id_field = $nom.'.'.$id_prim;
216 216
 			if (!in_array($id_field, $boucle->group)) {
217 217
 				$boucle->group[] = $id_field;
218 218
 			}
Please login to merge, or discard this patch.