Completed
Push — master ( fb0017...92433c )
by cam
01:14
created
prive/formulaires/rediriger_article.php 2 patches
Indentation   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -11,65 +11,65 @@
 block discarded – undo
11 11
 \***************************************************************************/
12 12
 
13 13
 if (!defined('_ECRIRE_INC_VERSION')) {
14
-	return;
14
+    return;
15 15
 }
16 16
 
17 17
 function formulaires_rediriger_article_charger_dist($id_article, $retour = '') {
18 18
 
19
-	include_spip('inc/autoriser');
20
-	if (!autoriser('modifier', 'article', $id_article)) {
21
-		return false;
22
-	}
23
-
24
-	$row = sql_fetsel('id_article,virtuel', 'spip_articles', 'id_article=' . intval($id_article));
25
-	if (!$row['id_article']) {
26
-		return false;
27
-	}
28
-	include_spip('inc/lien');
29
-	$redirection = virtuel_redirige($row['virtuel']);
30
-
31
-	if (
32
-		!$redirection
33
-		and $GLOBALS['meta']['articles_redirection'] != 'oui'
34
-	) {
35
-		return false;
36
-	}
37
-
38
-
39
-	include_spip('inc/texte');
40
-	$valeurs = [
41
-		'redirection' => $redirection,
42
-		'id' => $id_article,
43
-		'_afficher_url' => ($redirection ? propre("[->$redirection]") : ''),
44
-	];
45
-
46
-	return $valeurs;
19
+    include_spip('inc/autoriser');
20
+    if (!autoriser('modifier', 'article', $id_article)) {
21
+        return false;
22
+    }
23
+
24
+    $row = sql_fetsel('id_article,virtuel', 'spip_articles', 'id_article=' . intval($id_article));
25
+    if (!$row['id_article']) {
26
+        return false;
27
+    }
28
+    include_spip('inc/lien');
29
+    $redirection = virtuel_redirige($row['virtuel']);
30
+
31
+    if (
32
+        !$redirection
33
+        and $GLOBALS['meta']['articles_redirection'] != 'oui'
34
+    ) {
35
+        return false;
36
+    }
37
+
38
+
39
+    include_spip('inc/texte');
40
+    $valeurs = [
41
+        'redirection' => $redirection,
42
+        'id' => $id_article,
43
+        '_afficher_url' => ($redirection ? propre("[->$redirection]") : ''),
44
+    ];
45
+
46
+    return $valeurs;
47 47
 }
48 48
 
49 49
 function formulaires_rediriger_article_verifier_dist($id_article, $retour = '') {
50
-	$erreurs = [];
50
+    $erreurs = [];
51 51
 
52
-	if (($redirection = _request('redirection')) == $id_article || $redirection == 'art' . $id_article) {
53
-		$erreurs['redirection'] = _T('info_redirection_boucle');
54
-	}
52
+    if (($redirection = _request('redirection')) == $id_article || $redirection == 'art' . $id_article) {
53
+        $erreurs['redirection'] = _T('info_redirection_boucle');
54
+    }
55 55
 
56
-	return $erreurs;
56
+    return $erreurs;
57 57
 }
58 58
 
59 59
 function formulaires_rediriger_article_traiter_dist($id_article, $retour = '') {
60 60
 
61
-	$url = preg_replace(',^\s*https?://$,i', '', rtrim(_request('redirection')));
62
-	if ($url) {
63
-		$url = corriger_caracteres($url);
64
-	}
61
+    $url = preg_replace(',^\s*https?://$,i', '', rtrim(_request('redirection')));
62
+    if ($url) {
63
+        $url = corriger_caracteres($url);
64
+    }
65 65
 
66
-	include_spip('action/editer_article');
67
-	article_modifier($id_article, ['virtuel' => $url]);
66
+    include_spip('action/editer_article');
67
+    article_modifier($id_article, ['virtuel' => $url]);
68 68
 
69
-	$js = _AJAX ? '<script type="text/javascript">if (window.ajaxReload) ajaxReload("wysiwyg");</script>' : '';
69
+    $js = _AJAX ? '<script type="text/javascript">if (window.ajaxReload) ajaxReload("wysiwyg");</script>' : '';
70 70
 
71
-	return [
72
-		'message_ok' => ($url ? _T('info_redirection_activee') : _T('info_redirection_desactivee')) . $js,
73
-		'editable' => true
74
-	];
71
+    return [
72
+        'message_ok' => ($url ? _T('info_redirection_activee') : _T('info_redirection_desactivee')) . $js,
73
+        'editable' => true
74
+    ];
75 75
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
 		return false;
22 22
 	}
23 23
 
24
-	$row = sql_fetsel('id_article,virtuel', 'spip_articles', 'id_article=' . intval($id_article));
24
+	$row = sql_fetsel('id_article,virtuel', 'spip_articles', 'id_article='.intval($id_article));
25 25
 	if (!$row['id_article']) {
26 26
 		return false;
27 27
 	}
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
 function formulaires_rediriger_article_verifier_dist($id_article, $retour = '') {
50 50
 	$erreurs = [];
51 51
 
52
-	if (($redirection = _request('redirection')) == $id_article || $redirection == 'art' . $id_article) {
52
+	if (($redirection = _request('redirection')) == $id_article || $redirection == 'art'.$id_article) {
53 53
 		$erreurs['redirection'] = _T('info_redirection_boucle');
54 54
 	}
55 55
 
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
 	$js = _AJAX ? '<script type="text/javascript">if (window.ajaxReload) ajaxReload("wysiwyg");</script>' : '';
70 70
 
71 71
 	return [
72
-		'message_ok' => ($url ? _T('info_redirection_activee') : _T('info_redirection_desactivee')) . $js,
72
+		'message_ok' => ($url ? _T('info_redirection_activee') : _T('info_redirection_desactivee')).$js,
73 73
 		'editable' => true
74 74
 	];
75 75
 }
Please login to merge, or discard this patch.
prive/formulaires/configurer_preferences_menus.php 1 patch
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -30,13 +30,13 @@  discard block
 block discarded – undo
30 30
  *     Environnement du formulaire
31 31
  **/
32 32
 function formulaires_configurer_preferences_menus_charger_dist() {
33
-	// travailler sur des meta fraîches
34
-	include_spip('inc/meta');
35
-	lire_metas();
36
-	$valeurs = [];
37
-	$valeurs['activer_menudev'] = table_valeur($GLOBALS['visiteur_session'], 'prefs/activer_menudev', 'non');
38
-	$valeurs['menus_favoris'] = obtenir_menus_favoris();
39
-	return $valeurs;
33
+    // travailler sur des meta fraîches
34
+    include_spip('inc/meta');
35
+    lire_metas();
36
+    $valeurs = [];
37
+    $valeurs['activer_menudev'] = table_valeur($GLOBALS['visiteur_session'], 'prefs/activer_menudev', 'non');
38
+    $valeurs['menus_favoris'] = obtenir_menus_favoris();
39
+    return $valeurs;
40 40
 }
41 41
 
42 42
 /**
@@ -47,32 +47,32 @@  discard block
 block discarded – undo
47 47
  **/
48 48
 function formulaires_configurer_preferences_menus_traiter_dist() {
49 49
 
50
-	$activer_menudev = _request('activer_menudev');
51
-	$menus_favoris = _request('menus_favoris');
52
-	$menus_favoris = array_filter($menus_favoris);
53
-	$menus_favoris = array_map('intval', $menus_favoris);
50
+    $activer_menudev = _request('activer_menudev');
51
+    $menus_favoris = _request('menus_favoris');
52
+    $menus_favoris = array_filter($menus_favoris);
53
+    $menus_favoris = array_map('intval', $menus_favoris);
54 54
 
55
-	if (_request('reset')) {
56
-		$menus_favoris = [];
57
-		set_request('menus_favoris', null);
58
-	}
55
+    if (_request('reset')) {
56
+        $menus_favoris = [];
57
+        set_request('menus_favoris', null);
58
+    }
59 59
 
60
-	// si le menu dev change, ou les menus favoris, on recharge toute la page.
61
-	if (
62
-		table_valeur($GLOBALS['visiteur_session'], 'prefs/activer_menudev') != $activer_menudev
63
-		or $menus_favoris != obtenir_menus_favoris()
64
-	) {
65
-		refuser_traiter_formulaire_ajax();
60
+    // si le menu dev change, ou les menus favoris, on recharge toute la page.
61
+    if (
62
+        table_valeur($GLOBALS['visiteur_session'], 'prefs/activer_menudev') != $activer_menudev
63
+        or $menus_favoris != obtenir_menus_favoris()
64
+    ) {
65
+        refuser_traiter_formulaire_ajax();
66 66
 
67
-		$GLOBALS['visiteur_session']['prefs']['activer_menudev'] = $activer_menudev;
68
-		$GLOBALS['visiteur_session']['prefs']['menus_favoris'] = $menus_favoris;
67
+        $GLOBALS['visiteur_session']['prefs']['activer_menudev'] = $activer_menudev;
68
+        $GLOBALS['visiteur_session']['prefs']['menus_favoris'] = $menus_favoris;
69 69
 
70
-		if (intval($GLOBALS['visiteur_session']['id_auteur'])) {
71
-			include_spip('action/editer_auteur');
72
-			$c = ['prefs' => serialize($GLOBALS['visiteur_session']['prefs'])];
73
-			auteur_modifier($GLOBALS['visiteur_session']['id_auteur'], $c);
74
-		}
75
-	}
70
+        if (intval($GLOBALS['visiteur_session']['id_auteur'])) {
71
+            include_spip('action/editer_auteur');
72
+            $c = ['prefs' => serialize($GLOBALS['visiteur_session']['prefs'])];
73
+            auteur_modifier($GLOBALS['visiteur_session']['id_auteur'], $c);
74
+        }
75
+    }
76 76
 
77
-	return ['message_ok' => _T('config_info_enregistree'), 'editable' => true];
77
+    return ['message_ok' => _T('config_info_enregistree'), 'editable' => true];
78 78
 }
Please login to merge, or discard this patch.
ecrire/typographie/fr.php 2 patches
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -11,74 +11,74 @@
 block discarded – undo
11 11
 \***************************************************************************/
12 12
 
13 13
 if (!defined('_ECRIRE_INC_VERSION')) {
14
-	return;
14
+    return;
15 15
 }
16 16
 
17 17
 // Correction typographique francaise
18 18
 
19 19
 function typographie_fr_dist($letexte) {
20 20
 
21
-	static $trans;
21
+    static $trans;
22 22
 
23
-	// Nettoyer 160 = nbsp ; 187 = raquo ; 171 = laquo ; 176 = deg ;
24
-	// 147 = ldquo; 148 = rdquo; ' = zouli apostrophe
25
-	if (!$trans) {
26
-		$trans = [
27
-			"'" => '&#8217;',
28
-			'&nbsp;' => '~',
29
-			'&raquo;' => '&#187;',
30
-			'&laquo;' => '&#171;',
31
-			'&rdquo;' => '&#8221;',
32
-			'&ldquo;' => '&#8220;',
33
-			'&deg;' => '&#176;'
34
-		];
35
-		$chars = [160 => '~', 187 => '&#187;', 171 => '&#171;', 148 => '&#8221;', 147 => '&#8220;', 176 => '&#176;'];
36
-		$chars_trans = array_keys($chars);
37
-		$chars = array_values($chars);
38
-		$chars_trans = implode(' ', array_map('chr', $chars_trans));
39
-		$chars_trans = unicode2charset(charset2unicode($chars_trans, 'iso-8859-1', 'forcer'));
40
-		$chars_trans = explode(' ', $chars_trans);
41
-		foreach ($chars as $k => $r) {
42
-			$trans[$chars_trans[$k]] = $r;
43
-		}
44
-	}
23
+    // Nettoyer 160 = nbsp ; 187 = raquo ; 171 = laquo ; 176 = deg ;
24
+    // 147 = ldquo; 148 = rdquo; ' = zouli apostrophe
25
+    if (!$trans) {
26
+        $trans = [
27
+            "'" => '&#8217;',
28
+            '&nbsp;' => '~',
29
+            '&raquo;' => '&#187;',
30
+            '&laquo;' => '&#171;',
31
+            '&rdquo;' => '&#8221;',
32
+            '&ldquo;' => '&#8220;',
33
+            '&deg;' => '&#176;'
34
+        ];
35
+        $chars = [160 => '~', 187 => '&#187;', 171 => '&#171;', 148 => '&#8221;', 147 => '&#8220;', 176 => '&#176;'];
36
+        $chars_trans = array_keys($chars);
37
+        $chars = array_values($chars);
38
+        $chars_trans = implode(' ', array_map('chr', $chars_trans));
39
+        $chars_trans = unicode2charset(charset2unicode($chars_trans, 'iso-8859-1', 'forcer'));
40
+        $chars_trans = explode(' ', $chars_trans);
41
+        foreach ($chars as $k => $r) {
42
+            $trans[$chars_trans[$k]] = $r;
43
+        }
44
+    }
45 45
 
46
-	$letexte = strtr($letexte, $trans);
46
+    $letexte = strtr($letexte, $trans);
47 47
 
48
-	$cherche1 = [
49
-		/* 1 */
50
-		'/((?:^|[^\#0-9a-zA-Z\&])[\#0-9a-zA-Z]*)\;/S',
51
-		/* 2 */
52
-		'/&#187;| --?,|(?::(?!:)| %)(?:\W|$)/S',
53
-		/* 3 */
54
-		'/([^[<(!?.])([!?][!?\.]*)/iS',
55
-		/* 4 */
56
-		'/&#171;|(?:M(?:M?\.|mes?|r\.?)|[MnN]&#176;) /S'
57
-	];
58
-	$remplace1 = [
59
-		/* 1 */
60
-		'\1~;',
61
-		/* 2 */
62
-		'~\0',
63
-		/* 3 */
64
-		'\1~\2',
65
-		/* 4 */
66
-		'\0~'
67
-	];
68
-	$letexte = preg_replace($cherche1, $remplace1, $letexte);
69
-	$letexte = preg_replace('/ *~+ */S', '~', $letexte);
48
+    $cherche1 = [
49
+        /* 1 */
50
+        '/((?:^|[^\#0-9a-zA-Z\&])[\#0-9a-zA-Z]*)\;/S',
51
+        /* 2 */
52
+        '/&#187;| --?,|(?::(?!:)| %)(?:\W|$)/S',
53
+        /* 3 */
54
+        '/([^[<(!?.])([!?][!?\.]*)/iS',
55
+        /* 4 */
56
+        '/&#171;|(?:M(?:M?\.|mes?|r\.?)|[MnN]&#176;) /S'
57
+    ];
58
+    $remplace1 = [
59
+        /* 1 */
60
+        '\1~;',
61
+        /* 2 */
62
+        '~\0',
63
+        /* 3 */
64
+        '\1~\2',
65
+        /* 4 */
66
+        '\0~'
67
+    ];
68
+    $letexte = preg_replace($cherche1, $remplace1, $letexte);
69
+    $letexte = preg_replace('/ *~+ */S', '~', $letexte);
70 70
 
71
-	$cherche2 = [
72
-		'/([^-\n]|^)--([^-]|$)/S',
73
-		',(' . _PROTOCOLES_STD . ')~((://[^"\'\s\[\]\}\)<>]+)~([?]))?,S',
74
-		'/~/'
75
-	];
76
-	$remplace2 = [
77
-		'\1&mdash;\2',
78
-		'\1\3\4',
79
-		'&nbsp;'
80
-	];
81
-	$letexte = preg_replace($cherche2, $remplace2, $letexte);
71
+    $cherche2 = [
72
+        '/([^-\n]|^)--([^-]|$)/S',
73
+        ',(' . _PROTOCOLES_STD . ')~((://[^"\'\s\[\]\}\)<>]+)~([?]))?,S',
74
+        '/~/'
75
+    ];
76
+    $remplace2 = [
77
+        '\1&mdash;\2',
78
+        '\1\3\4',
79
+        '&nbsp;'
80
+    ];
81
+    $letexte = preg_replace($cherche2, $remplace2, $letexte);
82 82
 
83
-	return $letexte;
83
+    return $letexte;
84 84
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -70,7 +70,7 @@
 block discarded – undo
70 70
 
71 71
 	$cherche2 = [
72 72
 		'/([^-\n]|^)--([^-]|$)/S',
73
-		',(' . _PROTOCOLES_STD . ')~((://[^"\'\s\[\]\}\)<>]+)~([?]))?,S',
73
+		',('._PROTOCOLES_STD.')~((://[^"\'\s\[\]\}\)<>]+)~([?]))?,S',
74 74
 		'/~/'
75 75
 	];
76 76
 	$remplace2 = [
Please login to merge, or discard this patch.
ecrire/typographie/en.php 1 patch
Indentation   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -11,37 +11,37 @@
 block discarded – undo
11 11
 \***************************************************************************/
12 12
 
13 13
 if (!defined('_ECRIRE_INC_VERSION')) {
14
-	return;
14
+    return;
15 15
 }
16 16
 
17 17
 // rien sauf les "~" et "-,"
18 18
 
19 19
 function typographie_en_dist($letexte) {
20 20
 
21
-	// zouli apostrophe
22
-	$letexte = str_replace("'", '&#8217;', $letexte);
21
+    // zouli apostrophe
22
+    $letexte = str_replace("'", '&#8217;', $letexte);
23 23
 
24
-	$cherche1 = [
25
-		'/ --?,/S'
26
-	];
27
-	$remplace1 = [
28
-		'~\0'
29
-	];
30
-	$letexte = preg_replace($cherche1, $remplace1, $letexte);
24
+    $cherche1 = [
25
+        '/ --?,/S'
26
+    ];
27
+    $remplace1 = [
28
+        '~\0'
29
+    ];
30
+    $letexte = preg_replace($cherche1, $remplace1, $letexte);
31 31
 
32
-	$letexte = str_replace('&nbsp;', '~', $letexte);
33
-	$letexte = preg_replace('/ *~+ */', '~', $letexte);
32
+    $letexte = str_replace('&nbsp;', '~', $letexte);
33
+    $letexte = preg_replace('/ *~+ */', '~', $letexte);
34 34
 
35
-	$cherche2 = [
36
-		'/([^-\n]|^)--([^-]|$)/',
37
-		'/~/'
38
-	];
39
-	$remplace2 = [
40
-		'\1&mdash;\2',
41
-		'&nbsp;'
42
-	];
35
+    $cherche2 = [
36
+        '/([^-\n]|^)--([^-]|$)/',
37
+        '/~/'
38
+    ];
39
+    $remplace2 = [
40
+        '\1&mdash;\2',
41
+        '&nbsp;'
42
+    ];
43 43
 
44
-	$letexte = preg_replace($cherche2, $remplace2, $letexte);
44
+    $letexte = preg_replace($cherche2, $remplace2, $letexte);
45 45
 
46
-	return $letexte;
46
+    return $letexte;
47 47
 }
Please login to merge, or discard this patch.
ecrire/public/jointures.php 2 patches
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -177,14 +177,14 @@  discard block
 block discarded – undo
177 177
 			// sache qu'il peut enlever ce where si il enleve la jointure
178 178
 			$boucle->where["JOIN-L$n"] =
179 179
 				$echap ?
180
-					["'='","'$obj'","sql_quote('$type')"]
180
+					["'='", "'$obj'", "sql_quote('$type')"]
181 181
 					:
182
-					['=',"$obj",sql_quote($type)];
182
+					['=', "$obj", sql_quote($type)];
183 183
 			$boucle->join["L$n"] =
184 184
 				$echap ?
185 185
 					["'$id_table'", "'$j2'", "'$j1'", "'$obj='.sql_quote('$type')"]
186 186
 					:
187
-					[$id_table, $j2, $j1, "$obj=" . sql_quote($type)];
187
+					[$id_table, $j2, $j1, "$obj=".sql_quote($type)];
188 188
 		} else {
189 189
 			$boucle->join["L$n"] = $echap ? ["'$id_table'", "'$j'"] : [$id_table, $j];
190 190
 		}
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
 	$groups = liste_champs_jointures($nom, $desc, true);
219 219
 	if (!$pk) {
220 220
 		foreach ($groups as $id_prim) {
221
-			$id_field = $nom . '.' . $id_prim;
221
+			$id_field = $nom.'.'.$id_prim;
222 222
 			if (!in_array($id_field, $boucle->group)) {
223 223
 				$boucle->group[] = $id_field;
224 224
 			}
Please login to merge, or discard this patch.
Indentation   +401 added lines, -401 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 ['id_objet', 'objet', objet_type($champ)];
38
-	}
36
+    if (($champ !== 'id_objet') and preg_match(',^id_([a-z_]+)$,', $champ, $regs)) {
37
+        return ['id_objet', 'objet', objet_type($champ)];
38
+    }
39 39
 
40
-	return $champ;
40
+    return $champ;
41 41
 }
42 42
 
43 43
 /**
@@ -56,21 +56,21 @@  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 (
60
-		!is_array($desc) // on ne se risque pas en conjectures si on ne connait pas la table
61
-		or array_key_exists($champ, $desc['field'])
62
-	) {
63
-		return [$champ];
64
-	}
65
-	// si le champ se décompose, tester que les colonnes décomposées sont présentes
66
-	if (is_array($decompose = decompose_champ_id_objet($champ))) {
67
-		array_pop($decompose);
68
-		if (count(array_intersect($decompose, array_keys($desc['field']))) == count($decompose)) {
69
-			return $decompose;
70
-		}
71
-	}
72
-
73
-	return [$champ];
59
+    if (
60
+        !is_array($desc) // on ne se risque pas en conjectures si on ne connait pas la table
61
+        or array_key_exists($champ, $desc['field'])
62
+    ) {
63
+        return [$champ];
64
+    }
65
+    // si le champ se décompose, tester que les colonnes décomposées sont présentes
66
+    if (is_array($decompose = decompose_champ_id_objet($champ))) {
67
+        array_pop($decompose);
68
+        if (count(array_intersect($decompose, array_keys($desc['field']))) == count($decompose)) {
69
+            return $decompose;
70
+        }
71
+    }
72
+
73
+    return [$champ];
74 74
 }
75 75
 
76 76
 
@@ -100,23 +100,23 @@  discard block
 block discarded – undo
100 100
  *     Alias de la table de jointure (Lx)
101 101
  */
102 102
 function calculer_jointure(&$boucle, $depart, $arrivee, $col = '', $cond = false, $max_liens = 5) {
103
-	// les jointures minimales sont optimales :
104
-	// on contraint le nombre d'etapes en l'augmentant
105
-	// jusqu'a ce qu'on trouve une jointure ou qu'on atteigne la limite maxi
106
-	$max = 1;
107
-	$res = false;
108
-	$milieu_exclus = ($col ?: []);
109
-	while ($max <= $max_liens and !$res) {
110
-		$res = calculer_chaine_jointures($boucle, $depart, $arrivee, [], $milieu_exclus, $max);
111
-		$max++;
112
-	}
113
-	if (!$res) {
114
-		return '';
115
-	}
116
-
117
-	[$nom, $desc] = $depart;
118
-
119
-	return fabrique_jointures($boucle, $res, $cond, $desc, $nom, $col);
103
+    // les jointures minimales sont optimales :
104
+    // on contraint le nombre d'etapes en l'augmentant
105
+    // jusqu'a ce qu'on trouve une jointure ou qu'on atteigne la limite maxi
106
+    $max = 1;
107
+    $res = false;
108
+    $milieu_exclus = ($col ?: []);
109
+    while ($max <= $max_liens and !$res) {
110
+        $res = calculer_chaine_jointures($boucle, $depart, $arrivee, [], $milieu_exclus, $max);
111
+        $max++;
112
+    }
113
+    if (!$res) {
114
+        return '';
115
+    }
116
+
117
+    [$nom, $desc] = $depart;
118
+
119
+    return fabrique_jointures($boucle, $res, $cond, $desc, $nom, $col);
120 120
 }
121 121
 
122 122
 /**
@@ -155,82 +155,82 @@  discard block
 block discarded – undo
155 155
  *     Alias de la table de jointure (Lx)
156 156
  */
157 157
 function fabrique_jointures(&$boucle, $res, $cond = false, $desc = [], $nom = '', $col = '', $echap = true) {
158
-	$a = [];
159
-	$j = null;
160
-	$n = null;
161
-	static $num = [];
162
-	$id_table = '';
163
-	$cpt = &$num[$boucle->descr['nom']][$boucle->descr['gram']][$boucle->id_boucle];
164
-	foreach ($res as $cle => $r) {
165
-		[$d, $a, $j] = $r;
166
-		if (!$id_table) {
167
-			$id_table = $d;
168
-		}
169
-		$n = ++$cpt;
170
-		if (is_array($j)) { // c'est un lien sur un champ du type id_objet,objet,'article'
171
-			[$j1, $j2, $obj, $type] = $j;
172
-			// trouver de quel cote est (id_objet,objet)
173
-			if ($j1 == "id_$obj") {
174
-				$obj = "$id_table.$obj";
175
-			} else {
176
-				$obj = "L$n.$obj";
177
-			}
178
-			// le where complementaire est envoye dans la jointure et dans le where
179
-			// on utilise une clé qui le relie a la jointure pour que l'optimiseur
180
-			// sache qu'il peut enlever ce where si il enleve la jointure
181
-			$boucle->where["JOIN-L$n"] =
182
-				$echap ?
183
-					["'='","'$obj'","sql_quote('$type')"]
184
-					:
185
-					['=',"$obj",sql_quote($type)];
186
-			$boucle->join["L$n"] =
187
-				$echap ?
188
-					["'$id_table'", "'$j2'", "'$j1'", "'$obj='.sql_quote('$type')"]
189
-					:
190
-					[$id_table, $j2, $j1, "$obj=" . sql_quote($type)];
191
-		} else {
192
-			$boucle->join["L$n"] = $echap ? ["'$id_table'", "'$j'"] : [$id_table, $j];
193
-		}
194
-		$boucle->from[$id_table = "L$n"] = $a[0];
195
-	}
196
-
197
-
198
-	// pas besoin de group by
199
-	// (cf http://article.gmane.org/gmane.comp.web.spip.devel/30555)
200
-	// si une seule jointure et sur une table avec primary key formee
201
-	// de l'index principal et de l'index de jointure (non conditionnel! [6031])
202
-	// et operateur d'egalite (https://core.spip.net/issues/477)
203
-
204
-	if ($pk = (isset($a[1]) && (count($boucle->from) == 2) && !$cond)) {
205
-		$pk = nogroupby_if($desc, $a[1], $col);
206
-	}
207
-
208
-	// pas de group by
209
-	// si une seule jointure
210
-	// et si l'index de jointure est une primary key a l'arrivee !
211
-	if (
212
-		!$pk
213
-		and (count($boucle->from) == 2)
214
-		and isset($a[1]['key']['PRIMARY KEY'])
215
-		and ($j == $a[1]['key']['PRIMARY KEY'])
216
-	) {
217
-		$pk = true;
218
-	}
219
-
220
-	// la clause Group by est en conflit avec ORDER BY, a completer
221
-	$groups = liste_champs_jointures($nom, $desc, true);
222
-	if (!$pk) {
223
-		foreach ($groups as $id_prim) {
224
-			$id_field = $nom . '.' . $id_prim;
225
-			if (!in_array($id_field, $boucle->group)) {
226
-				$boucle->group[] = $id_field;
227
-			}
228
-		}
229
-	}
230
-
231
-	$boucle->modificateur['lien'] = true;
232
-
233
-	return "L$n";
158
+    $a = [];
159
+    $j = null;
160
+    $n = null;
161
+    static $num = [];
162
+    $id_table = '';
163
+    $cpt = &$num[$boucle->descr['nom']][$boucle->descr['gram']][$boucle->id_boucle];
164
+    foreach ($res as $cle => $r) {
165
+        [$d, $a, $j] = $r;
166
+        if (!$id_table) {
167
+            $id_table = $d;
168
+        }
169
+        $n = ++$cpt;
170
+        if (is_array($j)) { // c'est un lien sur un champ du type id_objet,objet,'article'
171
+            [$j1, $j2, $obj, $type] = $j;
172
+            // trouver de quel cote est (id_objet,objet)
173
+            if ($j1 == "id_$obj") {
174
+                $obj = "$id_table.$obj";
175
+            } else {
176
+                $obj = "L$n.$obj";
177
+            }
178
+            // le where complementaire est envoye dans la jointure et dans le where
179
+            // on utilise une clé qui le relie a la jointure pour que l'optimiseur
180
+            // sache qu'il peut enlever ce where si il enleve la jointure
181
+            $boucle->where["JOIN-L$n"] =
182
+                $echap ?
183
+                    ["'='","'$obj'","sql_quote('$type')"]
184
+                    :
185
+                    ['=',"$obj",sql_quote($type)];
186
+            $boucle->join["L$n"] =
187
+                $echap ?
188
+                    ["'$id_table'", "'$j2'", "'$j1'", "'$obj='.sql_quote('$type')"]
189
+                    :
190
+                    [$id_table, $j2, $j1, "$obj=" . sql_quote($type)];
191
+        } else {
192
+            $boucle->join["L$n"] = $echap ? ["'$id_table'", "'$j'"] : [$id_table, $j];
193
+        }
194
+        $boucle->from[$id_table = "L$n"] = $a[0];
195
+    }
196
+
197
+
198
+    // pas besoin de group by
199
+    // (cf http://article.gmane.org/gmane.comp.web.spip.devel/30555)
200
+    // si une seule jointure et sur une table avec primary key formee
201
+    // de l'index principal et de l'index de jointure (non conditionnel! [6031])
202
+    // et operateur d'egalite (https://core.spip.net/issues/477)
203
+
204
+    if ($pk = (isset($a[1]) && (count($boucle->from) == 2) && !$cond)) {
205
+        $pk = nogroupby_if($desc, $a[1], $col);
206
+    }
207
+
208
+    // pas de group by
209
+    // si une seule jointure
210
+    // et si l'index de jointure est une primary key a l'arrivee !
211
+    if (
212
+        !$pk
213
+        and (count($boucle->from) == 2)
214
+        and isset($a[1]['key']['PRIMARY KEY'])
215
+        and ($j == $a[1]['key']['PRIMARY KEY'])
216
+    ) {
217
+        $pk = true;
218
+    }
219
+
220
+    // la clause Group by est en conflit avec ORDER BY, a completer
221
+    $groups = liste_champs_jointures($nom, $desc, true);
222
+    if (!$pk) {
223
+        foreach ($groups as $id_prim) {
224
+            $id_field = $nom . '.' . $id_prim;
225
+            if (!in_array($id_field, $boucle->group)) {
226
+                $boucle->group[] = $id_field;
227
+            }
228
+        }
229
+    }
230
+
231
+    $boucle->modificateur['lien'] = true;
232
+
233
+    return "L$n";
234 234
 }
235 235
 
236 236
 /**
@@ -245,19 +245,19 @@  discard block
 block discarded – undo
245 245
  * @return bool
246 246
  */
247 247
 function nogroupby_if($depart, $arrivee, $col) {
248
-	if (
249
-		empty($arrivee['key']['PRIMARY KEY'])
250
-		or !($pk = $arrivee['key']['PRIMARY KEY'])
251
-		or empty($depart['key']['PRIMARY KEY'])
252
-	) {
253
-		return false;
254
-	}
255
-	$id_primary = $depart['key']['PRIMARY KEY'];
256
-	if (is_array($col)) {
257
-		$col = implode(', *', $col);
258
-	} // cas id_objet, objet
259
-	return (preg_match("/^$id_primary, *$col$/", $pk) or
260
-		preg_match("/^$col, *$id_primary$/", $pk));
248
+    if (
249
+        empty($arrivee['key']['PRIMARY KEY'])
250
+        or !($pk = $arrivee['key']['PRIMARY KEY'])
251
+        or empty($depart['key']['PRIMARY KEY'])
252
+    ) {
253
+        return false;
254
+    }
255
+    $id_primary = $depart['key']['PRIMARY KEY'];
256
+    if (is_array($col)) {
257
+        $col = implode(', *', $col);
258
+    } // cas id_objet, objet
259
+    return (preg_match("/^$id_primary, *$col$/", $pk) or
260
+        preg_match("/^$col, *$id_primary$/", $pk));
261 261
 }
262 262
 
263 263
 /**
@@ -275,46 +275,46 @@  discard block
 block discarded – undo
275 275
  */
276 276
 function liste_champs_jointures($nom, $desc, $primary = false) {
277 277
 
278
-	static $nojoin = ['idx', 'maj', 'date', 'statut'];
278
+    static $nojoin = ['idx', 'maj', 'date', 'statut'];
279 279
 
280
-	// si cle primaire demandee, la privilegier
281
-	if ($primary && isset($desc['key']['PRIMARY KEY'])) {
282
-		return split_key($desc['key']['PRIMARY KEY']);
283
-	}
280
+    // si cle primaire demandee, la privilegier
281
+    if ($primary && isset($desc['key']['PRIMARY KEY'])) {
282
+        return split_key($desc['key']['PRIMARY KEY']);
283
+    }
284 284
 
285
-	// les champs declares explicitement pour les jointures
286
-	if (isset($desc['join'])) {
287
-		return $desc['join'];
288
-	}
289
-	/*elseif (isset($GLOBALS['tables_principales'][$nom]['join'])) return $GLOBALS['tables_principales'][$nom]['join'];
285
+    // les champs declares explicitement pour les jointures
286
+    if (isset($desc['join'])) {
287
+        return $desc['join'];
288
+    }
289
+    /*elseif (isset($GLOBALS['tables_principales'][$nom]['join'])) return $GLOBALS['tables_principales'][$nom]['join'];
290 290
 	elseif (isset($GLOBALS['tables_auxiliaires'][$nom]['join'])) return $GLOBALS['tables_auxiliaires'][$nom]['join'];*/
291 291
 
292
-	// si pas de cle, c'est fichu
293
-	if (!isset($desc['key'])) {
294
-		return [];
295
-	}
296
-
297
-	// si cle primaire
298
-	if (isset($desc['key']['PRIMARY KEY'])) {
299
-		return split_key($desc['key']['PRIMARY KEY']);
300
-	}
301
-
302
-	// ici on se rabat sur les cles secondaires,
303
-	// en eliminant celles qui sont pas pertinentes (idx, maj)
304
-	// si jamais le resultat n'est pas pertinent pour une table donnee,
305
-	// il faut declarer explicitement le champ 'join' de sa description
306
-
307
-	$join = [];
308
-	foreach ($desc['key'] as $v) {
309
-		$join = split_key($v, $join);
310
-	}
311
-	foreach ($join as $k) {
312
-		if (in_array($k, $nojoin)) {
313
-			unset($join[$k]);
314
-		}
315
-	}
316
-
317
-	return $join;
292
+    // si pas de cle, c'est fichu
293
+    if (!isset($desc['key'])) {
294
+        return [];
295
+    }
296
+
297
+    // si cle primaire
298
+    if (isset($desc['key']['PRIMARY KEY'])) {
299
+        return split_key($desc['key']['PRIMARY KEY']);
300
+    }
301
+
302
+    // ici on se rabat sur les cles secondaires,
303
+    // en eliminant celles qui sont pas pertinentes (idx, maj)
304
+    // si jamais le resultat n'est pas pertinent pour une table donnee,
305
+    // il faut declarer explicitement le champ 'join' de sa description
306
+
307
+    $join = [];
308
+    foreach ($desc['key'] as $v) {
309
+        $join = split_key($v, $join);
310
+    }
311
+    foreach ($join as $k) {
312
+        if (in_array($k, $nojoin)) {
313
+            unset($join[$k]);
314
+        }
315
+    }
316
+
317
+    return $join;
318 318
 }
319 319
 
320 320
 /**
@@ -325,14 +325,14 @@  discard block
 block discarded – undo
325 325
  * @return array
326 326
  */
327 327
 function split_key($v, $join = []) {
328
-	foreach (preg_split('/,\s*/', $v) as $k) {
329
-		if (strpos($k, '(') !== false) {
330
-			$k = explode('(', $k);
331
-			$k = trim(reset($k));
332
-		}
333
-		$join[$k] = $k;
334
-	}
335
-	return $join;
328
+    foreach (preg_split('/,\s*/', $v) as $k) {
329
+        if (strpos($k, '(') !== false) {
330
+            $k = explode('(', $k);
331
+            $k = trim(reset($k));
332
+        }
333
+        $join[$k] = $k;
334
+    }
335
+    return $join;
336 336
 }
337 337
 
338 338
 /**
@@ -355,135 +355,135 @@  discard block
 block discarded – undo
355 355
  * @return array
356 356
  */
357 357
 function calculer_chaine_jointures(
358
-	&$boucle,
359
-	$depart,
360
-	$arrivee,
361
-	$vu = [],
362
-	$milieu_exclus = [],
363
-	$max_liens = 5
358
+    &$boucle,
359
+    $depart,
360
+    $arrivee,
361
+    $vu = [],
362
+    $milieu_exclus = [],
363
+    $max_liens = 5
364 364
 ) {
365
-	static $trouver_table;
366
-	if (!$trouver_table) {
367
-		$trouver_table = charger_fonction('trouver_table', 'base');
368
-	}
369
-
370
-	if (is_string($milieu_exclus)) {
371
-		$milieu_exclus = [$milieu_exclus];
372
-	}
373
-	// quand on a exclus id_objet comme cle de jointure, il faut aussi exclure objet
374
-	// faire une jointure sur objet tout seul n'a pas de sens
375
-	if (in_array('id_objet', $milieu_exclus) and !in_array('objet', $milieu_exclus)) {
376
-		$milieu_exclus[] = 'objet';
377
-	}
378
-
379
-	[$dnom, $ddesc] = $depart;
380
-	[$anom, $adesc] = $arrivee;
381
-	if (!count($vu)) {
382
-		$vu[] = $dnom; // ne pas oublier la table de depart
383
-		$vu[] = $anom; // ne pas oublier la table d'arrivee
384
-	}
385
-
386
-	$akeys = [];
387
-	foreach ($adesc['key'] as $k) {
388
-		// respecter l'ordre de $adesc['key'] pour ne pas avoir id_trad en premier entre autres...
389
-		$akeys = array_merge($akeys, preg_split('/,\s*/', $k));
390
-	}
391
-
392
-	// enlever les cles d'arrivee exclues par l'appel
393
-	$akeys = array_diff($akeys, $milieu_exclus);
394
-
395
-	// cles candidates au depart
396
-	$keys = liste_champs_jointures($dnom, $ddesc);
397
-	// enlever les cles dde depart exclues par l'appel
398
-	$keys = array_diff($keys, $milieu_exclus);
399
-
400
-	$v = !$keys ? false : array_intersect(array_values($keys), $akeys);
401
-
402
-	if ($v) {
403
-		return [[$dnom, [$adesc['table'], $adesc], array_shift($v)]];
404
-	}
405
-
406
-	// regarder si l'on a (id_objet,objet) au depart et si on peut le mapper sur un id_xx
407
-	if (count(array_intersect(['id_objet', 'objet'], $keys)) == 2) {
408
-		// regarder si l'une des cles d'arrivee peut se decomposer en
409
-		// id_objet,objet
410
-		// si oui on la prend
411
-		foreach ($akeys as $key) {
412
-			$v = decompose_champ_id_objet($key);
413
-			if (is_array($v)) {
414
-				$objet = array_shift($v); // objet,'article'
415
-				array_unshift($v, $key); // id_article,objet,'article'
416
-				array_unshift($v, $objet); // id_objet,id_article,objet,'article'
417
-				return [[$dnom, [$adesc['table'], $adesc], $v]];
418
-			}
419
-		}
420
-	} else {
421
-		// regarder si l'une des cles de depart peut se decomposer en
422
-		// id_objet,objet a l'arrivee
423
-		// si oui on la prend
424
-		foreach ($keys as $key) {
425
-			if (count($v = trouver_champs_decomposes($key, $adesc)) > 1) {
426
-				if (count($v) == count(array_intersect($v, $akeys))) {
427
-					$v = decompose_champ_id_objet($key); // id_objet,objet,'article'
428
-					array_unshift($v, $key); // id_article,id_objet,objet,'article'
429
-					return [[$dnom, [$adesc['table'], $adesc], $v]];
430
-				}
431
-			}
432
-		}
433
-	}
434
-	// si l'on voulait une jointure direct, c'est rate !
435
-	if ($max_liens <= 1) {
436
-		return [];
437
-	}
438
-
439
-	// sinon essayer de passer par une autre table
440
-	$new = $vu;
441
-	foreach ($boucle->jointures as $v) {
442
-		if (
443
-			$v
444
-			and !in_array($v, $vu)
445
-			and $def = $trouver_table($v, $boucle->sql_serveur)
446
-			and !in_array($def['table_sql'], $vu)
447
-		) {
448
-			// ne pas tester les cles qui sont exclues a l'appel
449
-			// ie la cle de la jointure precedente
450
-			$test_cles = $milieu_exclus;
451
-			$new[] = $v;
452
-			$max_iter = 50; // securite
453
-			while (
454
-				count($jointure_directe_possible = calculer_chaine_jointures(
455
-					$boucle,
456
-					$depart,
457
-					[$v, $def],
458
-					$vu,
459
-					$test_cles,
460
-					1
461
-				))
462
-				and $max_iter--
463
-			) {
464
-				$jointure_directe_possible = reset($jointure_directe_possible);
465
-				$milieu = end($jointure_directe_possible);
466
-				$exclure_fin = $milieu_exclus;
467
-				if (is_string($milieu)) {
468
-					$exclure_fin[] = $milieu;
469
-					$test_cles[] = $milieu;
470
-				} else {
471
-					$exclure_fin = array_merge($exclure_fin, $milieu);
472
-					$test_cles = array_merge($test_cles, $milieu);
473
-				}
474
-				// essayer de rejoindre l'arrivee a partir de cette etape intermediaire
475
-				// sans repasser par la meme cle milieu, ni une cle deja vue !
476
-				$r = calculer_chaine_jointures($boucle, [$v, $def], $arrivee, $new, $exclure_fin, $max_liens - 1);
477
-				if ($r) {
478
-					array_unshift($r, $jointure_directe_possible);
479
-
480
-					return $r;
481
-				}
482
-			}
483
-		}
484
-	}
485
-
486
-	return [];
365
+    static $trouver_table;
366
+    if (!$trouver_table) {
367
+        $trouver_table = charger_fonction('trouver_table', 'base');
368
+    }
369
+
370
+    if (is_string($milieu_exclus)) {
371
+        $milieu_exclus = [$milieu_exclus];
372
+    }
373
+    // quand on a exclus id_objet comme cle de jointure, il faut aussi exclure objet
374
+    // faire une jointure sur objet tout seul n'a pas de sens
375
+    if (in_array('id_objet', $milieu_exclus) and !in_array('objet', $milieu_exclus)) {
376
+        $milieu_exclus[] = 'objet';
377
+    }
378
+
379
+    [$dnom, $ddesc] = $depart;
380
+    [$anom, $adesc] = $arrivee;
381
+    if (!count($vu)) {
382
+        $vu[] = $dnom; // ne pas oublier la table de depart
383
+        $vu[] = $anom; // ne pas oublier la table d'arrivee
384
+    }
385
+
386
+    $akeys = [];
387
+    foreach ($adesc['key'] as $k) {
388
+        // respecter l'ordre de $adesc['key'] pour ne pas avoir id_trad en premier entre autres...
389
+        $akeys = array_merge($akeys, preg_split('/,\s*/', $k));
390
+    }
391
+
392
+    // enlever les cles d'arrivee exclues par l'appel
393
+    $akeys = array_diff($akeys, $milieu_exclus);
394
+
395
+    // cles candidates au depart
396
+    $keys = liste_champs_jointures($dnom, $ddesc);
397
+    // enlever les cles dde depart exclues par l'appel
398
+    $keys = array_diff($keys, $milieu_exclus);
399
+
400
+    $v = !$keys ? false : array_intersect(array_values($keys), $akeys);
401
+
402
+    if ($v) {
403
+        return [[$dnom, [$adesc['table'], $adesc], array_shift($v)]];
404
+    }
405
+
406
+    // regarder si l'on a (id_objet,objet) au depart et si on peut le mapper sur un id_xx
407
+    if (count(array_intersect(['id_objet', 'objet'], $keys)) == 2) {
408
+        // regarder si l'une des cles d'arrivee peut se decomposer en
409
+        // id_objet,objet
410
+        // si oui on la prend
411
+        foreach ($akeys as $key) {
412
+            $v = decompose_champ_id_objet($key);
413
+            if (is_array($v)) {
414
+                $objet = array_shift($v); // objet,'article'
415
+                array_unshift($v, $key); // id_article,objet,'article'
416
+                array_unshift($v, $objet); // id_objet,id_article,objet,'article'
417
+                return [[$dnom, [$adesc['table'], $adesc], $v]];
418
+            }
419
+        }
420
+    } else {
421
+        // regarder si l'une des cles de depart peut se decomposer en
422
+        // id_objet,objet a l'arrivee
423
+        // si oui on la prend
424
+        foreach ($keys as $key) {
425
+            if (count($v = trouver_champs_decomposes($key, $adesc)) > 1) {
426
+                if (count($v) == count(array_intersect($v, $akeys))) {
427
+                    $v = decompose_champ_id_objet($key); // id_objet,objet,'article'
428
+                    array_unshift($v, $key); // id_article,id_objet,objet,'article'
429
+                    return [[$dnom, [$adesc['table'], $adesc], $v]];
430
+                }
431
+            }
432
+        }
433
+    }
434
+    // si l'on voulait une jointure direct, c'est rate !
435
+    if ($max_liens <= 1) {
436
+        return [];
437
+    }
438
+
439
+    // sinon essayer de passer par une autre table
440
+    $new = $vu;
441
+    foreach ($boucle->jointures as $v) {
442
+        if (
443
+            $v
444
+            and !in_array($v, $vu)
445
+            and $def = $trouver_table($v, $boucle->sql_serveur)
446
+            and !in_array($def['table_sql'], $vu)
447
+        ) {
448
+            // ne pas tester les cles qui sont exclues a l'appel
449
+            // ie la cle de la jointure precedente
450
+            $test_cles = $milieu_exclus;
451
+            $new[] = $v;
452
+            $max_iter = 50; // securite
453
+            while (
454
+                count($jointure_directe_possible = calculer_chaine_jointures(
455
+                    $boucle,
456
+                    $depart,
457
+                    [$v, $def],
458
+                    $vu,
459
+                    $test_cles,
460
+                    1
461
+                ))
462
+                and $max_iter--
463
+            ) {
464
+                $jointure_directe_possible = reset($jointure_directe_possible);
465
+                $milieu = end($jointure_directe_possible);
466
+                $exclure_fin = $milieu_exclus;
467
+                if (is_string($milieu)) {
468
+                    $exclure_fin[] = $milieu;
469
+                    $test_cles[] = $milieu;
470
+                } else {
471
+                    $exclure_fin = array_merge($exclure_fin, $milieu);
472
+                    $test_cles = array_merge($test_cles, $milieu);
473
+                }
474
+                // essayer de rejoindre l'arrivee a partir de cette etape intermediaire
475
+                // sans repasser par la meme cle milieu, ni une cle deja vue !
476
+                $r = calculer_chaine_jointures($boucle, [$v, $def], $arrivee, $new, $exclure_fin, $max_liens - 1);
477
+                if ($r) {
478
+                    array_unshift($r, $jointure_directe_possible);
479
+
480
+                    return $r;
481
+                }
482
+            }
483
+        }
484
+    }
485
+
486
+    return [];
487 487
 }
488 488
 
489 489
 /**
@@ -494,18 +494,18 @@  discard block
 block discarded – undo
494 494
  * @return array
495 495
  */
496 496
 function trouver_cles_table($keys) {
497
-	$res = [];
498
-	foreach ($keys as $v) {
499
-		if (!strpos($v, ',')) {
500
-			$res[$v] = 1;
501
-		} else {
502
-			foreach (preg_split('/\s*,\s*/', $v) as $k) {
503
-				$res[$k] = 1;
504
-			}
505
-		}
506
-	}
507
-
508
-	return array_keys($res);
497
+    $res = [];
498
+    foreach ($keys as $v) {
499
+        if (!strpos($v, ',')) {
500
+            $res[$v] = 1;
501
+        } else {
502
+            foreach (preg_split('/\s*,\s*/', $v) as $k) {
503
+                $res[$k] = 1;
504
+            }
505
+        }
506
+    }
507
+
508
+    return array_keys($res);
509 509
 }
510 510
 
511 511
 
@@ -532,34 +532,34 @@  discard block
 block discarded – undo
532 532
  *     - 'alias' : alias utilisé pour la table (si pertinent. ie: avec `$boucle->from` transmis par exemple)
533 533
  */
534 534
 function chercher_champ_dans_tables($cle, $tables, $connect, $checkarrivee = false) {
535
-	static $trouver_table = '';
536
-	if (!$trouver_table) {
537
-		$trouver_table = charger_fonction('trouver_table', 'base');
538
-	}
539
-
540
-	if (!is_array($cle)) {
541
-		$cle = [$cle];
542
-	}
543
-
544
-	foreach ($tables as $k => $table) {
545
-		if ($table && $desc = $trouver_table($table, $connect)) {
546
-			if (
547
-				isset($desc['field'])
548
-				// verifier que toutes les cles cherchees sont la
549
-				and (count(array_intersect($cle, array_keys($desc['field']))) == count($cle))
550
-				// si on sait ou on veut arriver, il faut que ca colle
551
-				and ($checkarrivee == false || $checkarrivee == $desc['table'])
552
-			) {
553
-				return [
554
-					'desc' => $desc,
555
-					'table' => $desc['table'],
556
-					'alias' => $k,
557
-				];
558
-			}
559
-		}
560
-	}
561
-
562
-	return false;
535
+    static $trouver_table = '';
536
+    if (!$trouver_table) {
537
+        $trouver_table = charger_fonction('trouver_table', 'base');
538
+    }
539
+
540
+    if (!is_array($cle)) {
541
+        $cle = [$cle];
542
+    }
543
+
544
+    foreach ($tables as $k => $table) {
545
+        if ($table && $desc = $trouver_table($table, $connect)) {
546
+            if (
547
+                isset($desc['field'])
548
+                // verifier que toutes les cles cherchees sont la
549
+                and (count(array_intersect($cle, array_keys($desc['field']))) == count($cle))
550
+                // si on sait ou on veut arriver, il faut que ca colle
551
+                and ($checkarrivee == false || $checkarrivee == $desc['table'])
552
+            ) {
553
+                return [
554
+                    'desc' => $desc,
555
+                    'table' => $desc['table'],
556
+                    'alias' => $k,
557
+                ];
558
+            }
559
+        }
560
+    }
561
+
562
+    return false;
563 563
 }
564 564
 
565 565
 /**
@@ -585,52 +585,52 @@  discard block
 block discarded – undo
585 585
  */
586 586
 function trouver_champ_exterieur($cle, $joints, &$boucle, $checkarrivee = false) {
587 587
 
588
-	// support de la recherche multi champ :
589
-	// si en seconde etape on a decompose le champ id_xx en id_objet,objet
590
-	// on reentre ici soit en cherchant une table les 2 champs id_objet,objet
591
-	// soit une table avec les 3 champs id_xx, id_objet, objet
592
-	if (!is_array($cle)) {
593
-		$cle = [$cle];
594
-	}
595
-
596
-	if ($infos = chercher_champ_dans_tables($cle, $joints, $boucle->sql_serveur, $checkarrivee)) {
597
-		return [$infos['table'], $infos['desc'], $cle];
598
-	}
599
-
600
-	// au premier coup, on essaye de decomposer, si possible
601
-	if (
602
-		count($cle) == 1
603
-		and $c = reset($cle)
604
-		and is_array($decompose = decompose_champ_id_objet($c))
605
-	) {
606
-		$desc = $boucle->show;
607
-
608
-		// cas 1 : la cle id_xx est dans la table de depart
609
-		// -> on cherche uniquement id_objet,objet a l'arrivee
610
-		if (isset($desc['field'][$c])) {
611
-			$cle = [];
612
-			$cle[] = array_shift($decompose); // id_objet
613
-			$cle[] = array_shift($decompose); // objet
614
-			return trouver_champ_exterieur($cle, $joints, $boucle, $checkarrivee);
615
-		}
616
-		// cas 2 : la cle id_xx n'est pas dans la table de depart
617
-		// -> il faut trouver une cle de depart zzz telle que
618
-		// id_objet,objet,zzz soit a l'arrivee
619
-		else {
620
-			$depart = liste_champs_jointures(($desc['table'] ?? ''), $desc);
621
-			foreach ($depart as $d) {
622
-				$cle = [];
623
-				$cle[] = array_shift($decompose); // id_objet
624
-				$cle[] = array_shift($decompose); // objet
625
-				$cle[] = $d;
626
-				if ($ext = trouver_champ_exterieur($cle, $joints, $boucle, $checkarrivee)) {
627
-					return $ext;
628
-				}
629
-			}
630
-		}
631
-	}
632
-
633
-	return '';
588
+    // support de la recherche multi champ :
589
+    // si en seconde etape on a decompose le champ id_xx en id_objet,objet
590
+    // on reentre ici soit en cherchant une table les 2 champs id_objet,objet
591
+    // soit une table avec les 3 champs id_xx, id_objet, objet
592
+    if (!is_array($cle)) {
593
+        $cle = [$cle];
594
+    }
595
+
596
+    if ($infos = chercher_champ_dans_tables($cle, $joints, $boucle->sql_serveur, $checkarrivee)) {
597
+        return [$infos['table'], $infos['desc'], $cle];
598
+    }
599
+
600
+    // au premier coup, on essaye de decomposer, si possible
601
+    if (
602
+        count($cle) == 1
603
+        and $c = reset($cle)
604
+        and is_array($decompose = decompose_champ_id_objet($c))
605
+    ) {
606
+        $desc = $boucle->show;
607
+
608
+        // cas 1 : la cle id_xx est dans la table de depart
609
+        // -> on cherche uniquement id_objet,objet a l'arrivee
610
+        if (isset($desc['field'][$c])) {
611
+            $cle = [];
612
+            $cle[] = array_shift($decompose); // id_objet
613
+            $cle[] = array_shift($decompose); // objet
614
+            return trouver_champ_exterieur($cle, $joints, $boucle, $checkarrivee);
615
+        }
616
+        // cas 2 : la cle id_xx n'est pas dans la table de depart
617
+        // -> il faut trouver une cle de depart zzz telle que
618
+        // id_objet,objet,zzz soit a l'arrivee
619
+        else {
620
+            $depart = liste_champs_jointures(($desc['table'] ?? ''), $desc);
621
+            foreach ($depart as $d) {
622
+                $cle = [];
623
+                $cle[] = array_shift($decompose); // id_objet
624
+                $cle[] = array_shift($decompose); // objet
625
+                $cle[] = $d;
626
+                if ($ext = trouver_champ_exterieur($cle, $joints, $boucle, $checkarrivee)) {
627
+                    return $ext;
628
+                }
629
+            }
630
+        }
631
+    }
632
+
633
+    return '';
634 634
 }
635 635
 
636 636
 /**
@@ -662,21 +662,21 @@  discard block
 block discarded – undo
662 662
  * @return string
663 663
  */
664 664
 function trouver_jointure_champ($champ, &$boucle, $jointures = false, $cond = false, $checkarrivee = false) {
665
-	if ($jointures === false) {
666
-		$jointures = $boucle->jointures;
667
-	}
668
-	// TODO : aberration, on utilise $jointures pour trouver le champ
669
-	// mais pas poour construire la jointure ensuite
670
-	$arrivee = trouver_champ_exterieur($champ, $jointures, $boucle, $checkarrivee);
671
-	if ($arrivee) {
672
-		$desc = $boucle->show;
673
-		array_pop($arrivee); // enlever la cle en 3eme argument
674
-		$cle = calculer_jointure($boucle, [$desc['id_table'], $desc], $arrivee, '', $cond);
675
-		if ($cle) {
676
-			return $cle;
677
-		}
678
-	}
679
-	spip_log("trouver_jointure_champ: $champ inconnu");
680
-
681
-	return '';
665
+    if ($jointures === false) {
666
+        $jointures = $boucle->jointures;
667
+    }
668
+    // TODO : aberration, on utilise $jointures pour trouver le champ
669
+    // mais pas poour construire la jointure ensuite
670
+    $arrivee = trouver_champ_exterieur($champ, $jointures, $boucle, $checkarrivee);
671
+    if ($arrivee) {
672
+        $desc = $boucle->show;
673
+        array_pop($arrivee); // enlever la cle en 3eme argument
674
+        $cle = calculer_jointure($boucle, [$desc['id_table'], $desc], $arrivee, '', $cond);
675
+        if ($cle) {
676
+            return $cle;
677
+        }
678
+    }
679
+    spip_log("trouver_jointure_champ: $champ inconnu");
680
+
681
+    return '';
682 682
 }
Please login to merge, or discard this patch.
ecrire/public/compiler.php 3 patches
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -920,8 +920,7 @@
 block discarded – undo
920 920
 			if (isset($boucles[$idb]->descr['sourcefile'])) {
921 921
 				$descr['sourcefile'] = $boucles[$idb]->descr['sourcefile'];
922 922
 			}
923
-		}
924
-		else {
923
+		} else {
925 924
 			$descr = [];
926 925
 		}
927 926
 	}
Please login to merge, or discard this patch.
Indentation   +1212 added lines, -1212 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
  **/
22 22
 
23 23
 if (!defined('_ECRIRE_INC_VERSION')) {
24
-	return;
24
+    return;
25 25
 }
26 26
 
27 27
 /** Repérer un code ne calculant rien, meme avec commentaire */
@@ -62,92 +62,92 @@  discard block
 block discarded – undo
62 62
 
63 63
 
64 64
 function argumenter_inclure(
65
-	$params,
66
-	$rejet_filtres,
67
-	$p,
68
-	&$boucles,
69
-	$id_boucle,
70
-	$echap = true,
71
-	$lang = '',
72
-	$fond1 = false
65
+    $params,
66
+    $rejet_filtres,
67
+    $p,
68
+    &$boucles,
69
+    $id_boucle,
70
+    $echap = true,
71
+    $lang = '',
72
+    $fond1 = false
73 73
 ) {
74
-	$l = [];
75
-	$erreur_p_i_i = '';
76
-	if (!is_array($params)) {
77
-		return $l;
78
-	}
79
-	foreach ($params as $k => $couple) {
80
-		// la liste d'arguments d'inclusion peut se terminer par un filtre
81
-		$filtre = array_shift($couple);
82
-		if ($filtre) {
83
-			break;
84
-		}
85
-		foreach ($couple as $n => $val) {
86
-			$var = $val[0];
87
-			if ($var->type != 'texte') {
88
-				if ($n or $k or $fond1) {
89
-					$erreur_p_i_i = [
90
-						'zbug_parametres_inclus_incorrects',
91
-						['param' => $var->nom_champ]
92
-					];
93
-					erreur_squelette($erreur_p_i_i, $p);
94
-					break;
95
-				} else {
96
-					$l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle);
97
-				}
98
-			} else {
99
-				preg_match(',^([^=]*)(=?)(.*)$,m', $var->texte, $m);
100
-				$m = array_pad($m, 3, null);
101
-				$var = $m[1];
102
-				$auto = false;
103
-
104
-				if ($m[2]) {
105
-					$v = $m[3];
106
-					if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) {
107
-						$v = $m[1];
108
-					}
109
-					$val[0] = new Texte();
110
-					$val[0]->texte = $v;
111
-				} elseif ($k or $n or $fond1) {
112
-					$auto = true;
113
-				} else {
114
-					$var = 1;
115
-				}
116
-
117
-				if ($var == 'lang') {
118
-					$lang = !$auto
119
-						? calculer_liste($val, $p->descr, $boucles, $id_boucle)
120
-						: '$GLOBALS["spip_lang"]';
121
-				} else {
122
-					$val = $auto
123
-						? index_pile($id_boucle, $var, $boucles)
124
-						: calculer_liste($val, $p->descr, $boucles, $id_boucle);
125
-					if ($var !== 1) {
126
-						$val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
127
-							. $val . ($echap ? ") . '" : ' ');
128
-					} else {
129
-						$val = $echap ? "'.$val.'" : $val;
130
-					}
131
-					$l[$var] = $val;
132
-				}
133
-			}
134
-		}
135
-	}
136
-	if ($erreur_p_i_i) {
137
-		return false;
138
-	}
139
-	// Cas particulier de la langue : si {lang=xx} est definie, on
140
-	// la passe, sinon on passe la langue courante au moment du calcul
141
-	// sauf si on n'en veut pas
142
-	if ($lang === false) {
143
-		return $l;
144
-	}
145
-	if (!$lang) {
146
-		$lang = '$GLOBALS["spip_lang"]';
147
-	}
148
-	$l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : ' ');
149
-
150
-	return $l;
74
+    $l = [];
75
+    $erreur_p_i_i = '';
76
+    if (!is_array($params)) {
77
+        return $l;
78
+    }
79
+    foreach ($params as $k => $couple) {
80
+        // la liste d'arguments d'inclusion peut se terminer par un filtre
81
+        $filtre = array_shift($couple);
82
+        if ($filtre) {
83
+            break;
84
+        }
85
+        foreach ($couple as $n => $val) {
86
+            $var = $val[0];
87
+            if ($var->type != 'texte') {
88
+                if ($n or $k or $fond1) {
89
+                    $erreur_p_i_i = [
90
+                        'zbug_parametres_inclus_incorrects',
91
+                        ['param' => $var->nom_champ]
92
+                    ];
93
+                    erreur_squelette($erreur_p_i_i, $p);
94
+                    break;
95
+                } else {
96
+                    $l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle);
97
+                }
98
+            } else {
99
+                preg_match(',^([^=]*)(=?)(.*)$,m', $var->texte, $m);
100
+                $m = array_pad($m, 3, null);
101
+                $var = $m[1];
102
+                $auto = false;
103
+
104
+                if ($m[2]) {
105
+                    $v = $m[3];
106
+                    if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) {
107
+                        $v = $m[1];
108
+                    }
109
+                    $val[0] = new Texte();
110
+                    $val[0]->texte = $v;
111
+                } elseif ($k or $n or $fond1) {
112
+                    $auto = true;
113
+                } else {
114
+                    $var = 1;
115
+                }
116
+
117
+                if ($var == 'lang') {
118
+                    $lang = !$auto
119
+                        ? calculer_liste($val, $p->descr, $boucles, $id_boucle)
120
+                        : '$GLOBALS["spip_lang"]';
121
+                } else {
122
+                    $val = $auto
123
+                        ? index_pile($id_boucle, $var, $boucles)
124
+                        : calculer_liste($val, $p->descr, $boucles, $id_boucle);
125
+                    if ($var !== 1) {
126
+                        $val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
127
+                            . $val . ($echap ? ") . '" : ' ');
128
+                    } else {
129
+                        $val = $echap ? "'.$val.'" : $val;
130
+                    }
131
+                    $l[$var] = $val;
132
+                }
133
+            }
134
+        }
135
+    }
136
+    if ($erreur_p_i_i) {
137
+        return false;
138
+    }
139
+    // Cas particulier de la langue : si {lang=xx} est definie, on
140
+    // la passe, sinon on passe la langue courante au moment du calcul
141
+    // sauf si on n'en veut pas
142
+    if ($lang === false) {
143
+        return $l;
144
+    }
145
+    if (!$lang) {
146
+        $lang = '$GLOBALS["spip_lang"]';
147
+    }
148
+    $l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : ' ');
149
+
150
+    return $l;
151 151
 }
152 152
 
153 153
 /**
@@ -171,84 +171,84 @@  discard block
 block discarded – undo
171 171
  **/
172 172
 function calculer_inclure($p, &$boucles, $id_boucle) {
173 173
 
174
-	$_options = [];
175
-	$_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
176
-	if (is_string($p->texte)) {
177
-		$fichier = $p->texte;
178
-		$code = '"' . str_replace('"', '\"', $fichier) . '"';
179
-	} else {
180
-		$code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
181
-		if ($code and preg_match("/^'([^']*)'/s", $code, $r)) {
182
-			$fichier = $r[1];
183
-		} else {
184
-			$fichier = '';
185
-		}
186
-	}
187
-	if (!$code or $code === '""' or $code === "''") {
188
-		$trace = $p->fonctions;
189
-		while (
190
-			is_array($trace)
191
-			and $trace = array_filter($trace)
192
-			and count($trace) == 1
193
-		) {
194
-			$trace = reset($trace);
195
-		}
196
-		$erreur_p_i_i = [
197
-			'zbug_parametres_inclus_incorrects',
198
-			['param' => print_r($trace, true)]
199
-		];
200
-		erreur_squelette($erreur_p_i_i, $p);
201
-
202
-		return "''";
203
-	}
204
-	$compil = texte_script(memoriser_contexte_compil($p));
205
-
206
-	if (is_array($_contexte)) {
207
-		// Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
208
-		if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) {
209
-			unset($_contexte['env']);
210
-		}
211
-
212
-		// noter les doublons dans l'appel a public.php
213
-		if (isset($_contexte['doublons'])) {
214
-			$_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'";
215
-		}
216
-
217
-		if ($ajax = isset($_contexte['ajax'])) {
218
-			$ajax = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
219
-			unset($_contexte['ajax']);
220
-		}
221
-
222
-		$_contexte = join(",\n\t", $_contexte);
223
-	} else {
224
-		return false;
225
-	} // j'aurais voulu toucher le fond ...
226
-
227
-	$contexte = 'array(' . $_contexte . ')';
228
-
229
-	if ($env) {
230
-		$contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
231
-	}
232
-
233
-	// s'il y a une extension .php, ce n'est pas un squelette
234
-	if ($fichier and preg_match('/^.+[.]php$/s', $fichier)) {
235
-		$code = sandbox_composer_inclure_php($fichier, $p, $contexte);
236
-	} else {
237
-		$_options[] = "\"compil\"=>array($compil)";
238
-		if ($ajax) {
239
-			$_options[] = $ajax;
240
-		}
241
-		$code = " ' . argumenter_squelette($code) . '";
242
-		$code = 'echo ' . sprintf(
243
-			CODE_RECUPERER_FOND,
244
-			$code,
245
-			$contexte,
246
-			implode(',', $_options),
247
-			"_request(\\'connect\\') ?? \\'\\'"
248
-		) . ';';
249
-	}
250
-
251
-	return "\n'<'.'" . '?php ' . $code . "\n?'." . "'>'";
174
+    $_options = [];
175
+    $_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
176
+    if (is_string($p->texte)) {
177
+        $fichier = $p->texte;
178
+        $code = '"' . str_replace('"', '\"', $fichier) . '"';
179
+    } else {
180
+        $code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
181
+        if ($code and preg_match("/^'([^']*)'/s", $code, $r)) {
182
+            $fichier = $r[1];
183
+        } else {
184
+            $fichier = '';
185
+        }
186
+    }
187
+    if (!$code or $code === '""' or $code === "''") {
188
+        $trace = $p->fonctions;
189
+        while (
190
+            is_array($trace)
191
+            and $trace = array_filter($trace)
192
+            and count($trace) == 1
193
+        ) {
194
+            $trace = reset($trace);
195
+        }
196
+        $erreur_p_i_i = [
197
+            'zbug_parametres_inclus_incorrects',
198
+            ['param' => print_r($trace, true)]
199
+        ];
200
+        erreur_squelette($erreur_p_i_i, $p);
201
+
202
+        return "''";
203
+    }
204
+    $compil = texte_script(memoriser_contexte_compil($p));
205
+
206
+    if (is_array($_contexte)) {
207
+        // Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
208
+        if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) {
209
+            unset($_contexte['env']);
210
+        }
211
+
212
+        // noter les doublons dans l'appel a public.php
213
+        if (isset($_contexte['doublons'])) {
214
+            $_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'";
215
+        }
216
+
217
+        if ($ajax = isset($_contexte['ajax'])) {
218
+            $ajax = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
219
+            unset($_contexte['ajax']);
220
+        }
221
+
222
+        $_contexte = join(",\n\t", $_contexte);
223
+    } else {
224
+        return false;
225
+    } // j'aurais voulu toucher le fond ...
226
+
227
+    $contexte = 'array(' . $_contexte . ')';
228
+
229
+    if ($env) {
230
+        $contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
231
+    }
232
+
233
+    // s'il y a une extension .php, ce n'est pas un squelette
234
+    if ($fichier and preg_match('/^.+[.]php$/s', $fichier)) {
235
+        $code = sandbox_composer_inclure_php($fichier, $p, $contexte);
236
+    } else {
237
+        $_options[] = "\"compil\"=>array($compil)";
238
+        if ($ajax) {
239
+            $_options[] = $ajax;
240
+        }
241
+        $code = " ' . argumenter_squelette($code) . '";
242
+        $code = 'echo ' . sprintf(
243
+            CODE_RECUPERER_FOND,
244
+            $code,
245
+            $contexte,
246
+            implode(',', $_options),
247
+            "_request(\\'connect\\') ?? \\'\\'"
248
+        ) . ';';
249
+    }
250
+
251
+    return "\n'<'.'" . '?php ' . $code . "\n?'." . "'>'";
252 252
 }
253 253
 
254 254
 
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
  *     true pour ne tester que le cas publie et ignorer l'eventuel var_mode=preview de la page
267 267
  */
268 268
 function instituer_boucle(&$boucle, $echapper = true, $ignore_previsu = false) {
269
-	/*
269
+    /*
270 270
 	$show['statut'][] = array(
271 271
 		'champ'=>'statut',  // champ de la table sur lequel porte le filtrage par le statut
272 272
 		'publie'=>'publie', // valeur ou liste de valeurs, qui definissent l'objet comme publie.
@@ -290,74 +290,74 @@  discard block
 block discarded – undo
290 290
 	champstatut est alors le champ statut sur la tablen
291 291
 	dans les jointures, clen peut etre un tableau pour une jointure complexe : array('id_objet','id_article','objet','article')
292 292
 	*/
293
-	$id_table = $boucle->id_table;
294
-	$show = $boucle->show;
295
-	if (isset($show['statut']) and $show['statut']) {
296
-		foreach ($show['statut'] as $k => $s) {
297
-			// Restreindre aux elements publies si pas de {statut} ou autre dans les criteres
298
-			$filtrer = true;
299
-			if (isset($s['exception'])) {
300
-				foreach (is_array($s['exception']) ? $s['exception'] : [$s['exception']] as $m) {
301
-					if (isset($boucle->modificateur[$m]) or isset($boucle->modificateur['criteres'][$m])) {
302
-						$filtrer = false;
303
-						break;
304
-					}
305
-				}
306
-			}
307
-
308
-			if ($filtrer) {
309
-				if (is_array($s['champ'])) {
310
-					$statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite
311
-					$jointures = [];
312
-					// indiquer la description de chaque table dans le tableau de jointures,
313
-					// ce qui permet d'eviter certains GROUP BY inutiles.
314
-					$trouver_table = charger_fonction('trouver_table', 'base');
315
-					foreach ($s['champ'] as $j) {
316
-						$id = reset($j);
317
-						$def = $trouver_table($id);
318
-						$jointures[] = ['', [$id, $def], end($j)];
319
-					}
320
-					$jointures[0][0] = $id_table;
321
-					if (!array_search($id, $boucle->from)) {
322
-						include_spip('public/jointures');
323
-						fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper);
324
-					}
325
-					// trouver l'alias de la table d'arrivee qui porte le statut
326
-					$id = array_search($id, $boucle->from);
327
-				} else {
328
-					$id = $id_table;
329
-					$statut = preg_replace(',\W,', '', $s['champ']); // securite
330
-				}
331
-				$mstatut = $id . '.' . $statut;
332
-
333
-				$arg_ignore_previsu = ($ignore_previsu ? ',true' : '');
334
-				include_spip('public/quete');
335
-				if (
336
-					isset($s['post_date']) and $s['post_date']
337
-					and $GLOBALS['meta']['post_dates'] == 'non'
338
-				) {
339
-					$date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
340
-					array_unshift(
341
-						$boucle->where,
342
-						$echapper ?
343
-							"\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
344
-							:
345
-							quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
346
-					);
347
-				}
348
-				array_unshift(
349
-					$boucle->where,
350
-					$echapper ?
351
-						"\nquete_condition_statut('$mstatut',"
352
-						. _q($s['previsu']) . ','
353
-						. _q($s['publie']) . ','
354
-						. _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
355
-						:
356
-						quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
357
-				);
358
-			}
359
-		}
360
-	}
293
+    $id_table = $boucle->id_table;
294
+    $show = $boucle->show;
295
+    if (isset($show['statut']) and $show['statut']) {
296
+        foreach ($show['statut'] as $k => $s) {
297
+            // Restreindre aux elements publies si pas de {statut} ou autre dans les criteres
298
+            $filtrer = true;
299
+            if (isset($s['exception'])) {
300
+                foreach (is_array($s['exception']) ? $s['exception'] : [$s['exception']] as $m) {
301
+                    if (isset($boucle->modificateur[$m]) or isset($boucle->modificateur['criteres'][$m])) {
302
+                        $filtrer = false;
303
+                        break;
304
+                    }
305
+                }
306
+            }
307
+
308
+            if ($filtrer) {
309
+                if (is_array($s['champ'])) {
310
+                    $statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite
311
+                    $jointures = [];
312
+                    // indiquer la description de chaque table dans le tableau de jointures,
313
+                    // ce qui permet d'eviter certains GROUP BY inutiles.
314
+                    $trouver_table = charger_fonction('trouver_table', 'base');
315
+                    foreach ($s['champ'] as $j) {
316
+                        $id = reset($j);
317
+                        $def = $trouver_table($id);
318
+                        $jointures[] = ['', [$id, $def], end($j)];
319
+                    }
320
+                    $jointures[0][0] = $id_table;
321
+                    if (!array_search($id, $boucle->from)) {
322
+                        include_spip('public/jointures');
323
+                        fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper);
324
+                    }
325
+                    // trouver l'alias de la table d'arrivee qui porte le statut
326
+                    $id = array_search($id, $boucle->from);
327
+                } else {
328
+                    $id = $id_table;
329
+                    $statut = preg_replace(',\W,', '', $s['champ']); // securite
330
+                }
331
+                $mstatut = $id . '.' . $statut;
332
+
333
+                $arg_ignore_previsu = ($ignore_previsu ? ',true' : '');
334
+                include_spip('public/quete');
335
+                if (
336
+                    isset($s['post_date']) and $s['post_date']
337
+                    and $GLOBALS['meta']['post_dates'] == 'non'
338
+                ) {
339
+                    $date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
340
+                    array_unshift(
341
+                        $boucle->where,
342
+                        $echapper ?
343
+                            "\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
344
+                            :
345
+                            quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
346
+                    );
347
+                }
348
+                array_unshift(
349
+                    $boucle->where,
350
+                    $echapper ?
351
+                        "\nquete_condition_statut('$mstatut',"
352
+                        . _q($s['previsu']) . ','
353
+                        . _q($s['publie']) . ','
354
+                        . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
355
+                        :
356
+                        quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
357
+                );
358
+            }
359
+        }
360
+    }
361 361
 }
362 362
 
363 363
 /**
@@ -376,29 +376,29 @@  discard block
 block discarded – undo
376 376
  */
377 377
 function calculer_boucle($id_boucle, &$boucles) {
378 378
 
379
-	$boucle = &$boucles[$id_boucle];
380
-	instituer_boucle($boucle);
381
-	$boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]);
382
-
383
-	// en mode debug memoriser les premiers passages dans la boucle,
384
-	// mais pas tous, sinon ca pete.
385
-	if (_request('var_mode_affiche') != 'resultat') {
386
-		$trace = '';
387
-	} else {
388
-		$_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
389
-		$_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
390
-		$trace = "
379
+    $boucle = &$boucles[$id_boucle];
380
+    instituer_boucle($boucle);
381
+    $boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]);
382
+
383
+    // en mode debug memoriser les premiers passages dans la boucle,
384
+    // mais pas tous, sinon ca pete.
385
+    if (_request('var_mode_affiche') != 'resultat') {
386
+        $trace = '';
387
+    } else {
388
+        $_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
389
+        $_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
390
+        $trace = "
391 391
 		if (empty($_trace)) {
392 392
 			$_trace = [];
393 393
 		}
394 394
 		if (count($_trace) < 3) {
395 395
 			$_trace" . '[] = $t0;
396 396
 		}';
397
-	}
397
+    }
398 398
 
399
-	return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF)
400
-		? calculer_boucle_rec($id_boucle, $boucles, $trace)
401
-		: calculer_boucle_nonrec($id_boucle, $boucles, $trace);
399
+    return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF)
400
+        ? calculer_boucle_rec($id_boucle, $boucles, $trace)
401
+        : calculer_boucle_nonrec($id_boucle, $boucles, $trace);
402 402
 }
403 403
 
404 404
 
@@ -421,15 +421,15 @@  discard block
 block discarded – undo
421 421
  *    Code PHP compilé de la boucle récursive
422 422
  **/
423 423
 function calculer_boucle_rec($id_boucle, &$boucles, $trace) {
424
-	$nom = $boucles[$id_boucle]->param[0];
425
-
426
-	return
427
-		// Numrows[$nom] peut ne pas être encore defini
428
-		"\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
429
-		. "\n\t\$t0 = " . $boucles[$id_boucle]->return . ';'
430
-		. "\n\t\$Numrows['$nom'] = (\$save_numrows);"
431
-		. $trace
432
-		. "\n\treturn \$t0;";
424
+    $nom = $boucles[$id_boucle]->param[0];
425
+
426
+    return
427
+        // Numrows[$nom] peut ne pas être encore defini
428
+        "\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
429
+        . "\n\t\$t0 = " . $boucles[$id_boucle]->return . ';'
430
+        . "\n\t\$Numrows['$nom'] = (\$save_numrows);"
431
+        . $trace
432
+        . "\n\treturn \$t0;";
433 433
 }
434 434
 
435 435
 /**
@@ -482,173 +482,173 @@  discard block
 block discarded – undo
482 482
  **/
483 483
 function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) {
484 484
 
485
-	$code_sep = null;
486
-	$boucle = &$boucles[$id_boucle];
487
-	$return = $boucle->return;
488
-	$type_boucle = $boucle->type_requete;
489
-	$primary = $boucle->primary;
490
-	$constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return));
491
-	$flag_cpt = $boucle->mode_partie || $boucle->cptrows;
492
-	$corps = '';
493
-
494
-	// faudrait expanser le foreach a la compil, car y en a souvent qu'un
495
-	// et puis faire un [] plutot qu'un "','."
496
-	if ($boucle->doublons) {
497
-		$corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
498
-			index_pile($id_boucle, $primary, $boucles)
499
-			. "; // doublons\n";
500
-	}
501
-
502
-	// La boucle doit-elle selectionner la langue ?
503
-	// - par defaut, les boucles suivantes le font
504
-	//    (sauf si forcer_lang==true ou si le titre contient <multi>).
505
-	// - a moins d'une demande explicite via {!lang_select}
506
-	if (
507
-		!$constant && $boucle->lang_select != 'non' &&
508
-		(($boucle->lang_select == 'oui') ||
509
-			in_array($type_boucle, [
510
-				'articles',
511
-				'rubriques',
512
-				'hierarchie',
513
-				'breves'
514
-			]))
515
-	) {
516
-		// Memoriser la langue avant la boucle et la restituer apres
517
-		// afin que le corps de boucle affecte la globale directement
518
-		$init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t";
519
-		$fin_lang = "lang_select();\n\t";
520
-		$fin_lang_select_public = "\n\t\tlang_select();";
521
-
522
-		$corps .=
523
-			"\n\t\tlang_select_public("
524
-			. index_pile($id_boucle, 'lang', $boucles)
525
-			. ", '" . $boucle->lang_select . "'"
526
-			. (in_array($type_boucle, [
527
-				'articles',
528
-				'rubriques',
529
-				'hierarchie',
530
-				'breves'
531
-			]) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
532
-			. ');';
533
-	} else {
534
-		$init_lang = '';
535
-		$fin_lang = '';
536
-		$fin_lang_select_public = '';
537
-		// sortir les appels au traducteur (invariants de boucle)
538
-		if (
539
-			strpos($return, '?php') === false
540
-			and preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r)
541
-		) {
542
-			$i = 1;
543
-			foreach ($r[1] as $t) {
544
-				$init_lang .= "\n\t\$l$i = $t;";
545
-				$return = str_replace($t, "\$l$i", $return);
546
-				$i++;
547
-			}
548
-		}
549
-	}
550
-
551
-	// gestion optimale des separateurs et des boucles constantes
552
-	if (is_countable($boucle->separateur) ? count($boucle->separateur) : 0) {
553
-		$code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
554
-	}
555
-
556
-	$corps .=
557
-		((!$boucle->separateur) ?
558
-			(($constant && !$corps && !$flag_cpt) ? $return :
559
-				(($return === "''") ? '' :
560
-					("\n\t\t" . '$t0 .= ' . $return . ';'))) :
561
-			("\n\t\t\$t1 " .
562
-				((strpos($return, '$t1.') === 0) ?
563
-					('.=' . substr($return, 4)) :
564
-					('= ' . $return)) .
565
-				";\n\t\t" .
566
-				'$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
567
-
568
-	// Calculer les invalideurs si c'est une boucle non constante et si on
569
-	// souhaite invalider ces elements
570
-	if (!$constant and $primary) {
571
-		include_spip('inc/invalideur');
572
-		$corps = calcul_invalideurs($corps, $primary, $boucles, $id_boucle);
573
-	}
574
-
575
-	// gerer le compteur de boucle
576
-	// avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}...
577
-
578
-	if ($boucle->partie or $boucle->cptrows) {
579
-		$corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;"
580
-			. $boucle->partie
581
-			. $corps;
582
-	}
583
-
584
-	// depiler la lang de la boucle si besoin
585
-	$corps .= $fin_lang_select_public;
586
-
587
-	// si le corps est une constante, ne pas appeler le serveur N fois!
588
-
589
-	if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) {
590
-		if (!isset($r[2]) or (!$r[2])) {
591
-			if (!$boucle->numrows) {
592
-				return "\n\t\$t0 = '';";
593
-			} else {
594
-				$corps = '';
595
-			}
596
-		} else {
597
-			$boucle->numrows = true;
598
-			$corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);";
599
-		}
600
-	} else {
601
-		$corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n	}";
602
-	}
603
-
604
-	$count = '';
605
-	if (!$boucle->select) {
606
-		if (!$boucle->numrows or $boucle->limit or $boucle->mode_partie or $boucle->group) {
607
-			$count = '1';
608
-		} else {
609
-			$count = 'count(*)';
610
-		}
611
-		$boucles[$id_boucle]->select[] = $count;
612
-	}
613
-
614
-	if ($flag_cpt) {
615
-		$nums = "\n\t// COMPTEUR\n\t"
616
-			. "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t";
617
-	} else {
618
-		$nums = '';
619
-	}
620
-
621
-	if ($boucle->numrows or $boucle->mode_partie) {
622
-		$nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t"
623
-			. "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());"
624
-			. $boucle->mode_partie
625
-			. "\n\t";
626
-	}
627
-
628
-	// Ne calculer la requete que maintenant
629
-	// car ce qui precede appelle index_pile qui influe dessus
630
-
631
-	$init = (($init = $boucles[$id_boucle]->doublons)
632
-			? ("\n\t$init = array();") : '')
633
-		. calculer_requete_sql($boucles[$id_boucle]);
634
-
635
-	$contexte = memoriser_contexte_compil($boucle);
636
-
637
-	$a = sprintf(
638
-		CODE_CORPS_BOUCLE,
639
-		$init,
640
-		$boucle->iterateur,
641
-		'$command',
642
-		$contexte,
643
-		$nums,
644
-		$init_lang,
645
-		$corps,
646
-		$fin_lang,
647
-		$trace,
648
-		'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
649
-	);
650
-
651
-	return $a;
485
+    $code_sep = null;
486
+    $boucle = &$boucles[$id_boucle];
487
+    $return = $boucle->return;
488
+    $type_boucle = $boucle->type_requete;
489
+    $primary = $boucle->primary;
490
+    $constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return));
491
+    $flag_cpt = $boucle->mode_partie || $boucle->cptrows;
492
+    $corps = '';
493
+
494
+    // faudrait expanser le foreach a la compil, car y en a souvent qu'un
495
+    // et puis faire un [] plutot qu'un "','."
496
+    if ($boucle->doublons) {
497
+        $corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
498
+            index_pile($id_boucle, $primary, $boucles)
499
+            . "; // doublons\n";
500
+    }
501
+
502
+    // La boucle doit-elle selectionner la langue ?
503
+    // - par defaut, les boucles suivantes le font
504
+    //    (sauf si forcer_lang==true ou si le titre contient <multi>).
505
+    // - a moins d'une demande explicite via {!lang_select}
506
+    if (
507
+        !$constant && $boucle->lang_select != 'non' &&
508
+        (($boucle->lang_select == 'oui') ||
509
+            in_array($type_boucle, [
510
+                'articles',
511
+                'rubriques',
512
+                'hierarchie',
513
+                'breves'
514
+            ]))
515
+    ) {
516
+        // Memoriser la langue avant la boucle et la restituer apres
517
+        // afin que le corps de boucle affecte la globale directement
518
+        $init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t";
519
+        $fin_lang = "lang_select();\n\t";
520
+        $fin_lang_select_public = "\n\t\tlang_select();";
521
+
522
+        $corps .=
523
+            "\n\t\tlang_select_public("
524
+            . index_pile($id_boucle, 'lang', $boucles)
525
+            . ", '" . $boucle->lang_select . "'"
526
+            . (in_array($type_boucle, [
527
+                'articles',
528
+                'rubriques',
529
+                'hierarchie',
530
+                'breves'
531
+            ]) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
532
+            . ');';
533
+    } else {
534
+        $init_lang = '';
535
+        $fin_lang = '';
536
+        $fin_lang_select_public = '';
537
+        // sortir les appels au traducteur (invariants de boucle)
538
+        if (
539
+            strpos($return, '?php') === false
540
+            and preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r)
541
+        ) {
542
+            $i = 1;
543
+            foreach ($r[1] as $t) {
544
+                $init_lang .= "\n\t\$l$i = $t;";
545
+                $return = str_replace($t, "\$l$i", $return);
546
+                $i++;
547
+            }
548
+        }
549
+    }
550
+
551
+    // gestion optimale des separateurs et des boucles constantes
552
+    if (is_countable($boucle->separateur) ? count($boucle->separateur) : 0) {
553
+        $code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
554
+    }
555
+
556
+    $corps .=
557
+        ((!$boucle->separateur) ?
558
+            (($constant && !$corps && !$flag_cpt) ? $return :
559
+                (($return === "''") ? '' :
560
+                    ("\n\t\t" . '$t0 .= ' . $return . ';'))) :
561
+            ("\n\t\t\$t1 " .
562
+                ((strpos($return, '$t1.') === 0) ?
563
+                    ('.=' . substr($return, 4)) :
564
+                    ('= ' . $return)) .
565
+                ";\n\t\t" .
566
+                '$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
567
+
568
+    // Calculer les invalideurs si c'est une boucle non constante et si on
569
+    // souhaite invalider ces elements
570
+    if (!$constant and $primary) {
571
+        include_spip('inc/invalideur');
572
+        $corps = calcul_invalideurs($corps, $primary, $boucles, $id_boucle);
573
+    }
574
+
575
+    // gerer le compteur de boucle
576
+    // avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}...
577
+
578
+    if ($boucle->partie or $boucle->cptrows) {
579
+        $corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;"
580
+            . $boucle->partie
581
+            . $corps;
582
+    }
583
+
584
+    // depiler la lang de la boucle si besoin
585
+    $corps .= $fin_lang_select_public;
586
+
587
+    // si le corps est une constante, ne pas appeler le serveur N fois!
588
+
589
+    if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) {
590
+        if (!isset($r[2]) or (!$r[2])) {
591
+            if (!$boucle->numrows) {
592
+                return "\n\t\$t0 = '';";
593
+            } else {
594
+                $corps = '';
595
+            }
596
+        } else {
597
+            $boucle->numrows = true;
598
+            $corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);";
599
+        }
600
+    } else {
601
+        $corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n	}";
602
+    }
603
+
604
+    $count = '';
605
+    if (!$boucle->select) {
606
+        if (!$boucle->numrows or $boucle->limit or $boucle->mode_partie or $boucle->group) {
607
+            $count = '1';
608
+        } else {
609
+            $count = 'count(*)';
610
+        }
611
+        $boucles[$id_boucle]->select[] = $count;
612
+    }
613
+
614
+    if ($flag_cpt) {
615
+        $nums = "\n\t// COMPTEUR\n\t"
616
+            . "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t";
617
+    } else {
618
+        $nums = '';
619
+    }
620
+
621
+    if ($boucle->numrows or $boucle->mode_partie) {
622
+        $nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t"
623
+            . "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());"
624
+            . $boucle->mode_partie
625
+            . "\n\t";
626
+    }
627
+
628
+    // Ne calculer la requete que maintenant
629
+    // car ce qui precede appelle index_pile qui influe dessus
630
+
631
+    $init = (($init = $boucles[$id_boucle]->doublons)
632
+            ? ("\n\t$init = array();") : '')
633
+        . calculer_requete_sql($boucles[$id_boucle]);
634
+
635
+    $contexte = memoriser_contexte_compil($boucle);
636
+
637
+    $a = sprintf(
638
+        CODE_CORPS_BOUCLE,
639
+        $init,
640
+        $boucle->iterateur,
641
+        '$command',
642
+        $contexte,
643
+        $nums,
644
+        $init_lang,
645
+        $corps,
646
+        $fin_lang,
647
+        $trace,
648
+        'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
649
+    );
650
+
651
+    return $a;
652 652
 }
653 653
 
654 654
 
@@ -664,48 +664,48 @@  discard block
 block discarded – undo
664 664
  *     Code PHP compilé définissant les informations de requête
665 665
  **/
666 666
 function calculer_requete_sql($boucle) {
667
-	$init = [];
668
-	$init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
669
-	$init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
670
-	# En absence de champ c'est un decompte :
671
-	$init[] = calculer_dec('from', calculer_from($boucle));
672
-	$init[] = calculer_dec('type', calculer_from_type($boucle));
673
-	$init[] = calculer_dec(
674
-		'groupby',
675
-		'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ')'
676
-	);
677
-	$init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . '")');
678
-	$init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ')');
679
-	$init[] = calculer_dec('where', calculer_dump_array($boucle->where));
680
-	$init[] = calculer_dec('join', calculer_dump_join($boucle->join));
681
-	$init[] = calculer_dec(
682
-		'limit',
683
-		(
684
-			strpos($boucle->limit, 'intval') === false ?
685
-			"'" . ($boucle->limit) . "'" :
686
-			$boucle->limit
687
-		)
688
-	);
689
-	$init[] = calculer_dec('having', calculer_dump_array($boucle->having));
690
-	$s = $d = '';
691
-	// l'index 0 de $i indique si l'affectation est statique (contenu)
692
-	// ou recalculée à chaque passage (vide)
693
-	foreach ($init as $i) {
694
-		if (reset($i)) {
695
-			$s .= "\n\t\t" . end($i);
696
-		} # statique
697
-		else {
698
-			$d .= "\n\t" . end($i);
699
-		} # dynamique
700
-	}
701
-
702
-	return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
703
-	. $boucle->in
704
-	. $boucle->hash
705
-	. "\n\t" . 'if (!isset($command[\'table\'])) {'
706
-	. $s
707
-	. "\n\t}"
708
-	. $d;
667
+    $init = [];
668
+    $init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
669
+    $init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
670
+    # En absence de champ c'est un decompte :
671
+    $init[] = calculer_dec('from', calculer_from($boucle));
672
+    $init[] = calculer_dec('type', calculer_from_type($boucle));
673
+    $init[] = calculer_dec(
674
+        'groupby',
675
+        'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ')'
676
+    );
677
+    $init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . '")');
678
+    $init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ')');
679
+    $init[] = calculer_dec('where', calculer_dump_array($boucle->where));
680
+    $init[] = calculer_dec('join', calculer_dump_join($boucle->join));
681
+    $init[] = calculer_dec(
682
+        'limit',
683
+        (
684
+            strpos($boucle->limit, 'intval') === false ?
685
+            "'" . ($boucle->limit) . "'" :
686
+            $boucle->limit
687
+        )
688
+    );
689
+    $init[] = calculer_dec('having', calculer_dump_array($boucle->having));
690
+    $s = $d = '';
691
+    // l'index 0 de $i indique si l'affectation est statique (contenu)
692
+    // ou recalculée à chaque passage (vide)
693
+    foreach ($init as $i) {
694
+        if (reset($i)) {
695
+            $s .= "\n\t\t" . end($i);
696
+        } # statique
697
+        else {
698
+            $d .= "\n\t" . end($i);
699
+        } # dynamique
700
+    }
701
+
702
+    return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
703
+    . $boucle->in
704
+    . $boucle->hash
705
+    . "\n\t" . 'if (!isset($command[\'table\'])) {'
706
+    . $s
707
+    . "\n\t}"
708
+    . $d;
709 709
 }
710 710
 
711 711
 /**
@@ -723,13 +723,13 @@  discard block
 block discarded – undo
723 723
  *     qui peut être utilisé pour la production d'un tableau array()
724 724
  **/
725 725
 function memoriser_contexte_compil($p) {
726
-	return join(',', [
727
-		_q($p->descr['sourcefile'] ?? ''),
728
-		_q($p->descr['nom'] ?? ''),
729
-		_q($p->id_boucle ?? ''),
730
-		intval($p->ligne),
731
-		'$GLOBALS[\'spip_lang\']'
732
-	]);
726
+    return join(',', [
727
+        _q($p->descr['sourcefile'] ?? ''),
728
+        _q($p->descr['nom'] ?? ''),
729
+        _q($p->id_boucle ?? ''),
730
+        intval($p->ligne),
731
+        '$GLOBALS[\'spip_lang\']'
732
+    ]);
733 733
 }
734 734
 
735 735
 /**
@@ -747,20 +747,20 @@  discard block
 block discarded – undo
747 747
  *     Objet Contexte
748 748
  **/
749 749
 function reconstruire_contexte_compil($context_compil) {
750
-	if (!is_array($context_compil)) {
751
-		return $context_compil;
752
-	}
753
-	$p = new Contexte();
754
-	$p->descr = [
755
-		'sourcefile' => $context_compil[0] ?? '',
756
-		'nom' => $context_compil[1] ?? '',
757
-	];
758
-
759
-	$p->id_boucle = $context_compil[2] ?? '';
760
-	$p->ligne = (int)($context_compil[3] ?? 0);
761
-	$p->lang = $context_compil[4] ?? '';
762
-
763
-	return $p;
750
+    if (!is_array($context_compil)) {
751
+        return $context_compil;
752
+    }
753
+    $p = new Contexte();
754
+    $p->descr = [
755
+        'sourcefile' => $context_compil[0] ?? '',
756
+        'nom' => $context_compil[1] ?? '',
757
+    ];
758
+
759
+    $p->id_boucle = $context_compil[2] ?? '';
760
+    $p->ligne = (int)($context_compil[3] ?? 0);
761
+    $p->lang = $context_compil[4] ?? '';
762
+
763
+    return $p;
764 764
 }
765 765
 
766 766
 /**
@@ -786,12 +786,12 @@  discard block
 block discarded – undo
786 786
  *    - index 1 : Code de l'affectation
787 787
  **/
788 788
 function calculer_dec($nom, $val) {
789
-	$static = 'if (!isset($command[\'' . $nom . '\'])) ';
790
-	// si une variable apparait dans le calcul de la clause
791
-	// il faut la re-evaluer a chaque passage
792
-	if (
793
-		str_contains($val, '$')
794
-		/*
789
+    $static = 'if (!isset($command[\'' . $nom . '\'])) ';
790
+    // si une variable apparait dans le calcul de la clause
791
+    // il faut la re-evaluer a chaque passage
792
+    if (
793
+        str_contains($val, '$')
794
+        /*
795 795
 		OR str_contains($val, 'sql_')
796 796
 		OR (
797 797
 			$test = str_replace(array("array(",'\"',"\'"),array("","",""),$val) // supprimer les array( et les echappements de guillemets
@@ -799,11 +799,11 @@  discard block
 block discarded – undo
799 799
 			AND $test = preg_replace(",'[^']*',UimsS","",$test) // supprimer les chaines qui peuvent contenir des fonctions SQL qui ne genent pas
800 800
 			AND preg_match(",\w+\s*\(,UimsS",$test,$regs) // tester la presence de fonctions restantes
801 801
 		)*/
802
-	) {
803
-		$static = '';
804
-	}
802
+    ) {
803
+        $static = '';
804
+    }
805 805
 
806
-	return [$static, '$command[\'' . $nom . '\'] = ' . $val . ';'];
806
+    return [$static, '$command[\'' . $nom . '\'] = ' . $val . ';'];
807 807
 }
808 808
 
809 809
 /**
@@ -823,32 +823,32 @@  discard block
 block discarded – undo
823 823
  *     Expression PHP décrivant un texte ou un tableau
824 824
  **/
825 825
 function calculer_dump_array($a) {
826
-	if (!is_array($a)) {
827
-		return $a;
828
-	}
829
-	$res = '';
830
-	if ($a and $a[0] == "'?'") {
831
-		return ('(' . calculer_dump_array($a[1]) .
832
-			' ? ' . calculer_dump_array($a[2]) .
833
-			' : ' . calculer_dump_array($a[3]) .
834
-			')');
835
-	} else {
836
-		foreach ($a as $k => $v) {
837
-			$showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
838
-			$res .= ', ' . $showk . calculer_dump_array($v);
839
-		}
840
-
841
-		return "\n\t\t\tarray(" . substr($res, 2) . ')';
842
-	}
826
+    if (!is_array($a)) {
827
+        return $a;
828
+    }
829
+    $res = '';
830
+    if ($a and $a[0] == "'?'") {
831
+        return ('(' . calculer_dump_array($a[1]) .
832
+            ' ? ' . calculer_dump_array($a[2]) .
833
+            ' : ' . calculer_dump_array($a[3]) .
834
+            ')');
835
+    } else {
836
+        foreach ($a as $k => $v) {
837
+            $showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
838
+            $res .= ', ' . $showk . calculer_dump_array($v);
839
+        }
840
+
841
+        return "\n\t\t\tarray(" . substr($res, 2) . ')';
842
+    }
843 843
 }
844 844
 
845 845
 function calculer_dump_join($a) {
846
-	$res = '';
847
-	foreach ($a as $k => $v) {
848
-		$res .= ", '$k' => array(" . implode(',', $v) . ')';
849
-	}
846
+    $res = '';
847
+    foreach ($a as $k => $v) {
848
+        $res .= ", '$k' => array(" . implode(',', $v) . ')';
849
+    }
850 850
 
851
-	return 'array(' . substr($res, 2) . ')';
851
+    return 'array(' . substr($res, 2) . ')';
852 852
 }
853 853
 
854 854
 /**
@@ -860,12 +860,12 @@  discard block
 block discarded – undo
860 860
  *     Code PHP construisant un tableau des alias et noms des tables du FROM
861 861
  **/
862 862
 function calculer_from(&$boucle) {
863
-	$res = '';
864
-	foreach ($boucle->from as $k => $v) {
865
-		$res .= ",'$k' => '$v'";
866
-	}
863
+    $res = '';
864
+    foreach ($boucle->from as $k => $v) {
865
+        $res .= ",'$k' => '$v'";
866
+    }
867 867
 
868
-	return 'array(' . substr($res, 1) . ')';
868
+    return 'array(' . substr($res, 1) . ')';
869 869
 }
870 870
 
871 871
 /**
@@ -878,30 +878,30 @@  discard block
 block discarded – undo
878 878
  *     Code PHP construisant un tableau des alias et type de jointure du FROM
879 879
  **/
880 880
 function calculer_from_type(&$boucle) {
881
-	$res = '';
882
-	foreach ($boucle->from_type as $k => $v) {
883
-		$res .= ",'$k' => '$v'";
884
-	}
881
+    $res = '';
882
+    foreach ($boucle->from_type as $k => $v) {
883
+        $res .= ",'$k' => '$v'";
884
+    }
885 885
 
886
-	return 'array(' . substr($res, 1) . ')';
886
+    return 'array(' . substr($res, 1) . ')';
887 887
 }
888 888
 
889 889
 function calculer_order(&$boucle) {
890
-	if (
891
-		!$order = $boucle->order
892
-		and !$order = $boucle->default_order
893
-	) {
894
-		$order = [];
895
-	}
896
-
897
-	/*if (isset($boucle->modificateur['collate'])){
890
+    if (
891
+        !$order = $boucle->order
892
+        and !$order = $boucle->default_order
893
+    ) {
894
+        $order = [];
895
+    }
896
+
897
+    /*if (isset($boucle->modificateur['collate'])){
898 898
 		$col = "." . $boucle->modificateur['collate'];
899 899
 		foreach($order as $k=>$o)
900 900
 			if (strpos($order[$k],'COLLATE')===false)
901 901
 				$order[$k].= $col;
902 902
 	}*/
903 903
 
904
-	return join(', ', $order);
904
+    return join(', ', $order);
905 905
 }
906 906
 
907 907
 // Production du code PHP a partir de la sequence livree par le phraseur
@@ -910,62 +910,62 @@  discard block
 block discarded – undo
910 910
 // (qui sera argument d'un Return ou la partie droite d'une affectation).
911 911
 
912 912
 function calculer_liste($tableau, $descr, &$boucles, $id_boucle = '') {
913
-	if (!$tableau) {
914
-		return "''";
915
-	}
916
-	if (is_string($descr)) {
917
-		if (isset($boucles[$descr])) {
918
-			$idb = $descr;
919
-			$descr = [];
920
-			if (isset($boucles[$idb]->descr['id_mere_contexte'])) {
921
-				$descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte'];
922
-			}
923
-			if (isset($boucles[$idb]->descr['sourcefile'])) {
924
-				$descr['sourcefile'] = $boucles[$idb]->descr['sourcefile'];
925
-			}
926
-		}
927
-		else {
928
-			$descr = [];
929
-		}
930
-	}
931
-	if (!isset($descr['niv'])) {
932
-		$descr['niv'] = 0;
933
-	}
934
-	$codes = compile_cas($tableau, $descr, $boucles, $id_boucle);
935
-	if ($codes === false) {
936
-		return false;
937
-	}
938
-	$n = is_countable($codes) ? count($codes) : 0;
939
-	if (!$n) {
940
-		return "''";
941
-	}
942
-	$tab = str_repeat("\t", $descr['niv']);
943
-	if (_request('var_mode_affiche') != 'validation') {
944
-		if ($n == 1) {
945
-			return $codes[0];
946
-		} else {
947
-			$res = '';
948
-			foreach ($codes as $code) {
949
-				if (
950
-					!preg_match("/^'[^']*'$/", $code)
951
-					or substr($res, -1, 1) !== "'"
952
-				) {
953
-					$res .= " .\n$tab$code";
954
-				} else {
955
-					$res = substr($res, 0, -1) . substr($code, 1);
956
-				}
957
-			}
958
-
959
-			return '(' . substr($res, 2 + $descr['niv']) . ')';
960
-		}
961
-	} else {
962
-		$nom = $descr['nom'] . $id_boucle . ($descr['niv'] ?: '');
963
-
964
-		return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(
965
-			" ,\n$tab",
966
-			$codes
967
-		) . ')))';
968
-	}
913
+    if (!$tableau) {
914
+        return "''";
915
+    }
916
+    if (is_string($descr)) {
917
+        if (isset($boucles[$descr])) {
918
+            $idb = $descr;
919
+            $descr = [];
920
+            if (isset($boucles[$idb]->descr['id_mere_contexte'])) {
921
+                $descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte'];
922
+            }
923
+            if (isset($boucles[$idb]->descr['sourcefile'])) {
924
+                $descr['sourcefile'] = $boucles[$idb]->descr['sourcefile'];
925
+            }
926
+        }
927
+        else {
928
+            $descr = [];
929
+        }
930
+    }
931
+    if (!isset($descr['niv'])) {
932
+        $descr['niv'] = 0;
933
+    }
934
+    $codes = compile_cas($tableau, $descr, $boucles, $id_boucle);
935
+    if ($codes === false) {
936
+        return false;
937
+    }
938
+    $n = is_countable($codes) ? count($codes) : 0;
939
+    if (!$n) {
940
+        return "''";
941
+    }
942
+    $tab = str_repeat("\t", $descr['niv']);
943
+    if (_request('var_mode_affiche') != 'validation') {
944
+        if ($n == 1) {
945
+            return $codes[0];
946
+        } else {
947
+            $res = '';
948
+            foreach ($codes as $code) {
949
+                if (
950
+                    !preg_match("/^'[^']*'$/", $code)
951
+                    or substr($res, -1, 1) !== "'"
952
+                ) {
953
+                    $res .= " .\n$tab$code";
954
+                } else {
955
+                    $res = substr($res, 0, -1) . substr($code, 1);
956
+                }
957
+            }
958
+
959
+            return '(' . substr($res, 2 + $descr['niv']) . ')';
960
+        }
961
+    } else {
962
+        $nom = $descr['nom'] . $id_boucle . ($descr['niv'] ?: '');
963
+
964
+        return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(
965
+            " ,\n$tab",
966
+            $codes
967
+        ) . ')))';
968
+    }
969 969
 }
970 970
 
971 971
 
@@ -984,213 +984,213 @@  discard block
 block discarded – undo
984 984
  */
985 985
 function compile_cas($tableau, $descr, &$boucles, $id_boucle) {
986 986
 
987
-	$codes = [];
988
-	// cas de la boucle recursive
989
-	if (is_array($id_boucle)) {
990
-		$id_boucle = $id_boucle[0];
991
-	}
992
-	$type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete;
993
-	$tab = str_repeat("\t", ++$descr['niv']);
994
-	$mode = _request('var_mode_affiche');
995
-	$err_e_c = '';
996
-	// chaque commentaire introduit dans le code doit commencer
997
-	// par un caractere distinguant le cas, pour exploitation par debug.
998
-	foreach ($tableau as $p) {
999
-		switch ($p->type) {
1000
-			// texte seul
1001
-			case 'texte':
1002
-				$code = sandbox_composer_texte($p->texte, $p);
1003
-				$commentaire = strlen($p->texte) . ' signes';
1004
-				$avant = '';
1005
-				$apres = '';
1006
-				$altern = "''";
1007
-				break;
1008
-
1009
-			case 'polyglotte':
1010
-				$code = '';
1011
-				foreach ($p->traductions as $k => $v) {
1012
-					$code .= ",'" .
1013
-						str_replace(['\\', "'"], ['\\\\', "\\'"], $k) .
1014
-						"' => '" .
1015
-						str_replace(['\\', "'"], ['\\\\', "\\'"], $v) .
1016
-						"'";
1017
-				}
1018
-				$code = 'choisir_traduction(array(' .
1019
-					substr($code, 1) .
1020
-					'))';
1021
-				$commentaire = '&';
1022
-				$avant = '';
1023
-				$apres = '';
1024
-				$altern = "''";
1025
-				break;
1026
-
1027
-			// inclure
1028
-			case 'include':
1029
-				$p->descr = $descr;
1030
-				$code = calculer_inclure($p, $boucles, $id_boucle);
1031
-				if ($code === false) {
1032
-					$err_e_c = true;
1033
-					$code = "''";
1034
-				} else {
1035
-					$commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1036
-					$avant = '';
1037
-					$apres = '';
1038
-					$altern = "''";
1039
-				}
1040
-				break;
1041
-
1042
-			// boucle
1043
-			case TYPE_RECURSIF:
1044
-				$nom = $p->id_boucle;
1045
-				$newdescr = $descr;
1046
-				$newdescr['id_mere'] = $nom;
1047
-				$newdescr['niv']++;
1048
-				$preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle);
1049
-				$avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle);
1050
-				$apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle);
1051
-				$postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle);
1052
-				$newdescr['niv']--;
1053
-				$altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle);
1054
-				if (
1055
-					$preaff === false
1056
-					or $avant === false
1057
-					or $apres === false
1058
-					or $altern === false
1059
-					or $postaff === false
1060
-				) {
1061
-					$err_e_c = true;
1062
-					$code = "''";
1063
-				} else {
1064
-					$code = 'BOUCLE' .
1065
-						str_replace('-', '_', $nom) . $descr['nom'] .
1066
-						'($Cache, $Pile, $doublons, $Numrows, $SP)';
1067
-					$commentaire = "?$nom";
1068
-					if (
1069
-						!$boucles[$nom]->milieu
1070
-						and $boucles[$nom]->type_requete <> TYPE_RECURSIF
1071
-					) {
1072
-						if ($preaff != "''") {
1073
-							$code .= "\n. $preaff";
1074
-						}
1075
-						if ($altern != "''") {
1076
-							$code .= "\n. $altern";
1077
-						}
1078
-						if ($postaff != "''") {
1079
-							$code .= "\n. $postaff";
1080
-						}
1081
-						if ($avant <> "''" or $apres <> "''") {
1082
-							spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]");
1083
-						}
1084
-						$avant = $apres = $altern = "''";
1085
-					} else {
1086
-						if ($preaff != "''") {
1087
-							$avant = compile_concatene_parties_codes($preaff, $avant);
1088
-							$altern = compile_concatene_parties_codes($preaff, $altern);
1089
-						}
1090
-						if ($postaff != "''") {
1091
-							$apres = compile_concatene_parties_codes($apres, $postaff);
1092
-							$altern = compile_concatene_parties_codes($altern, $postaff);
1093
-						}
1094
-						if ($altern != "''") {
1095
-							$altern = "($altern)";
1096
-						}
1097
-					}
1098
-				}
1099
-				break;
1100
-
1101
-			case 'idiome':
1102
-				$l = [];
1103
-				$code = '';
1104
-				foreach ($p->arg as $k => $v) {
1105
-					$_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1106
-					if ($k) {
1107
-						$l[] = _q($k) . ' => ' . $_v;
1108
-					} else {
1109
-						$code = $_v;
1110
-					}
1111
-				}
1112
-				// Si le module n'est pas fourni, l'expliciter sauf si calculé
1113
-				if ($p->module) {
1114
-					$m = $p->module . ':' . $p->nom_champ;
1115
-				} elseif ($p->nom_champ) {
1116
-					$m = MODULES_IDIOMES . ':' . $p->nom_champ;
1117
-				} else {
1118
-					$m = '';
1119
-				}
1120
-
1121
-				$code = (!$code ? "'$m'" :
1122
-						($m ? "'$m' . $code" :
1123
-							("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1124
-					. (!$l ? '' : (', array(' . implode(",\n", $l) . ')'));
1125
-				$code = "_T($code)";
1126
-				if ($p->param) {
1127
-					$p->id_boucle = $id_boucle;
1128
-					$p->boucles = &$boucles;
1129
-					$code = compose_filtres($p, $code);
1130
-				}
1131
-				$commentaire = ':';
1132
-				$avant = '';
1133
-				$apres = '';
1134
-				$altern = "''";
1135
-				break;
1136
-
1137
-			case 'champ':
1138
-				// cette structure pourrait etre completee des le phrase' (a faire)
1139
-				$p->id_boucle = $id_boucle;
1140
-				$p->boucles = &$boucles;
1141
-				$p->descr = $descr;
1142
-				#$p->interdire_scripts = true;
1143
-				$p->type_requete = $type;
1144
-
1145
-				$code = calculer_champ($p);
1146
-				$commentaire = '#' . $p->nom_champ . $p->etoile;
1147
-				$avant = calculer_liste(
1148
-					$p->avant,
1149
-					$descr,
1150
-					$boucles,
1151
-					$id_boucle
1152
-				);
1153
-				$apres = calculer_liste(
1154
-					$p->apres,
1155
-					$descr,
1156
-					$boucles,
1157
-					$id_boucle
1158
-				);
1159
-				$altern = "''";
1160
-				// Si la valeur est destinee a une comparaison a ''
1161
-				// forcer la conversion en une chaine par strval
1162
-				// si ca peut etre autre chose qu'une chaine
1163
-				if (
1164
-					($avant != "''" or $apres != "''")
1165
-					and $code[0] != "'"
1166
-					# AND (strpos($code,'interdire_scripts') !== 0)
1167
-					and !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code)
1168
-					and !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code)
1169
-					and !preg_match(_REGEXP_CONCAT_NON_VIDE, $code)
1170
-				) {
1171
-					$code = "strval($code)";
1172
-				}
1173
-				break;
1174
-
1175
-			default:
1176
-				// Erreur de construction de l'arbre de syntaxe abstraite
1177
-				$code = "''";
1178
-				$p->descr = $descr;
1179
-				$err_e_c = _T('zbug_erreur_compilation');
1180
-				erreur_squelette($err_e_c, $p);
1181
-		} // switch
1182
-
1183
-		if ($code != "''") {
1184
-			$code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1185
-			$codes[] = (($mode == 'validation') ?
1186
-				"array($code, '$commentaire', " . $p->ligne . ')'
1187
-				: (($mode == 'code') ?
1188
-					"\n// $commentaire\n$code" :
1189
-					$code));
1190
-		}
1191
-	} // foreach
1192
-
1193
-	return $err_e_c ? false : $codes;
987
+    $codes = [];
988
+    // cas de la boucle recursive
989
+    if (is_array($id_boucle)) {
990
+        $id_boucle = $id_boucle[0];
991
+    }
992
+    $type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete;
993
+    $tab = str_repeat("\t", ++$descr['niv']);
994
+    $mode = _request('var_mode_affiche');
995
+    $err_e_c = '';
996
+    // chaque commentaire introduit dans le code doit commencer
997
+    // par un caractere distinguant le cas, pour exploitation par debug.
998
+    foreach ($tableau as $p) {
999
+        switch ($p->type) {
1000
+            // texte seul
1001
+            case 'texte':
1002
+                $code = sandbox_composer_texte($p->texte, $p);
1003
+                $commentaire = strlen($p->texte) . ' signes';
1004
+                $avant = '';
1005
+                $apres = '';
1006
+                $altern = "''";
1007
+                break;
1008
+
1009
+            case 'polyglotte':
1010
+                $code = '';
1011
+                foreach ($p->traductions as $k => $v) {
1012
+                    $code .= ",'" .
1013
+                        str_replace(['\\', "'"], ['\\\\', "\\'"], $k) .
1014
+                        "' => '" .
1015
+                        str_replace(['\\', "'"], ['\\\\', "\\'"], $v) .
1016
+                        "'";
1017
+                }
1018
+                $code = 'choisir_traduction(array(' .
1019
+                    substr($code, 1) .
1020
+                    '))';
1021
+                $commentaire = '&';
1022
+                $avant = '';
1023
+                $apres = '';
1024
+                $altern = "''";
1025
+                break;
1026
+
1027
+            // inclure
1028
+            case 'include':
1029
+                $p->descr = $descr;
1030
+                $code = calculer_inclure($p, $boucles, $id_boucle);
1031
+                if ($code === false) {
1032
+                    $err_e_c = true;
1033
+                    $code = "''";
1034
+                } else {
1035
+                    $commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1036
+                    $avant = '';
1037
+                    $apres = '';
1038
+                    $altern = "''";
1039
+                }
1040
+                break;
1041
+
1042
+            // boucle
1043
+            case TYPE_RECURSIF:
1044
+                $nom = $p->id_boucle;
1045
+                $newdescr = $descr;
1046
+                $newdescr['id_mere'] = $nom;
1047
+                $newdescr['niv']++;
1048
+                $preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle);
1049
+                $avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle);
1050
+                $apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle);
1051
+                $postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle);
1052
+                $newdescr['niv']--;
1053
+                $altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle);
1054
+                if (
1055
+                    $preaff === false
1056
+                    or $avant === false
1057
+                    or $apres === false
1058
+                    or $altern === false
1059
+                    or $postaff === false
1060
+                ) {
1061
+                    $err_e_c = true;
1062
+                    $code = "''";
1063
+                } else {
1064
+                    $code = 'BOUCLE' .
1065
+                        str_replace('-', '_', $nom) . $descr['nom'] .
1066
+                        '($Cache, $Pile, $doublons, $Numrows, $SP)';
1067
+                    $commentaire = "?$nom";
1068
+                    if (
1069
+                        !$boucles[$nom]->milieu
1070
+                        and $boucles[$nom]->type_requete <> TYPE_RECURSIF
1071
+                    ) {
1072
+                        if ($preaff != "''") {
1073
+                            $code .= "\n. $preaff";
1074
+                        }
1075
+                        if ($altern != "''") {
1076
+                            $code .= "\n. $altern";
1077
+                        }
1078
+                        if ($postaff != "''") {
1079
+                            $code .= "\n. $postaff";
1080
+                        }
1081
+                        if ($avant <> "''" or $apres <> "''") {
1082
+                            spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]");
1083
+                        }
1084
+                        $avant = $apres = $altern = "''";
1085
+                    } else {
1086
+                        if ($preaff != "''") {
1087
+                            $avant = compile_concatene_parties_codes($preaff, $avant);
1088
+                            $altern = compile_concatene_parties_codes($preaff, $altern);
1089
+                        }
1090
+                        if ($postaff != "''") {
1091
+                            $apres = compile_concatene_parties_codes($apres, $postaff);
1092
+                            $altern = compile_concatene_parties_codes($altern, $postaff);
1093
+                        }
1094
+                        if ($altern != "''") {
1095
+                            $altern = "($altern)";
1096
+                        }
1097
+                    }
1098
+                }
1099
+                break;
1100
+
1101
+            case 'idiome':
1102
+                $l = [];
1103
+                $code = '';
1104
+                foreach ($p->arg as $k => $v) {
1105
+                    $_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1106
+                    if ($k) {
1107
+                        $l[] = _q($k) . ' => ' . $_v;
1108
+                    } else {
1109
+                        $code = $_v;
1110
+                    }
1111
+                }
1112
+                // Si le module n'est pas fourni, l'expliciter sauf si calculé
1113
+                if ($p->module) {
1114
+                    $m = $p->module . ':' . $p->nom_champ;
1115
+                } elseif ($p->nom_champ) {
1116
+                    $m = MODULES_IDIOMES . ':' . $p->nom_champ;
1117
+                } else {
1118
+                    $m = '';
1119
+                }
1120
+
1121
+                $code = (!$code ? "'$m'" :
1122
+                        ($m ? "'$m' . $code" :
1123
+                            ("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1124
+                    . (!$l ? '' : (', array(' . implode(",\n", $l) . ')'));
1125
+                $code = "_T($code)";
1126
+                if ($p->param) {
1127
+                    $p->id_boucle = $id_boucle;
1128
+                    $p->boucles = &$boucles;
1129
+                    $code = compose_filtres($p, $code);
1130
+                }
1131
+                $commentaire = ':';
1132
+                $avant = '';
1133
+                $apres = '';
1134
+                $altern = "''";
1135
+                break;
1136
+
1137
+            case 'champ':
1138
+                // cette structure pourrait etre completee des le phrase' (a faire)
1139
+                $p->id_boucle = $id_boucle;
1140
+                $p->boucles = &$boucles;
1141
+                $p->descr = $descr;
1142
+                #$p->interdire_scripts = true;
1143
+                $p->type_requete = $type;
1144
+
1145
+                $code = calculer_champ($p);
1146
+                $commentaire = '#' . $p->nom_champ . $p->etoile;
1147
+                $avant = calculer_liste(
1148
+                    $p->avant,
1149
+                    $descr,
1150
+                    $boucles,
1151
+                    $id_boucle
1152
+                );
1153
+                $apres = calculer_liste(
1154
+                    $p->apres,
1155
+                    $descr,
1156
+                    $boucles,
1157
+                    $id_boucle
1158
+                );
1159
+                $altern = "''";
1160
+                // Si la valeur est destinee a une comparaison a ''
1161
+                // forcer la conversion en une chaine par strval
1162
+                // si ca peut etre autre chose qu'une chaine
1163
+                if (
1164
+                    ($avant != "''" or $apres != "''")
1165
+                    and $code[0] != "'"
1166
+                    # AND (strpos($code,'interdire_scripts') !== 0)
1167
+                    and !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code)
1168
+                    and !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code)
1169
+                    and !preg_match(_REGEXP_CONCAT_NON_VIDE, $code)
1170
+                ) {
1171
+                    $code = "strval($code)";
1172
+                }
1173
+                break;
1174
+
1175
+            default:
1176
+                // Erreur de construction de l'arbre de syntaxe abstraite
1177
+                $code = "''";
1178
+                $p->descr = $descr;
1179
+                $err_e_c = _T('zbug_erreur_compilation');
1180
+                erreur_squelette($err_e_c, $p);
1181
+        } // switch
1182
+
1183
+        if ($code != "''") {
1184
+            $code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1185
+            $codes[] = (($mode == 'validation') ?
1186
+                "array($code, '$commentaire', " . $p->ligne . ')'
1187
+                : (($mode == 'code') ?
1188
+                    "\n// $commentaire\n$code" :
1189
+                    $code));
1190
+        }
1191
+    } // foreach
1192
+
1193
+    return $err_e_c ? false : $codes;
1194 1194
 }
1195 1195
 
1196 1196
 /**
@@ -1200,13 +1200,13 @@  discard block
 block discarded – undo
1200 1200
  * @return string
1201 1201
  */
1202 1202
 function compile_concatene_parties_codes($partie1, $partie2) {
1203
-	if ($partie1 === "''") {
1204
-		return $partie2;
1205
-	}
1206
-	if ($partie2 === "''") {
1207
-		return $partie1;
1208
-	}
1209
-	return "$partie1\n. $partie2";
1203
+    if ($partie1 === "''") {
1204
+        return $partie2;
1205
+    }
1206
+    if ($partie2 === "''") {
1207
+        return $partie1;
1208
+    }
1209
+    return "$partie1\n. $partie2";
1210 1210
 }
1211 1211
 
1212 1212
 
@@ -1230,56 +1230,56 @@  discard block
 block discarded – undo
1230 1230
  * @return mixed|string
1231 1231
  */
1232 1232
 function compile_retour($code, $avant, $apres, $altern, $tab, $n) {
1233
-	if ($avant === "''") {
1234
-		$avant = '';
1235
-	}
1236
-	if ($apres === "''") {
1237
-		$apres = '';
1238
-	}
1239
-	if ($avant or $apres or ($altern !== "''")) {
1240
-		if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)) {
1241
-			$t = $code;
1242
-			$cond = '';
1243
-		} elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1244
-			$t = $r[2];
1245
-			$cond = '!' . $r[1];
1246
-		} else {
1247
-			if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) {
1248
-				$t = $r[2];
1249
-				$cond = $r[1];
1250
-			} else {
1251
-				$t = '$t' . $n;
1252
-				$cond = "($t = $code)!==''";
1253
-			}
1254
-		}
1255
-
1256
-		$res = (!$avant ? '' : "$avant . ") .
1257
-			$t .
1258
-			(!$apres ? '' : " . $apres");
1259
-
1260
-		if ($res !== $t) {
1261
-			$res = "($res)";
1262
-		}
1263
-
1264
-		$code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)");
1265
-	}
1266
-
1267
-	return $code;
1233
+    if ($avant === "''") {
1234
+        $avant = '';
1235
+    }
1236
+    if ($apres === "''") {
1237
+        $apres = '';
1238
+    }
1239
+    if ($avant or $apres or ($altern !== "''")) {
1240
+        if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)) {
1241
+            $t = $code;
1242
+            $cond = '';
1243
+        } elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1244
+            $t = $r[2];
1245
+            $cond = '!' . $r[1];
1246
+        } else {
1247
+            if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) {
1248
+                $t = $r[2];
1249
+                $cond = $r[1];
1250
+            } else {
1251
+                $t = '$t' . $n;
1252
+                $cond = "($t = $code)!==''";
1253
+            }
1254
+        }
1255
+
1256
+        $res = (!$avant ? '' : "$avant . ") .
1257
+            $t .
1258
+            (!$apres ? '' : " . $apres");
1259
+
1260
+        if ($res !== $t) {
1261
+            $res = "($res)";
1262
+        }
1263
+
1264
+        $code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)");
1265
+    }
1266
+
1267
+    return $code;
1268 1268
 }
1269 1269
 
1270 1270
 
1271 1271
 function compile_inclure_doublons($lexemes) {
1272
-	foreach ($lexemes as $v) {
1273
-		if ($v->type === 'include' and $v->param) {
1274
-			foreach ($v->param as $r) {
1275
-				if (trim($r[0]) === 'doublons') {
1276
-					return true;
1277
-				}
1278
-			}
1279
-		}
1280
-	}
1281
-
1282
-	return false;
1272
+    foreach ($lexemes as $v) {
1273
+        if ($v->type === 'include' and $v->param) {
1274
+            foreach ($v->param as $r) {
1275
+                if (trim($r[0]) === 'doublons') {
1276
+                    return true;
1277
+                }
1278
+            }
1279
+        }
1280
+    }
1281
+
1282
+    return false;
1283 1283
 }
1284 1284
 
1285 1285
 // Prend en argument le texte d'un squelette, le nom de son fichier d'origine,
@@ -1298,354 +1298,354 @@  discard block
 block discarded – undo
1298 1298
 // En cas d'erreur, elle retournera un tableau des 2 premiers elements seulement
1299 1299
 
1300 1300
 function public_compiler_dist($squelette, $nom, $gram, $sourcefile, string $connect = '') {
1301
-	// Pre-traitement : reperer le charset du squelette, et le convertir
1302
-	// Bonus : supprime le BOM
1303
-	include_spip('inc/charsets');
1304
-	$squelette = transcoder_page($squelette);
1305
-
1306
-	// rendre inertes les echappements de #[](){}<>
1307
-	$i = 0;
1308
-	while (str_contains($squelette, $inerte = '-INERTE' . $i)) {
1309
-		$i++;
1310
-	}
1311
-	$squelette = preg_replace_callback(
1312
-		',\\\\([#[()\]{}<>]),',
1313
-		fn($a) => "$inerte-" . ord($a[1]) . '-',
1314
-		$squelette,
1315
-		-1,
1316
-		$esc
1317
-	);
1318
-
1319
-	$descr = [
1320
-		'nom' => $nom,
1321
-		'gram' => $gram,
1322
-		'sourcefile' => $sourcefile,
1323
-		'squelette' => $squelette
1324
-	];
1325
-
1326
-	// Phraser le squelette, selon sa grammaire
1327
-
1328
-	$boucles = [];
1329
-	$f = charger_fonction('phraser_' . $gram, 'public');
1330
-
1331
-	$squelette = $f($squelette, '', $boucles, $descr);
1332
-
1333
-	$boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect);
1334
-
1335
-	// restituer les echappements
1336
-	if ($esc) {
1337
-		foreach ($boucles as $i => $boucle) {
1338
-			$boucles[$i]->return = preg_replace_callback(
1339
-				",$inerte-(\d+)-,",
1340
-				fn($a) => chr($a[1]),
1341
-				$boucle->return
1342
-			);
1343
-			$boucles[$i]->descr['squelette'] = preg_replace_callback(
1344
-				",$inerte-(\d+)-,",
1345
-				fn($a) => '\\\\' . chr($a[1]),
1346
-				$boucle->descr['squelette']
1347
-			);
1348
-		}
1349
-	}
1350
-
1351
-	$debug = ($boucles and defined('_VAR_MODE') and _VAR_MODE == 'debug');
1352
-	if ($debug) {
1353
-		include_spip('public/decompiler');
1354
-		foreach ($boucles as $id => $boucle) {
1355
-			if ($id) {
1356
-				$decomp = "\n/* BOUCLE " .
1357
-					$boucle->type_requete .
1358
-					' ' .
1359
-					str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1360
-					($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1361
-					" */\n";
1362
-			} else {
1363
-				$decomp = ("\n/*\n" .
1364
-					str_replace('*/', '* /', public_decompiler($squelette, $gram))
1365
-					. "\n*/");
1366
-			}
1367
-			$boucles[$id]->return = $decomp . $boucle->return;
1368
-			$GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1369
-		}
1370
-	}
1371
-
1372
-	return $boucles;
1301
+    // Pre-traitement : reperer le charset du squelette, et le convertir
1302
+    // Bonus : supprime le BOM
1303
+    include_spip('inc/charsets');
1304
+    $squelette = transcoder_page($squelette);
1305
+
1306
+    // rendre inertes les echappements de #[](){}<>
1307
+    $i = 0;
1308
+    while (str_contains($squelette, $inerte = '-INERTE' . $i)) {
1309
+        $i++;
1310
+    }
1311
+    $squelette = preg_replace_callback(
1312
+        ',\\\\([#[()\]{}<>]),',
1313
+        fn($a) => "$inerte-" . ord($a[1]) . '-',
1314
+        $squelette,
1315
+        -1,
1316
+        $esc
1317
+    );
1318
+
1319
+    $descr = [
1320
+        'nom' => $nom,
1321
+        'gram' => $gram,
1322
+        'sourcefile' => $sourcefile,
1323
+        'squelette' => $squelette
1324
+    ];
1325
+
1326
+    // Phraser le squelette, selon sa grammaire
1327
+
1328
+    $boucles = [];
1329
+    $f = charger_fonction('phraser_' . $gram, 'public');
1330
+
1331
+    $squelette = $f($squelette, '', $boucles, $descr);
1332
+
1333
+    $boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect);
1334
+
1335
+    // restituer les echappements
1336
+    if ($esc) {
1337
+        foreach ($boucles as $i => $boucle) {
1338
+            $boucles[$i]->return = preg_replace_callback(
1339
+                ",$inerte-(\d+)-,",
1340
+                fn($a) => chr($a[1]),
1341
+                $boucle->return
1342
+            );
1343
+            $boucles[$i]->descr['squelette'] = preg_replace_callback(
1344
+                ",$inerte-(\d+)-,",
1345
+                fn($a) => '\\\\' . chr($a[1]),
1346
+                $boucle->descr['squelette']
1347
+            );
1348
+        }
1349
+    }
1350
+
1351
+    $debug = ($boucles and defined('_VAR_MODE') and _VAR_MODE == 'debug');
1352
+    if ($debug) {
1353
+        include_spip('public/decompiler');
1354
+        foreach ($boucles as $id => $boucle) {
1355
+            if ($id) {
1356
+                $decomp = "\n/* BOUCLE " .
1357
+                    $boucle->type_requete .
1358
+                    ' ' .
1359
+                    str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1360
+                    ($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1361
+                    " */\n";
1362
+            } else {
1363
+                $decomp = ("\n/*\n" .
1364
+                    str_replace('*/', '* /', public_decompiler($squelette, $gram))
1365
+                    . "\n*/");
1366
+            }
1367
+            $boucles[$id]->return = $decomp . $boucle->return;
1368
+            $GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1369
+        }
1370
+    }
1371
+
1372
+    return $boucles;
1373 1373
 }
1374 1374
 
1375 1375
 // Point d'entree pour arbre de syntaxe abstraite fourni en premier argument
1376 1376
 // Autres specifications comme ci-dessus
1377 1377
 
1378 1378
 function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, string $connect = '') {
1379
-	static $trouver_table;
1380
-	spip_timer('calcul_skel');
1381
-
1382
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
1383
-		$GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
1384
-		$GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;
1385
-
1386
-		if (!isset($GLOBALS['debug_objets']['principal'])) {
1387
-			$GLOBALS['debug_objets']['principal'] = $nom;
1388
-		}
1389
-	}
1390
-	foreach ($boucles as $id => $boucle) {
1391
-		$GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1392
-	}
1393
-	$descr['documents'] = compile_inclure_doublons($squelette);
1394
-
1395
-	// Demander la description des tables une fois pour toutes
1396
-	if (!$trouver_table) {
1397
-		$trouver_table = charger_fonction('trouver_table', 'base');
1398
-	}
1399
-
1400
-	// reperer si les doublons sont demandes
1401
-	// pour un inclure ou une boucle document
1402
-	// c'est utile a la fonction champs_traitements
1403
-	foreach ($boucles as $id => $boucle) {
1404
-		if (!($type = $boucle->type_requete)) {
1405
-			continue;
1406
-		}
1407
-		if (
1408
-			!$descr['documents'] and (
1409
-				(($type == 'documents') and $boucle->doublons) or
1410
-				compile_inclure_doublons($boucle->avant) or
1411
-				compile_inclure_doublons($boucle->apres) or
1412
-				compile_inclure_doublons($boucle->milieu) or
1413
-				compile_inclure_doublons($boucle->altern))
1414
-		) {
1415
-			$descr['documents'] = true;
1416
-		}
1417
-		if ($type != TYPE_RECURSIF) {
1418
-			if (!$boucles[$id]->sql_serveur and $connect) {
1419
-				$boucles[$id]->sql_serveur = $connect;
1420
-			}
1421
-
1422
-			// chercher dans les iterateurs du repertoire iterateur/
1423
-			if (
1424
-				$g = charger_fonction(
1425
-					preg_replace('/\W/', '_', $boucle->type_requete),
1426
-					'iterateur',
1427
-					true
1428
-				)
1429
-			) {
1430
-				$boucles[$id] = $g($boucle);
1431
-
1432
-				// sinon, en cas de requeteur d'un type predefini,
1433
-				// utiliser les informations donnees par le requeteur
1434
-				// cas "php:xx" et "data:xx".
1435
-			} else {
1436
-				if ($boucle->sql_serveur and $requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true)) {
1437
-					$requeteur($boucles, $boucle, $id);
1438
-
1439
-					// utiliser la description des champs transmis
1440
-				} else {
1441
-					$show = $trouver_table($type, $boucles[$id]->sql_serveur);
1442
-					// si la table n'existe pas avec le connecteur par defaut,
1443
-					// c'est peut etre une table qui necessite son connecteur dedie fourni
1444
-					// permet une ecriture allegee (GEO) -> (geo:GEO)
1445
-					if (
1446
-						!$show
1447
-						and $show = $trouver_table($type, strtolower($type))
1448
-					) {
1449
-						$boucles[$id]->sql_serveur = strtolower($type);
1450
-					}
1451
-					if ($show) {
1452
-						$boucles[$id]->show = $show;
1453
-						// recopie les infos les plus importantes
1454
-						$boucles[$id]->primary = $show['key']['PRIMARY KEY'] ?? '';
1455
-						$boucles[$id]->id_table = $x = preg_replace(',^spip_,', '', $show['id_table']);
1456
-						$boucles[$id]->from[$x] = $nom_table = $show['table'];
1457
-						$boucles[$id]->iterateur = 'SQL';
1458
-
1459
-						if (empty($boucles[$id]->descr)) {
1460
-							$boucles[$id]->descr = &$descr;
1461
-						}
1462
-						if (
1463
-							(!$boucles[$id]->jointures)
1464
-							and is_array($show['tables_jointures'])
1465
-							and count($x = $show['tables_jointures'])
1466
-						) {
1467
-							$boucles[$id]->jointures = $x;
1468
-						}
1469
-						if ($boucles[$id]->jointures_explicites) {
1470
-							$jointures = preg_split('/\s+/', $boucles[$id]->jointures_explicites);
1471
-							while ($j = array_pop($jointures)) {
1472
-								array_unshift($boucles[$id]->jointures, $j);
1473
-							}
1474
-						}
1475
-					} else {
1476
-						// Pas une erreur si la table est optionnelle
1477
-						if ($boucles[$id]->table_optionnelle) {
1478
-							$boucles[$id]->type_requete = '';
1479
-						} else {
1480
-							$boucles[$id]->type_requete = false;
1481
-							$boucle = $boucles[$id];
1482
-							$x = (!$boucle->sql_serveur ? '' :
1483
-									($boucle->sql_serveur . ':')) .
1484
-								$type;
1485
-							$msg = [
1486
-								'zbug_table_inconnue',
1487
-								['table' => $x]
1488
-							];
1489
-							erreur_squelette($msg, $boucle);
1490
-						}
1491
-					}
1492
-				}
1493
-			}
1494
-		}
1495
-	}
1496
-
1497
-	// Commencer par reperer les boucles appelees explicitement
1498
-	// car elles indexent les arguments de maniere derogatoire
1499
-	foreach ($boucles as $id => $boucle) {
1500
-		if ($boucle->type_requete == TYPE_RECURSIF and $boucle->param) {
1501
-			$boucles[$id]->descr = &$descr;
1502
-			$rec = &$boucles[$boucle->param[0]];
1503
-			if (!$rec) {
1504
-				$msg = [
1505
-					'zbug_boucle_recursive_undef',
1506
-					['nom' => $boucle->param[0]]
1507
-				];
1508
-				erreur_squelette($msg, $boucle);
1509
-				$boucles[$id]->type_requete = false;
1510
-			} else {
1511
-				$rec->externe = $id;
1512
-				$descr['id_mere'] = $id;
1513
-				$boucles[$id]->return =
1514
-					calculer_liste(
1515
-						[$rec],
1516
-						$descr,
1517
-						$boucles,
1518
-						$boucle->param
1519
-					);
1520
-			}
1521
-		}
1522
-	}
1523
-	foreach ($boucles as $id => $boucle) {
1524
-		$id = strval($id); // attention au type dans index_pile
1525
-		$type = $boucle->type_requete;
1526
-		if ($type and $type != TYPE_RECURSIF) {
1527
-			$res = '';
1528
-			if ($boucle->param) {
1529
-				// retourne un tableau en cas d'erreur
1530
-				$res = calculer_criteres($id, $boucles);
1531
-			}
1532
-			$descr['id_mere'] = $id;
1533
-			$boucles[$id]->return =
1534
-				calculer_liste(
1535
-					$boucle->milieu,
1536
-					$descr,
1537
-					$boucles,
1538
-					$id
1539
-				);
1540
-			// Si les criteres se sont mal compiles
1541
-			// ne pas tenter d'assembler le code final
1542
-			// (mais compiler le corps pour detection d'erreurs)
1543
-			if (is_array($res)) {
1544
-				$boucles[$id]->type_requete = false;
1545
-			}
1546
-		}
1547
-	}
1548
-
1549
-	// idem pour la racine
1550
-	$descr['id_mere'] = '';
1551
-	$corps = calculer_liste($squelette, $descr, $boucles);
1552
-
1553
-
1554
-	// Calcul du corps de toutes les fonctions PHP,
1555
-	// en particulier les requetes SQL et TOTAL_BOUCLE
1556
-	// de'terminables seulement maintenant
1557
-
1558
-	foreach ($boucles as $id => $boucle) {
1559
-		$boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
1560
-		if ($boucle->return === false) {
1561
-			$corps = false;
1562
-			continue;
1563
-		}
1564
-		// appeler la fonction de definition de la boucle
1565
-
1566
-		if ($req = $boucle->type_requete) {
1567
-			// boucle personnalisée ?
1568
-			$table = strtoupper($boucle->type_requete);
1569
-			$serveur = strtolower($boucle->sql_serveur);
1570
-			if (
1571
-				// fonction de boucle avec serveur & table
1572
-				(!$serveur or
1573
-					((!function_exists($f = 'boucle_' . $serveur . '_' . $table))
1574
-						and (!function_exists($f = $f . '_dist'))
1575
-					)
1576
-				)
1577
-				// fonction de boucle avec table
1578
-				and (!function_exists($f = 'boucle_' . $table))
1579
-				and (!function_exists($f = $f . '_dist'))
1580
-			) {
1581
-				// fonction de boucle standard
1582
-				if (!function_exists($f = 'boucle_DEFAUT')) {
1583
-					$f = 'boucle_DEFAUT_dist';
1584
-				}
1585
-			}
1586
-
1587
-			$req = "\n\n\tstatic \$command = array();\n\t" .
1588
-				"static \$connect;\n\t" .
1589
-				"\$command['connect'] = \$connect = " .
1590
-				_q($boucle->sql_serveur) .
1591
-				';' .
1592
-				$f($id, $boucles);
1593
-		} else {
1594
-			$req = ("\n\treturn '';");
1595
-		}
1596
-
1597
-		$boucles[$id]->return =
1598
-			"\n\nfunction BOUCLE" . strtr($id, '-', '_') . $nom .
1599
-			'(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1600
-			$req .
1601
-			"\n}\n";
1602
-	}
1603
-
1604
-	// Au final, si le corps ou un critere au moins s'est mal compile
1605
-	// retourner False, sinon inserer leur decompilation
1606
-	if (is_bool($corps)) {
1607
-		return false;
1608
-	}
1609
-
1610
-	$principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1379
+    static $trouver_table;
1380
+    spip_timer('calcul_skel');
1381
+
1382
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
1383
+        $GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
1384
+        $GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;
1385
+
1386
+        if (!isset($GLOBALS['debug_objets']['principal'])) {
1387
+            $GLOBALS['debug_objets']['principal'] = $nom;
1388
+        }
1389
+    }
1390
+    foreach ($boucles as $id => $boucle) {
1391
+        $GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1392
+    }
1393
+    $descr['documents'] = compile_inclure_doublons($squelette);
1394
+
1395
+    // Demander la description des tables une fois pour toutes
1396
+    if (!$trouver_table) {
1397
+        $trouver_table = charger_fonction('trouver_table', 'base');
1398
+    }
1399
+
1400
+    // reperer si les doublons sont demandes
1401
+    // pour un inclure ou une boucle document
1402
+    // c'est utile a la fonction champs_traitements
1403
+    foreach ($boucles as $id => $boucle) {
1404
+        if (!($type = $boucle->type_requete)) {
1405
+            continue;
1406
+        }
1407
+        if (
1408
+            !$descr['documents'] and (
1409
+                (($type == 'documents') and $boucle->doublons) or
1410
+                compile_inclure_doublons($boucle->avant) or
1411
+                compile_inclure_doublons($boucle->apres) or
1412
+                compile_inclure_doublons($boucle->milieu) or
1413
+                compile_inclure_doublons($boucle->altern))
1414
+        ) {
1415
+            $descr['documents'] = true;
1416
+        }
1417
+        if ($type != TYPE_RECURSIF) {
1418
+            if (!$boucles[$id]->sql_serveur and $connect) {
1419
+                $boucles[$id]->sql_serveur = $connect;
1420
+            }
1421
+
1422
+            // chercher dans les iterateurs du repertoire iterateur/
1423
+            if (
1424
+                $g = charger_fonction(
1425
+                    preg_replace('/\W/', '_', $boucle->type_requete),
1426
+                    'iterateur',
1427
+                    true
1428
+                )
1429
+            ) {
1430
+                $boucles[$id] = $g($boucle);
1431
+
1432
+                // sinon, en cas de requeteur d'un type predefini,
1433
+                // utiliser les informations donnees par le requeteur
1434
+                // cas "php:xx" et "data:xx".
1435
+            } else {
1436
+                if ($boucle->sql_serveur and $requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true)) {
1437
+                    $requeteur($boucles, $boucle, $id);
1438
+
1439
+                    // utiliser la description des champs transmis
1440
+                } else {
1441
+                    $show = $trouver_table($type, $boucles[$id]->sql_serveur);
1442
+                    // si la table n'existe pas avec le connecteur par defaut,
1443
+                    // c'est peut etre une table qui necessite son connecteur dedie fourni
1444
+                    // permet une ecriture allegee (GEO) -> (geo:GEO)
1445
+                    if (
1446
+                        !$show
1447
+                        and $show = $trouver_table($type, strtolower($type))
1448
+                    ) {
1449
+                        $boucles[$id]->sql_serveur = strtolower($type);
1450
+                    }
1451
+                    if ($show) {
1452
+                        $boucles[$id]->show = $show;
1453
+                        // recopie les infos les plus importantes
1454
+                        $boucles[$id]->primary = $show['key']['PRIMARY KEY'] ?? '';
1455
+                        $boucles[$id]->id_table = $x = preg_replace(',^spip_,', '', $show['id_table']);
1456
+                        $boucles[$id]->from[$x] = $nom_table = $show['table'];
1457
+                        $boucles[$id]->iterateur = 'SQL';
1458
+
1459
+                        if (empty($boucles[$id]->descr)) {
1460
+                            $boucles[$id]->descr = &$descr;
1461
+                        }
1462
+                        if (
1463
+                            (!$boucles[$id]->jointures)
1464
+                            and is_array($show['tables_jointures'])
1465
+                            and count($x = $show['tables_jointures'])
1466
+                        ) {
1467
+                            $boucles[$id]->jointures = $x;
1468
+                        }
1469
+                        if ($boucles[$id]->jointures_explicites) {
1470
+                            $jointures = preg_split('/\s+/', $boucles[$id]->jointures_explicites);
1471
+                            while ($j = array_pop($jointures)) {
1472
+                                array_unshift($boucles[$id]->jointures, $j);
1473
+                            }
1474
+                        }
1475
+                    } else {
1476
+                        // Pas une erreur si la table est optionnelle
1477
+                        if ($boucles[$id]->table_optionnelle) {
1478
+                            $boucles[$id]->type_requete = '';
1479
+                        } else {
1480
+                            $boucles[$id]->type_requete = false;
1481
+                            $boucle = $boucles[$id];
1482
+                            $x = (!$boucle->sql_serveur ? '' :
1483
+                                    ($boucle->sql_serveur . ':')) .
1484
+                                $type;
1485
+                            $msg = [
1486
+                                'zbug_table_inconnue',
1487
+                                ['table' => $x]
1488
+                            ];
1489
+                            erreur_squelette($msg, $boucle);
1490
+                        }
1491
+                    }
1492
+                }
1493
+            }
1494
+        }
1495
+    }
1496
+
1497
+    // Commencer par reperer les boucles appelees explicitement
1498
+    // car elles indexent les arguments de maniere derogatoire
1499
+    foreach ($boucles as $id => $boucle) {
1500
+        if ($boucle->type_requete == TYPE_RECURSIF and $boucle->param) {
1501
+            $boucles[$id]->descr = &$descr;
1502
+            $rec = &$boucles[$boucle->param[0]];
1503
+            if (!$rec) {
1504
+                $msg = [
1505
+                    'zbug_boucle_recursive_undef',
1506
+                    ['nom' => $boucle->param[0]]
1507
+                ];
1508
+                erreur_squelette($msg, $boucle);
1509
+                $boucles[$id]->type_requete = false;
1510
+            } else {
1511
+                $rec->externe = $id;
1512
+                $descr['id_mere'] = $id;
1513
+                $boucles[$id]->return =
1514
+                    calculer_liste(
1515
+                        [$rec],
1516
+                        $descr,
1517
+                        $boucles,
1518
+                        $boucle->param
1519
+                    );
1520
+            }
1521
+        }
1522
+    }
1523
+    foreach ($boucles as $id => $boucle) {
1524
+        $id = strval($id); // attention au type dans index_pile
1525
+        $type = $boucle->type_requete;
1526
+        if ($type and $type != TYPE_RECURSIF) {
1527
+            $res = '';
1528
+            if ($boucle->param) {
1529
+                // retourne un tableau en cas d'erreur
1530
+                $res = calculer_criteres($id, $boucles);
1531
+            }
1532
+            $descr['id_mere'] = $id;
1533
+            $boucles[$id]->return =
1534
+                calculer_liste(
1535
+                    $boucle->milieu,
1536
+                    $descr,
1537
+                    $boucles,
1538
+                    $id
1539
+                );
1540
+            // Si les criteres se sont mal compiles
1541
+            // ne pas tenter d'assembler le code final
1542
+            // (mais compiler le corps pour detection d'erreurs)
1543
+            if (is_array($res)) {
1544
+                $boucles[$id]->type_requete = false;
1545
+            }
1546
+        }
1547
+    }
1548
+
1549
+    // idem pour la racine
1550
+    $descr['id_mere'] = '';
1551
+    $corps = calculer_liste($squelette, $descr, $boucles);
1552
+
1553
+
1554
+    // Calcul du corps de toutes les fonctions PHP,
1555
+    // en particulier les requetes SQL et TOTAL_BOUCLE
1556
+    // de'terminables seulement maintenant
1557
+
1558
+    foreach ($boucles as $id => $boucle) {
1559
+        $boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
1560
+        if ($boucle->return === false) {
1561
+            $corps = false;
1562
+            continue;
1563
+        }
1564
+        // appeler la fonction de definition de la boucle
1565
+
1566
+        if ($req = $boucle->type_requete) {
1567
+            // boucle personnalisée ?
1568
+            $table = strtoupper($boucle->type_requete);
1569
+            $serveur = strtolower($boucle->sql_serveur);
1570
+            if (
1571
+                // fonction de boucle avec serveur & table
1572
+                (!$serveur or
1573
+                    ((!function_exists($f = 'boucle_' . $serveur . '_' . $table))
1574
+                        and (!function_exists($f = $f . '_dist'))
1575
+                    )
1576
+                )
1577
+                // fonction de boucle avec table
1578
+                and (!function_exists($f = 'boucle_' . $table))
1579
+                and (!function_exists($f = $f . '_dist'))
1580
+            ) {
1581
+                // fonction de boucle standard
1582
+                if (!function_exists($f = 'boucle_DEFAUT')) {
1583
+                    $f = 'boucle_DEFAUT_dist';
1584
+                }
1585
+            }
1586
+
1587
+            $req = "\n\n\tstatic \$command = array();\n\t" .
1588
+                "static \$connect;\n\t" .
1589
+                "\$command['connect'] = \$connect = " .
1590
+                _q($boucle->sql_serveur) .
1591
+                ';' .
1592
+                $f($id, $boucles);
1593
+        } else {
1594
+            $req = ("\n\treturn '';");
1595
+        }
1596
+
1597
+        $boucles[$id]->return =
1598
+            "\n\nfunction BOUCLE" . strtr($id, '-', '_') . $nom .
1599
+            '(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1600
+            $req .
1601
+            "\n}\n";
1602
+    }
1603
+
1604
+    // Au final, si le corps ou un critere au moins s'est mal compile
1605
+    // retourner False, sinon inserer leur decompilation
1606
+    if (is_bool($corps)) {
1607
+        return false;
1608
+    }
1609
+
1610
+    $principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1611 1611
 '
1612
-		// reporter de maniere securisee les doublons inclus
1613
-		. '
1612
+        // reporter de maniere securisee les doublons inclus
1613
+        . '
1614 1614
 	if (isset($Pile[0]["doublons"]) AND is_array($Pile[0]["doublons"]))
1615 1615
 		$doublons = nettoyer_env_doublons($Pile[0]["doublons"]);
1616 1616
 
1617 1617
 	$connect = ' .
1618
-		_q($connect) . ';
1618
+        _q($connect) . ';
1619 1619
 	$page = ' .
1620
-		// ATTENTION, le calcul de l'expression $corps affectera $Cache
1621
-		// c'est pourquoi on l'affecte a la variable auxiliaire $page.
1622
-		// avant de referencer $Cache
1623
-		$corps . ';
1620
+        // ATTENTION, le calcul de l'expression $corps affectera $Cache
1621
+        // c'est pourquoi on l'affecte a la variable auxiliaire $page.
1622
+        // avant de referencer $Cache
1623
+        $corps . ';
1624 1624
 
1625 1625
 	return analyse_resultat_skel(' . var_export($nom, true)
1626
-		. ', $Cache, $page, ' . var_export($sourcefile, true) . ');
1626
+        . ', $Cache, $page, ' . var_export($sourcefile, true) . ');
1627 1627
 }';
1628 1628
 
1629
-	$secondes = spip_timer('calcul_skel');
1630
-	spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
1631
-	// $connect n'est pas sûr : on nettoie
1632
-	$connect = preg_replace(',[^\w],', '', $connect);
1629
+    $secondes = spip_timer('calcul_skel');
1630
+    spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
1631
+    // $connect n'est pas sûr : on nettoie
1632
+    $connect = preg_replace(',[^\w],', '', $connect);
1633 1633
 
1634
-	// Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple
1635
-	$code = new Boucle();
1636
-	$code->descr = $descr;
1637
-	$code->return = '
1634
+    // Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple
1635
+    $code = new Boucle();
1636
+    $code->descr = $descr;
1637
+    $code->return = '
1638 1638
 //
1639 1639
 // Fonction principale du squelette ' .
1640
-		$sourcefile .
1641
-		($connect ? " pour $connect" : '') .
1642
-		(!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1643
-		"\n//\n" .
1644
-		$principal;
1640
+        $sourcefile .
1641
+        ($connect ? " pour $connect" : '') .
1642
+        (!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1643
+        "\n//\n" .
1644
+        $principal;
1645 1645
 
1646
-	$boucles[''] = $code;
1646
+    $boucles[''] = $code;
1647 1647
 
1648
-	return $boucles;
1648
+    return $boucles;
1649 1649
 }
1650 1650
 
1651 1651
 
@@ -1662,18 +1662,18 @@  discard block
 block discarded – undo
1662 1662
  *
1663 1663
  **/
1664 1664
 function requeteur_php_dist(&$boucles, &$boucle, &$id) {
1665
-	if (class_exists($boucle->type_requete)) {
1666
-		$g = charger_fonction('php', 'iterateur');
1667
-		$boucles[$id] = $g($boucle, $boucle->type_requete);
1668
-	} else {
1669
-		$x = $boucle->type_requete;
1670
-		$boucle->type_requete = false;
1671
-		$msg = [
1672
-			'zbug_iterateur_inconnu',
1673
-			['iterateur' => $x]
1674
-		];
1675
-		erreur_squelette($msg, $boucle);
1676
-	}
1665
+    if (class_exists($boucle->type_requete)) {
1666
+        $g = charger_fonction('php', 'iterateur');
1667
+        $boucles[$id] = $g($boucle, $boucle->type_requete);
1668
+    } else {
1669
+        $x = $boucle->type_requete;
1670
+        $boucle->type_requete = false;
1671
+        $msg = [
1672
+            'zbug_iterateur_inconnu',
1673
+            ['iterateur' => $x]
1674
+        ];
1675
+        erreur_squelette($msg, $boucle);
1676
+    }
1677 1677
 }
1678 1678
 
1679 1679
 
@@ -1691,22 +1691,22 @@  discard block
 block discarded – undo
1691 1691
  *
1692 1692
  **/
1693 1693
 function requeteur_data_dist(&$boucles, &$boucle, &$id) {
1694
-	include_spip('iterateur/data');
1695
-	if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1696
-		$g = charger_fonction('data', 'iterateur');
1697
-		$boucles[$id] = $g($boucle);
1698
-		// from[0] stocke le type de data (rss, yql, ...)
1699
-		$boucles[$id]->from[] = $boucle->type_requete;
1700
-	} else {
1701
-		$x = $boucle->type_requete;
1702
-		$boucle->type_requete = false;
1703
-		$msg = [
1704
-			'zbug_requeteur_inconnu',
1705
-			[
1706
-				'requeteur' => 'data',
1707
-				'type' => $x
1708
-			]
1709
-		];
1710
-		erreur_squelette($msg, $boucle);
1711
-	}
1694
+    include_spip('iterateur/data');
1695
+    if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1696
+        $g = charger_fonction('data', 'iterateur');
1697
+        $boucles[$id] = $g($boucle);
1698
+        // from[0] stocke le type de data (rss, yql, ...)
1699
+        $boucles[$id]->from[] = $boucle->type_requete;
1700
+    } else {
1701
+        $x = $boucle->type_requete;
1702
+        $boucle->type_requete = false;
1703
+        $msg = [
1704
+            'zbug_requeteur_inconnu',
1705
+            [
1706
+                'requeteur' => 'data',
1707
+                'type' => $x
1708
+            ]
1709
+        ];
1710
+        erreur_squelette($msg, $boucle);
1711
+    }
1712 1712
 }
Please login to merge, or discard this patch.
Spacing   +109 added lines, -118 removed lines patch added patch discarded remove patch
@@ -124,7 +124,7 @@  discard block
 block discarded – undo
124 124
 						: calculer_liste($val, $p->descr, $boucles, $id_boucle);
125 125
 					if ($var !== 1) {
126 126
 						$val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
127
-							. $val . ($echap ? ") . '" : ' ');
127
+							. $val.($echap ? ") . '" : ' ');
128 128
 					} else {
129 129
 						$val = $echap ? "'.$val.'" : $val;
130 130
 					}
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
 	if (!$lang) {
146 146
 		$lang = '$GLOBALS["spip_lang"]';
147 147
 	}
148
-	$l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : ' ');
148
+	$l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ").$lang.($echap ? ") . '" : ' ');
149 149
 
150 150
 	return $l;
151 151
 }
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
 	$_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
176 176
 	if (is_string($p->texte)) {
177 177
 		$fichier = $p->texte;
178
-		$code = '"' . str_replace('"', '\"', $fichier) . '"';
178
+		$code = '"'.str_replace('"', '\"', $fichier).'"';
179 179
 	} else {
180 180
 		$code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
181 181
 		if ($code and preg_match("/^'([^']*)'/s", $code, $r)) {
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
 		return false;
225 225
 	} // j'aurais voulu toucher le fond ...
226 226
 
227
-	$contexte = 'array(' . $_contexte . ')';
227
+	$contexte = 'array('.$_contexte.')';
228 228
 
229 229
 	if ($env) {
230 230
 		$contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
@@ -239,16 +239,16 @@  discard block
 block discarded – undo
239 239
 			$_options[] = $ajax;
240 240
 		}
241 241
 		$code = " ' . argumenter_squelette($code) . '";
242
-		$code = 'echo ' . sprintf(
242
+		$code = 'echo '.sprintf(
243 243
 			CODE_RECUPERER_FOND,
244 244
 			$code,
245 245
 			$contexte,
246 246
 			implode(',', $_options),
247 247
 			"_request(\\'connect\\') ?? \\'\\'"
248
-		) . ';';
248
+		).';';
249 249
 	}
250 250
 
251
-	return "\n'<'.'" . '?php ' . $code . "\n?'." . "'>'";
251
+	return "\n'<'.'".'?php '.$code."\n?'."."'>'";
252 252
 }
253 253
 
254 254
 
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
 					$id = $id_table;
329 329
 					$statut = preg_replace(',\W,', '', $s['champ']); // securite
330 330
 				}
331
-				$mstatut = $id . '.' . $statut;
331
+				$mstatut = $id.'.'.$statut;
332 332
 
333 333
 				$arg_ignore_previsu = ($ignore_previsu ? ',true' : '');
334 334
 				include_spip('public/quete');
@@ -336,11 +336,11 @@  discard block
 block discarded – undo
336 336
 					isset($s['post_date']) and $s['post_date']
337 337
 					and $GLOBALS['meta']['post_dates'] == 'non'
338 338
 				) {
339
-					$date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
339
+					$date = $id.'.'.preg_replace(',\W,', '', $s['post_date']); // securite
340 340
 					array_unshift(
341 341
 						$boucle->where,
342 342
 						$echapper ?
343
-							"\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
343
+							"\nquete_condition_postdates('$date',"._q($boucle->sql_serveur)."$arg_ignore_previsu)"
344 344
 							:
345 345
 							quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
346 346
 					);
@@ -349,9 +349,9 @@  discard block
 block discarded – undo
349 349
 					$boucle->where,
350 350
 					$echapper ?
351 351
 						"\nquete_condition_statut('$mstatut',"
352
-						. _q($s['previsu']) . ','
353
-						. _q($s['publie']) . ','
354
-						. _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
352
+						. _q($s['previsu']).','
353
+						. _q($s['publie']).','
354
+						. _q($boucle->sql_serveur)."$arg_ignore_previsu)"
355 355
 						:
356 356
 						quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
357 357
 				);
@@ -385,14 +385,14 @@  discard block
 block discarded – undo
385 385
 	if (_request('var_mode_affiche') != 'resultat') {
386 386
 		$trace = '';
387 387
 	} else {
388
-		$_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
388
+		$_trace = $boucles[$id_boucle]->descr['nom'].$id_boucle;
389 389
 		$_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
390 390
 		$trace = "
391 391
 		if (empty($_trace)) {
392 392
 			$_trace = [];
393 393
 		}
394 394
 		if (count($_trace) < 3) {
395
-			$_trace" . '[] = $t0;
395
+			$_trace".'[] = $t0;
396 396
 		}';
397 397
 	}
398 398
 
@@ -426,7 +426,7 @@  discard block
 block discarded – undo
426 426
 	return
427 427
 		// Numrows[$nom] peut ne pas être encore defini
428 428
 		"\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
429
-		. "\n\t\$t0 = " . $boucles[$id_boucle]->return . ';'
429
+		. "\n\t\$t0 = ".$boucles[$id_boucle]->return.';'
430 430
 		. "\n\t\$Numrows['$nom'] = (\$save_numrows);"
431 431
 		. $trace
432 432
 		. "\n\treturn \$t0;";
@@ -494,7 +494,7 @@  discard block
 block discarded – undo
494 494
 	// faudrait expanser le foreach a la compil, car y en a souvent qu'un
495 495
 	// et puis faire un [] plutot qu'un "','."
496 496
 	if ($boucle->doublons) {
497
-		$corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
497
+		$corps .= "\n\t\t\tforeach(".$boucle->doublons.' as $k) $doublons[$k] .= "," . '.
498 498
 			index_pile($id_boucle, $primary, $boucles)
499 499
 			. "; // doublons\n";
500 500
 	}
@@ -522,13 +522,13 @@  discard block
 block discarded – undo
522 522
 		$corps .=
523 523
 			"\n\t\tlang_select_public("
524 524
 			. index_pile($id_boucle, 'lang', $boucles)
525
-			. ", '" . $boucle->lang_select . "'"
525
+			. ", '".$boucle->lang_select."'"
526 526
 			. (in_array($type_boucle, [
527 527
 				'articles',
528 528
 				'rubriques',
529 529
 				'hierarchie',
530 530
 				'breves'
531
-			]) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
531
+			]) ? ', '.index_pile($id_boucle, 'titre', $boucles) : '')
532 532
 			. ');';
533 533
 	} else {
534 534
 		$init_lang = '';
@@ -550,20 +550,16 @@  discard block
 block discarded – undo
550 550
 
551 551
 	// gestion optimale des separateurs et des boucles constantes
552 552
 	if (is_countable($boucle->separateur) ? count($boucle->separateur) : 0) {
553
-		$code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
553
+		$code_sep = ("'".str_replace("'", "\'", join('', $boucle->separateur))."'");
554 554
 	}
555 555
 
556 556
 	$corps .=
557 557
 		((!$boucle->separateur) ?
558
-			(($constant && !$corps && !$flag_cpt) ? $return :
559
-				(($return === "''") ? '' :
560
-					("\n\t\t" . '$t0 .= ' . $return . ';'))) :
561
-			("\n\t\t\$t1 " .
558
+			(($constant && !$corps && !$flag_cpt) ? $return : (($return === "''") ? '' : ("\n\t\t".'$t0 .= '.$return.';'))) : ("\n\t\t\$t1 ".
562 559
 				((strpos($return, '$t1.') === 0) ?
563
-					('.=' . substr($return, 4)) :
564
-					('= ' . $return)) .
565
-				";\n\t\t" .
566
-				'$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
560
+					('.='.substr($return, 4)) : ('= '.$return)).
561
+				";\n\t\t".
562
+				'$t0 .= ((strlen($t1) && strlen($t0)) ? '.$code_sep." : '') . \$t1;"));
567 563
 
568 564
 	// Calculer les invalideurs si c'est une boucle non constante et si on
569 565
 	// souhaite invalider ces elements
@@ -645,7 +641,7 @@  discard block
 block discarded – undo
645 641
 		$corps,
646 642
 		$fin_lang,
647 643
 		$trace,
648
-		'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
644
+		'BOUCLE'.$id_boucle.' @ '.($boucle->descr['sourcefile'])
649 645
 	);
650 646
 
651 647
 	return $a;
@@ -665,25 +661,24 @@  discard block
 block discarded – undo
665 661
  **/
666 662
 function calculer_requete_sql($boucle) {
667 663
 	$init = [];
668
-	$init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
669
-	$init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
664
+	$init[] = calculer_dec('table', "'".$boucle->id_table."'");
665
+	$init[] = calculer_dec('id', "'".$boucle->id_boucle."'");
670 666
 	# En absence de champ c'est un decompte :
671 667
 	$init[] = calculer_dec('from', calculer_from($boucle));
672 668
 	$init[] = calculer_dec('type', calculer_from_type($boucle));
673 669
 	$init[] = calculer_dec(
674 670
 		'groupby',
675
-		'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ')'
671
+		'array('.(($g = join("\",\n\t\t\"", $boucle->group)) ? '"'.$g.'"' : '').')'
676 672
 	);
677
-	$init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . '")');
678
-	$init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ')');
673
+	$init[] = calculer_dec('select', 'array("'.join("\",\n\t\t\"", $boucle->select).'")');
674
+	$init[] = calculer_dec('orderby', 'array('.calculer_order($boucle).')');
679 675
 	$init[] = calculer_dec('where', calculer_dump_array($boucle->where));
680 676
 	$init[] = calculer_dec('join', calculer_dump_join($boucle->join));
681 677
 	$init[] = calculer_dec(
682 678
 		'limit',
683 679
 		(
684 680
 			strpos($boucle->limit, 'intval') === false ?
685
-			"'" . ($boucle->limit) . "'" :
686
-			$boucle->limit
681
+			"'".($boucle->limit)."'" : $boucle->limit
687 682
 		)
688 683
 	);
689 684
 	$init[] = calculer_dec('having', calculer_dump_array($boucle->having));
@@ -692,17 +687,17 @@  discard block
 block discarded – undo
692 687
 	// ou recalculée à chaque passage (vide)
693 688
 	foreach ($init as $i) {
694 689
 		if (reset($i)) {
695
-			$s .= "\n\t\t" . end($i);
690
+			$s .= "\n\t\t".end($i);
696 691
 		} # statique
697 692
 		else {
698
-			$d .= "\n\t" . end($i);
693
+			$d .= "\n\t".end($i);
699 694
 		} # dynamique
700 695
 	}
701 696
 
702 697
 	return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
703 698
 	. $boucle->in
704 699
 	. $boucle->hash
705
-	. "\n\t" . 'if (!isset($command[\'table\'])) {'
700
+	. "\n\t".'if (!isset($command[\'table\'])) {'
706 701
 	. $s
707 702
 	. "\n\t}"
708 703
 	. $d;
@@ -757,7 +752,7 @@  discard block
 block discarded – undo
757 752
 	];
758 753
 
759 754
 	$p->id_boucle = $context_compil[2] ?? '';
760
-	$p->ligne = (int)($context_compil[3] ?? 0);
755
+	$p->ligne = (int) ($context_compil[3] ?? 0);
761 756
 	$p->lang = $context_compil[4] ?? '';
762 757
 
763 758
 	return $p;
@@ -786,7 +781,7 @@  discard block
 block discarded – undo
786 781
  *    - index 1 : Code de l'affectation
787 782
  **/
788 783
 function calculer_dec($nom, $val) {
789
-	$static = 'if (!isset($command[\'' . $nom . '\'])) ';
784
+	$static = 'if (!isset($command[\''.$nom.'\'])) ';
790 785
 	// si une variable apparait dans le calcul de la clause
791 786
 	// il faut la re-evaluer a chaque passage
792 787
 	if (
@@ -803,7 +798,7 @@  discard block
 block discarded – undo
803 798
 		$static = '';
804 799
 	}
805 800
 
806
-	return [$static, '$command[\'' . $nom . '\'] = ' . $val . ';'];
801
+	return [$static, '$command[\''.$nom.'\'] = '.$val.';'];
807 802
 }
808 803
 
809 804
 /**
@@ -828,27 +823,27 @@  discard block
 block discarded – undo
828 823
 	}
829 824
 	$res = '';
830 825
 	if ($a and $a[0] == "'?'") {
831
-		return ('(' . calculer_dump_array($a[1]) .
832
-			' ? ' . calculer_dump_array($a[2]) .
833
-			' : ' . calculer_dump_array($a[3]) .
826
+		return ('('.calculer_dump_array($a[1]).
827
+			' ? '.calculer_dump_array($a[2]).
828
+			' : '.calculer_dump_array($a[3]).
834 829
 			')');
835 830
 	} else {
836 831
 		foreach ($a as $k => $v) {
837
-			$showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
838
-			$res .= ', ' . $showk . calculer_dump_array($v);
832
+			$showk = (is_numeric($k) ? '' : sql_quote($k).' => ');
833
+			$res .= ', '.$showk.calculer_dump_array($v);
839 834
 		}
840 835
 
841
-		return "\n\t\t\tarray(" . substr($res, 2) . ')';
836
+		return "\n\t\t\tarray(".substr($res, 2).')';
842 837
 	}
843 838
 }
844 839
 
845 840
 function calculer_dump_join($a) {
846 841
 	$res = '';
847 842
 	foreach ($a as $k => $v) {
848
-		$res .= ", '$k' => array(" . implode(',', $v) . ')';
843
+		$res .= ", '$k' => array(".implode(',', $v).')';
849 844
 	}
850 845
 
851
-	return 'array(' . substr($res, 2) . ')';
846
+	return 'array('.substr($res, 2).')';
852 847
 }
853 848
 
854 849
 /**
@@ -865,7 +860,7 @@  discard block
 block discarded – undo
865 860
 		$res .= ",'$k' => '$v'";
866 861
 	}
867 862
 
868
-	return 'array(' . substr($res, 1) . ')';
863
+	return 'array('.substr($res, 1).')';
869 864
 }
870 865
 
871 866
 /**
@@ -883,7 +878,7 @@  discard block
 block discarded – undo
883 878
 		$res .= ",'$k' => '$v'";
884 879
 	}
885 880
 
886
-	return 'array(' . substr($res, 1) . ')';
881
+	return 'array('.substr($res, 1).')';
887 882
 }
888 883
 
889 884
 function calculer_order(&$boucle) {
@@ -952,19 +947,19 @@  discard block
 block discarded – undo
952 947
 				) {
953 948
 					$res .= " .\n$tab$code";
954 949
 				} else {
955
-					$res = substr($res, 0, -1) . substr($code, 1);
950
+					$res = substr($res, 0, -1).substr($code, 1);
956 951
 				}
957 952
 			}
958 953
 
959
-			return '(' . substr($res, 2 + $descr['niv']) . ')';
954
+			return '('.substr($res, 2 + $descr['niv']).')';
960 955
 		}
961 956
 	} else {
962
-		$nom = $descr['nom'] . $id_boucle . ($descr['niv'] ?: '');
957
+		$nom = $descr['nom'].$id_boucle.($descr['niv'] ?: '');
963 958
 
964
-		return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(
959
+		return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(".join(
965 960
 			" ,\n$tab",
966 961
 			$codes
967
-		) . ')))';
962
+		).')))';
968 963
 	}
969 964
 }
970 965
 
@@ -1000,7 +995,7 @@  discard block
 block discarded – undo
1000 995
 			// texte seul
1001 996
 			case 'texte':
1002 997
 				$code = sandbox_composer_texte($p->texte, $p);
1003
-				$commentaire = strlen($p->texte) . ' signes';
998
+				$commentaire = strlen($p->texte).' signes';
1004 999
 				$avant = '';
1005 1000
 				$apres = '';
1006 1001
 				$altern = "''";
@@ -1009,14 +1004,14 @@  discard block
 block discarded – undo
1009 1004
 			case 'polyglotte':
1010 1005
 				$code = '';
1011 1006
 				foreach ($p->traductions as $k => $v) {
1012
-					$code .= ",'" .
1013
-						str_replace(['\\', "'"], ['\\\\', "\\'"], $k) .
1014
-						"' => '" .
1015
-						str_replace(['\\', "'"], ['\\\\', "\\'"], $v) .
1007
+					$code .= ",'".
1008
+						str_replace(['\\', "'"], ['\\\\', "\\'"], $k).
1009
+						"' => '".
1010
+						str_replace(['\\', "'"], ['\\\\', "\\'"], $v).
1016 1011
 						"'";
1017 1012
 				}
1018
-				$code = 'choisir_traduction(array(' .
1019
-					substr($code, 1) .
1013
+				$code = 'choisir_traduction(array('.
1014
+					substr($code, 1).
1020 1015
 					'))';
1021 1016
 				$commentaire = '&';
1022 1017
 				$avant = '';
@@ -1032,7 +1027,7 @@  discard block
 block discarded – undo
1032 1027
 					$err_e_c = true;
1033 1028
 					$code = "''";
1034 1029
 				} else {
1035
-					$commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1030
+					$commentaire = '<INCLURE '.addslashes(str_replace("\n", ' ', $code)).'>';
1036 1031
 					$avant = '';
1037 1032
 					$apres = '';
1038 1033
 					$altern = "''";
@@ -1061,8 +1056,8 @@  discard block
 block discarded – undo
1061 1056
 					$err_e_c = true;
1062 1057
 					$code = "''";
1063 1058
 				} else {
1064
-					$code = 'BOUCLE' .
1065
-						str_replace('-', '_', $nom) . $descr['nom'] .
1059
+					$code = 'BOUCLE'.
1060
+						str_replace('-', '_', $nom).$descr['nom'].
1066 1061
 						'($Cache, $Pile, $doublons, $Numrows, $SP)';
1067 1062
 					$commentaire = "?$nom";
1068 1063
 					if (
@@ -1104,24 +1099,22 @@  discard block
 block discarded – undo
1104 1099
 				foreach ($p->arg as $k => $v) {
1105 1100
 					$_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1106 1101
 					if ($k) {
1107
-						$l[] = _q($k) . ' => ' . $_v;
1102
+						$l[] = _q($k).' => '.$_v;
1108 1103
 					} else {
1109 1104
 						$code = $_v;
1110 1105
 					}
1111 1106
 				}
1112 1107
 				// Si le module n'est pas fourni, l'expliciter sauf si calculé
1113 1108
 				if ($p->module) {
1114
-					$m = $p->module . ':' . $p->nom_champ;
1109
+					$m = $p->module.':'.$p->nom_champ;
1115 1110
 				} elseif ($p->nom_champ) {
1116
-					$m = MODULES_IDIOMES . ':' . $p->nom_champ;
1111
+					$m = MODULES_IDIOMES.':'.$p->nom_champ;
1117 1112
 				} else {
1118 1113
 					$m = '';
1119 1114
 				}
1120 1115
 
1121
-				$code = (!$code ? "'$m'" :
1122
-						($m ? "'$m' . $code" :
1123
-							("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1124
-					. (!$l ? '' : (', array(' . implode(",\n", $l) . ')'));
1116
+				$code = (!$code ? "'$m'" : ($m ? "'$m' . $code" : ("(strpos(\$x=$code, ':') ? \$x : ('".MODULES_IDIOMES.":' . \$x))")))
1117
+					. (!$l ? '' : (', array('.implode(",\n", $l).')'));
1125 1118
 				$code = "_T($code)";
1126 1119
 				if ($p->param) {
1127 1120
 					$p->id_boucle = $id_boucle;
@@ -1143,7 +1136,7 @@  discard block
 block discarded – undo
1143 1136
 				$p->type_requete = $type;
1144 1137
 
1145 1138
 				$code = calculer_champ($p);
1146
-				$commentaire = '#' . $p->nom_champ . $p->etoile;
1139
+				$commentaire = '#'.$p->nom_champ.$p->etoile;
1147 1140
 				$avant = calculer_liste(
1148 1141
 					$p->avant,
1149 1142
 					$descr,
@@ -1183,10 +1176,9 @@  discard block
 block discarded – undo
1183 1176
 		if ($code != "''") {
1184 1177
 			$code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1185 1178
 			$codes[] = (($mode == 'validation') ?
1186
-				"array($code, '$commentaire', " . $p->ligne . ')'
1179
+				"array($code, '$commentaire', ".$p->ligne.')'
1187 1180
 				: (($mode == 'code') ?
1188
-					"\n// $commentaire\n$code" :
1189
-					$code));
1181
+					"\n// $commentaire\n$code" : $code));
1190 1182
 		}
1191 1183
 	} // foreach
1192 1184
 
@@ -1242,19 +1234,19 @@  discard block
 block discarded – undo
1242 1234
 			$cond = '';
1243 1235
 		} elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1244 1236
 			$t = $r[2];
1245
-			$cond = '!' . $r[1];
1237
+			$cond = '!'.$r[1];
1246 1238
 		} else {
1247 1239
 			if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) {
1248 1240
 				$t = $r[2];
1249 1241
 				$cond = $r[1];
1250 1242
 			} else {
1251
-				$t = '$t' . $n;
1243
+				$t = '$t'.$n;
1252 1244
 				$cond = "($t = $code)!==''";
1253 1245
 			}
1254 1246
 		}
1255 1247
 
1256
-		$res = (!$avant ? '' : "$avant . ") .
1257
-			$t .
1248
+		$res = (!$avant ? '' : "$avant . ").
1249
+			$t.
1258 1250
 			(!$apres ? '' : " . $apres");
1259 1251
 
1260 1252
 		if ($res !== $t) {
@@ -1305,12 +1297,12 @@  discard block
 block discarded – undo
1305 1297
 
1306 1298
 	// rendre inertes les echappements de #[](){}<>
1307 1299
 	$i = 0;
1308
-	while (str_contains($squelette, $inerte = '-INERTE' . $i)) {
1300
+	while (str_contains($squelette, $inerte = '-INERTE'.$i)) {
1309 1301
 		$i++;
1310 1302
 	}
1311 1303
 	$squelette = preg_replace_callback(
1312 1304
 		',\\\\([#[()\]{}<>]),',
1313
-		fn($a) => "$inerte-" . ord($a[1]) . '-',
1305
+		fn($a) => "$inerte-".ord($a[1]).'-',
1314 1306
 		$squelette,
1315 1307
 		-1,
1316 1308
 		$esc
@@ -1326,7 +1318,7 @@  discard block
 block discarded – undo
1326 1318
 	// Phraser le squelette, selon sa grammaire
1327 1319
 
1328 1320
 	$boucles = [];
1329
-	$f = charger_fonction('phraser_' . $gram, 'public');
1321
+	$f = charger_fonction('phraser_'.$gram, 'public');
1330 1322
 
1331 1323
 	$squelette = $f($squelette, '', $boucles, $descr);
1332 1324
 
@@ -1342,7 +1334,7 @@  discard block
 block discarded – undo
1342 1334
 			);
1343 1335
 			$boucles[$i]->descr['squelette'] = preg_replace_callback(
1344 1336
 				",$inerte-(\d+)-,",
1345
-				fn($a) => '\\\\' . chr($a[1]),
1337
+				fn($a) => '\\\\'.chr($a[1]),
1346 1338
 				$boucle->descr['squelette']
1347 1339
 			);
1348 1340
 		}
@@ -1353,19 +1345,19 @@  discard block
 block discarded – undo
1353 1345
 		include_spip('public/decompiler');
1354 1346
 		foreach ($boucles as $id => $boucle) {
1355 1347
 			if ($id) {
1356
-				$decomp = "\n/* BOUCLE " .
1357
-					$boucle->type_requete .
1358
-					' ' .
1359
-					str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1360
-					($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1348
+				$decomp = "\n/* BOUCLE ".
1349
+					$boucle->type_requete.
1350
+					' '.
1351
+					str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')).
1352
+					($boucle->debug ? "\n *\n * ".implode("\n * ", $boucle->debug)."\n" : '').
1361 1353
 					" */\n";
1362 1354
 			} else {
1363
-				$decomp = ("\n/*\n" .
1355
+				$decomp = ("\n/*\n".
1364 1356
 					str_replace('*/', '* /', public_decompiler($squelette, $gram))
1365 1357
 					. "\n*/");
1366 1358
 			}
1367
-			$boucles[$id]->return = $decomp . $boucle->return;
1368
-			$GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1359
+			$boucles[$id]->return = $decomp.$boucle->return;
1360
+			$GLOBALS['debug_objets']['code'][$nom.$id] = $boucle->return;
1369 1361
 		}
1370 1362
 	}
1371 1363
 
@@ -1388,7 +1380,7 @@  discard block
 block discarded – undo
1388 1380
 		}
1389 1381
 	}
1390 1382
 	foreach ($boucles as $id => $boucle) {
1391
-		$GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1383
+		$GLOBALS['debug_objets']['boucle'][$nom.$id] = $boucle;
1392 1384
 	}
1393 1385
 	$descr['documents'] = compile_inclure_doublons($squelette);
1394 1386
 
@@ -1479,8 +1471,7 @@  discard block
 block discarded – undo
1479 1471
 						} else {
1480 1472
 							$boucles[$id]->type_requete = false;
1481 1473
 							$boucle = $boucles[$id];
1482
-							$x = (!$boucle->sql_serveur ? '' :
1483
-									($boucle->sql_serveur . ':')) .
1474
+							$x = (!$boucle->sql_serveur ? '' : ($boucle->sql_serveur.':')).
1484 1475
 								$type;
1485 1476
 							$msg = [
1486 1477
 								'zbug_table_inconnue',
@@ -1570,13 +1561,13 @@  discard block
 block discarded – undo
1570 1561
 			if (
1571 1562
 				// fonction de boucle avec serveur & table
1572 1563
 				(!$serveur or
1573
-					((!function_exists($f = 'boucle_' . $serveur . '_' . $table))
1574
-						and (!function_exists($f = $f . '_dist'))
1564
+					((!function_exists($f = 'boucle_'.$serveur.'_'.$table))
1565
+						and (!function_exists($f = $f.'_dist'))
1575 1566
 					)
1576 1567
 				)
1577 1568
 				// fonction de boucle avec table
1578
-				and (!function_exists($f = 'boucle_' . $table))
1579
-				and (!function_exists($f = $f . '_dist'))
1569
+				and (!function_exists($f = 'boucle_'.$table))
1570
+				and (!function_exists($f = $f.'_dist'))
1580 1571
 			) {
1581 1572
 				// fonction de boucle standard
1582 1573
 				if (!function_exists($f = 'boucle_DEFAUT')) {
@@ -1584,20 +1575,20 @@  discard block
 block discarded – undo
1584 1575
 				}
1585 1576
 			}
1586 1577
 
1587
-			$req = "\n\n\tstatic \$command = array();\n\t" .
1588
-				"static \$connect;\n\t" .
1589
-				"\$command['connect'] = \$connect = " .
1590
-				_q($boucle->sql_serveur) .
1591
-				';' .
1578
+			$req = "\n\n\tstatic \$command = array();\n\t".
1579
+				"static \$connect;\n\t".
1580
+				"\$command['connect'] = \$connect = ".
1581
+				_q($boucle->sql_serveur).
1582
+				';'.
1592 1583
 				$f($id, $boucles);
1593 1584
 		} else {
1594 1585
 			$req = ("\n\treturn '';");
1595 1586
 		}
1596 1587
 
1597 1588
 		$boucles[$id]->return =
1598
-			"\n\nfunction BOUCLE" . strtr($id, '-', '_') . $nom .
1599
-			'(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1600
-			$req .
1589
+			"\n\nfunction BOUCLE".strtr($id, '-', '_').$nom.
1590
+			'(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {'.
1591
+			$req.
1601 1592
 			"\n}\n";
1602 1593
 	}
1603 1594
 
@@ -1607,7 +1598,7 @@  discard block
 block discarded – undo
1607 1598
 		return false;
1608 1599
 	}
1609 1600
 
1610
-	$principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1601
+	$principal = "\nfunction ".$nom.'($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1611 1602
 '
1612 1603
 		// reporter de maniere securisee les doublons inclus
1613 1604
 		. '
@@ -1615,15 +1606,15 @@  discard block
 block discarded – undo
1615 1606
 		$doublons = nettoyer_env_doublons($Pile[0]["doublons"]);
1616 1607
 
1617 1608
 	$connect = ' .
1618
-		_q($connect) . ';
1609
+		_q($connect).';
1619 1610
 	$page = ' .
1620 1611
 		// ATTENTION, le calcul de l'expression $corps affectera $Cache
1621 1612
 		// c'est pourquoi on l'affecte a la variable auxiliaire $page.
1622 1613
 		// avant de referencer $Cache
1623
-		$corps . ';
1614
+		$corps.';
1624 1615
 
1625 1616
 	return analyse_resultat_skel(' . var_export($nom, true)
1626
-		. ', $Cache, $page, ' . var_export($sourcefile, true) . ');
1617
+		. ', $Cache, $page, '.var_export($sourcefile, true).');
1627 1618
 }';
1628 1619
 
1629 1620
 	$secondes = spip_timer('calcul_skel');
@@ -1637,10 +1628,10 @@  discard block
 block discarded – undo
1637 1628
 	$code->return = '
1638 1629
 //
1639 1630
 // Fonction principale du squelette ' .
1640
-		$sourcefile .
1641
-		($connect ? " pour $connect" : '') .
1642
-		(!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1643
-		"\n//\n" .
1631
+		$sourcefile.
1632
+		($connect ? " pour $connect" : '').
1633
+		(!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes").
1634
+		"\n//\n".
1644 1635
 		$principal;
1645 1636
 
1646 1637
 	$boucles[''] = $code;
@@ -1692,7 +1683,7 @@  discard block
 block discarded – undo
1692 1683
  **/
1693 1684
 function requeteur_data_dist(&$boucles, &$boucle, &$id) {
1694 1685
 	include_spip('iterateur/data');
1695
-	if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1686
+	if ($h = charger_fonction($boucle->type_requete.'_to_array', 'inc', true)) {
1696 1687
 		$g = charger_fonction('data', 'iterateur');
1697 1688
 		$boucles[$id] = $g($boucle);
1698 1689
 		// from[0] stocke le type de data (rss, yql, ...)
Please login to merge, or discard this patch.
ecrire/public/phraser_html.php 3 patches
Braces   +4 added lines, -8 removed lines patch added patch discarded remove patch
@@ -802,8 +802,7 @@  discard block
 block discarded – undo
802 802
 function public_compte_ligne($texte, $debut = 0, $fin = null) {
803 803
 	if (is_null($fin)) {
804 804
 		return substr_count($texte, "\n", $debut);
805
-	}
806
-	else {
805
+	} else {
807 806
 		return substr_count($texte, "\n", $debut, $fin - $debut);
808 807
 	}
809 808
 }
@@ -850,8 +849,7 @@  discard block
 block discarded – undo
850 849
 			erreur_squelette($err_b, $result);
851 850
 
852 851
 			continue;
853
-		}
854
-		else {
852
+		} else {
855 853
 			$boucle = [
856 854
 				'id_boucle' => $id_boucle,
857 855
 				'id_boucle_err' => $id_boucle,
@@ -991,8 +989,7 @@  discard block
 block discarded – undo
991 989
 	// si c'est un appel pour memoriser une boucle, memorisons la
992 990
 	if (is_string($champ) and !empty($boucle_placeholder) and !empty($boucle)) {
993 991
 		$boucles_connues[$boucle_placeholder][$champ] = &$boucle;
994
-	}
995
-	else {
992
+	} else {
996 993
 		if (!empty($champ->nom_champ) and !empty($boucles_connues[$champ->nom_champ])) {
997 994
 			$placeholder = $champ->nom_champ;
998 995
 			$id = reset($champ->param[0][1]);
@@ -1135,8 +1132,7 @@  discard block
 block discarded – undo
1135 1132
 				];
1136 1133
 				erreur_squelette($err_b, $result);
1137 1134
 				$pos_courante += strlen($fin_boucle);
1138
-			}
1139
-			else {
1135
+			} else {
1140 1136
 				// verifier une eventuelle imbrication d'une boucle homonyme
1141 1137
 				// (interdite, generera une erreur plus loin, mais permet de signaler la bonne erreur)
1142 1138
 				$search_debut_boucle = BALISE_BOUCLE . $id_boucle_search . '(';
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -48,19 +48,19 @@  discard block
 block discarded – undo
48 48
  * Nom d'une balise #TOTO
49 49
  *
50 50
  * Écriture alambiquée pour rester compatible avec les hexadecimaux des vieux squelettes */
51
-define('NOM_DE_CHAMP', '#((' . NOM_DE_BOUCLE . "):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)\b(\*{0,2})");
51
+define('NOM_DE_CHAMP', '#(('.NOM_DE_BOUCLE."):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)\b(\*{0,2})");
52 52
 /** Balise complète [...(#TOTO) ... ] */
53
-define('CHAMP_ETENDU', '/\[([^]\[]*)\(' . NOM_DE_CHAMP . '([^[)]*\)[^]\[]*)\]/S');
53
+define('CHAMP_ETENDU', '/\[([^]\[]*)\('.NOM_DE_CHAMP.'([^[)]*\)[^]\[]*)\]/S');
54 54
 
55 55
 define('BALISE_INCLURE', '/<INCLU[DR]E[[:space:]]*(\(([^)]*)\))?/S');
56 56
 define('BALISE_POLYGLOTTE', ',<multi>(.*)</multi>,Uims');
57 57
 define('BALISE_IDIOMES', ',<:(([a-z0-9_]+):)?([a-z0-9_]*)({([^\|=>]*=[^\|>]*)})?((\|[^>]*)?:/?>),iS');
58
-define('BALISE_IDIOMES_ARGS', '@^\s*([^= ]*)\s*=\s*((' . NOM_DE_CHAMP . '[{][^}]*})?[^,]*)\s*,?\s*@s');
58
+define('BALISE_IDIOMES_ARGS', '@^\s*([^= ]*)\s*=\s*(('.NOM_DE_CHAMP.'[{][^}]*})?[^,]*)\s*,?\s*@s');
59 59
 
60 60
 /** Champ sql dans parenthèse ex: (id_article) */
61 61
 define('SQL_ARGS', '(\([^)]*\))');
62 62
 /** Fonction SQL sur un champ ex: SUM(visites) */
63
-define('CHAMP_SQL_PLUS_FONC', '`?([A-Z_\/][A-Z_\/0-9.]*)' . SQL_ARGS . '?`?');
63
+define('CHAMP_SQL_PLUS_FONC', '`?([A-Z_\/][A-Z_\/0-9.]*)'.SQL_ARGS.'?`?');
64 64
 
65 65
 function phraser_inclure($texte, $ligne, $result) {
66 66
 
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
  * @return array
216 216
  **/
217 217
 function phraser_champs($texte, $ligne, $result) {
218
-	while (preg_match('/' . NOM_DE_CHAMP . '/S', $texte, $match)) {
218
+	while (preg_match('/'.NOM_DE_CHAMP.'/S', $texte, $match)) {
219 219
 		$p = strpos($texte, (string) $match[0]);
220 220
 		// texte après la balise
221 221
 		$suite = substr($texte, $p + strlen($match[0]));
@@ -363,7 +363,7 @@  discard block
 block discarded – undo
363 363
 			$collecte[] = $champ;
364 364
 			$args = ltrim($regs[count($regs) - 1]);
365 365
 		} else {
366
-			if (!preg_match('/' . NOM_DE_CHAMP . '([{|])/', $arg, $r)) {
366
+			if (!preg_match('/'.NOM_DE_CHAMP.'([{|])/', $arg, $r)) {
367 367
 				// 0 est un aveu d'impuissance. A completer
368 368
 				$arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
369 369
 
@@ -447,7 +447,7 @@  discard block
 block discarded – undo
447 447
 function phraser_champs_exterieurs($texte, $ligne, $sep, $nested) {
448 448
 	$res = [];
449 449
 	while (($p = strpos($texte, (string) "%$sep")) !== false) {
450
-		if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
450
+		if (!preg_match(',^%'.preg_quote($sep).'([0-9]+)@,', substr($texte, $p), $m)) {
451 451
 			break;
452 452
 		}
453 453
 		$debut = substr($texte, 0, $p);
@@ -487,7 +487,7 @@  discard block
 block discarded – undo
487 487
 			$pos_apres = 0;
488 488
 			$result = phraser_args($match[7], ')', $sep, $result, $champ, $pos_apres);
489 489
 			phraser_vieux($champ);
490
-			$champ->avant =	phraser_champs_exterieurs($match[1], $n, $sep, $result);
490
+			$champ->avant = phraser_champs_exterieurs($match[1], $n, $sep, $result);
491 491
 			$debut = substr($match[7], $pos_apres + 1);
492 492
 			if (!empty($debut)) {
493 493
 				$n += substr_count(substr($texte, 0, strpos($texte, $debut)), "\n");
@@ -618,7 +618,7 @@  discard block
 block discarded – undo
618 618
 					// une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
619 619
 					if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
620 620
 						$c = null;
621
-						eval('$c = ' . $m[4] . ';');
621
+						eval('$c = '.$m[4].';');
622 622
 						if (isset($c)) {
623 623
 							$m[4] = $c;
624 624
 						}
@@ -698,7 +698,7 @@  discard block
 block discarded – undo
698 698
 					if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
699 699
 						$crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
700 700
 					} elseif (
701
-						preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
701
+						preg_match(',^([!]?)('.CHAMP_SQL_PLUS_FONC.
702 702
 						')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)
703 703
 					) {
704 704
 						$a2 = trim($m[8]);
@@ -715,8 +715,8 @@  discard block
 block discarded – undo
715 715
 						);
716 716
 						$crit->exclus = $m[1];
717 717
 					} elseif (
718
-						preg_match('/^([!]?)\s*(' .
719
-						CHAMP_SQL_PLUS_FONC .
718
+						preg_match('/^([!]?)\s*('.
719
+						CHAMP_SQL_PLUS_FONC.
720 720
 						')\s*(\??)(.*)$/is', $param, $m)
721 721
 					) {
722 722
 						// contient aussi les comparaisons implicites !
@@ -861,7 +861,7 @@  discard block
 block discarded – undo
861 861
 			}
862 862
 
863 863
 			// trouver sa position de depart reelle : au <Bxx> ou au <BBxx>
864
-			$precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
864
+			$precond_boucle = BALISE_PRECOND_BOUCLE.$id_boucle.'>';
865 865
 			$pos_precond = strpos($texte, $precond_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
866 866
 			if (
867 867
 				$pos_precond !== false
@@ -872,7 +872,7 @@  discard block
 block discarded – undo
872 872
 				$boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
873 873
 			}
874 874
 
875
-			$preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
875
+			$preaff_boucle = BALISE_PREAFF_BOUCLE.$id_boucle.'>';
876 876
 			$pos_preaff = strpos($texte, $preaff_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
877 877
 			if (
878 878
 				$pos_preaff !== false
@@ -920,13 +920,13 @@  discard block
 block discarded – undo
920 920
 	$pos_anonyme_next = null;
921 921
 	// si c'est une boucle anonyme, chercher la position de la prochaine boucle anonyme
922 922
 	if (!strlen($id_boucle)) {
923
-		$pos_anonyme_next = strpos($texte, BALISE_BOUCLE . '(', $pos_courante);
923
+		$pos_anonyme_next = strpos($texte, BALISE_BOUCLE.'(', $pos_courante);
924 924
 	}
925 925
 
926 926
 	//
927 927
 	// 1. Recuperer la partie conditionnelle apres
928 928
 	//
929
-	$apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . '>';
929
+	$apres_boucle = BALISE_POSTCOND_BOUCLE.$id_boucle.'>';
930 930
 	$pos_apres = strpos($texte, $apres_boucle, $pos_courante);
931 931
 	if (
932 932
 		$pos_apres !== false
@@ -935,13 +935,13 @@  discard block
 block discarded – undo
935 935
 		$boucle['pos_postcond'] = $pos_apres;
936 936
 		$pos_apres += strlen($apres_boucle);
937 937
 		$boucle['pos_postcond_inside'] = $pos_apres;
938
-		$pos_courante = $pos_apres ;
938
+		$pos_courante = $pos_apres;
939 939
 	}
940 940
 
941 941
 	//
942 942
 	// 2. Récuperer la partie alternative apres
943 943
 	//
944
-	$altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . '>';
944
+	$altern_boucle = BALISE_ALT_BOUCLE.$id_boucle.'>';
945 945
 	$pos_altern = strpos($texte, $altern_boucle, $pos_courante);
946 946
 	if (
947 947
 		$pos_altern !== false
@@ -956,7 +956,7 @@  discard block
 block discarded – undo
956 956
 	//
957 957
 	// 3. Recuperer la partie footer non alternative
958 958
 	//
959
-	$postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . '>';
959
+	$postaff_boucle = BALISE_POSTAFF_BOUCLE.$id_boucle.'>';
960 960
 	$pos_postaff = strpos($texte, $postaff_boucle, $pos_courante);
961 961
 	if (
962 962
 		$pos_postaff !== false
@@ -965,7 +965,7 @@  discard block
 block discarded – undo
965 965
 		$boucle['pos_postaff'] = $pos_postaff;
966 966
 		$pos_postaff += strlen($postaff_boucle);
967 967
 		$boucle['pos_postaff_inside'] = $pos_postaff;
968
-		$pos_courante = $pos_postaff ;
968
+		$pos_courante = $pos_postaff;
969 969
 	}
970 970
 
971 971
 	return $boucle;
@@ -1005,7 +1005,7 @@  discard block
 block discarded – undo
1005 1005
  * @return string
1006 1006
  */
1007 1007
 function public_generer_boucle_placeholder($id_boucle, &$boucle, $boucle_placeholder, $nb_lignes) {
1008
-	$placeholder = "[(#{$boucle_placeholder}{" . $id_boucle . '})' . str_pad('', $nb_lignes, "\n") . ']';
1008
+	$placeholder = "[(#{$boucle_placeholder}{".$id_boucle.'})'.str_pad('', $nb_lignes, "\n").']';
1009 1009
 	//memoriser la boucle a reinjecter
1010 1010
 	$id_boucle = "$id_boucle";
1011 1011
 	phraser_boucle_placeholder($id_boucle, $boucle_placeholder, $boucle);
@@ -1018,7 +1018,7 @@  discard block
 block discarded – undo
1018 1018
 	// definir un placholder pour les boucles dont on est sur d'avoir aucune occurence dans le squelette
1019 1019
 	if (is_null($boucle_placeholder)) {
1020 1020
 		do {
1021
-			$boucle_placeholder = 'BOUCLE_PLACEHOLDER_' . strtoupper(md5(uniqid()));
1021
+			$boucle_placeholder = 'BOUCLE_PLACEHOLDER_'.strtoupper(md5(uniqid()));
1022 1022
 		} while (strpos($texte, $boucle_placeholder) !== false);
1023 1023
 	}
1024 1024
 
@@ -1038,7 +1038,7 @@  discard block
 block discarded – undo
1038 1038
 
1039 1039
 		// boucle anonyme ?
1040 1040
 		if (!strlen($id_boucle)) {
1041
-			$id_boucle = '_anon_L' . $ligne_milieu . '_' . substr(md5('anonyme:' . $id_parent . ':' . json_encode($boucle, JSON_THROW_ON_ERROR)), 0, 8);
1041
+			$id_boucle = '_anon_L'.$ligne_milieu.'_'.substr(md5('anonyme:'.$id_parent.':'.json_encode($boucle, JSON_THROW_ON_ERROR)), 0, 8);
1042 1042
 		}
1043 1043
 
1044 1044
 		$pos_debut_boucle = $pos_courante;
@@ -1051,7 +1051,7 @@  discard block
 block discarded – undo
1051 1051
 
1052 1052
 			$pos_avant = $boucle['pos_precond_inside'];
1053 1053
 			$result->avant = substr($texte, $pos_avant, $pos_courante - $pos_avant);
1054
-			$ligne_avant = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_avant);
1054
+			$ligne_avant = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_avant);
1055 1055
 		}
1056 1056
 
1057 1057
 		// Regarder si on a une partie inconditionnelle avant <BB_xxx>
@@ -1060,7 +1060,7 @@  discard block
 block discarded – undo
1060 1060
 
1061 1061
 			$pos_preaff = $boucle['pos_preaff_inside'];
1062 1062
 			$result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
1063
-			$ligne_preaff = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_preaff);
1063
+			$ligne_preaff = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_preaff);
1064 1064
 		}
1065 1065
 
1066 1066
 		$result->id_boucle = $id_boucle;
@@ -1117,7 +1117,7 @@  discard block
 block discarded – undo
1117 1117
 		} else {
1118 1118
 			$pos_milieu += 1;
1119 1119
 
1120
-			$fin_boucle = BALISE_FIN_BOUCLE . $id_boucle_search . '>';
1120
+			$fin_boucle = BALISE_FIN_BOUCLE.$id_boucle_search.'>';
1121 1121
 			$pos_fin = strpos($texte, $fin_boucle, $pos_milieu);
1122 1122
 			if ($pos_fin === false) {
1123 1123
 				$err_b = [
@@ -1130,7 +1130,7 @@  discard block
 block discarded – undo
1130 1130
 			else {
1131 1131
 				// verifier une eventuelle imbrication d'une boucle homonyme
1132 1132
 				// (interdite, generera une erreur plus loin, mais permet de signaler la bonne erreur)
1133
-				$search_debut_boucle = BALISE_BOUCLE . $id_boucle_search . '(';
1133
+				$search_debut_boucle = BALISE_BOUCLE.$id_boucle_search.'(';
1134 1134
 				$search_from = $pos_milieu;
1135 1135
 				$nb_open = 1;
1136 1136
 				$nb_close = 1;
@@ -1170,7 +1170,7 @@  discard block
 block discarded – undo
1170 1170
 		if ($boucle['pos_postcond']) {
1171 1171
 			$result->apres = substr($texte, $pos_courante, $boucle['pos_postcond'] - $pos_courante);
1172 1172
 			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postcond_inside']);
1173
-			$pos_courante = $boucle['pos_postcond_inside'] ;
1173
+			$pos_courante = $boucle['pos_postcond_inside'];
1174 1174
 		}
1175 1175
 
1176 1176
 
Please login to merge, or discard this patch.
Indentation   +1032 added lines, -1032 removed lines patch added patch discarded remove patch
@@ -27,7 +27,7 @@  discard block
 block discarded – undo
27 27
  **/
28 28
 
29 29
 if (!defined('_ECRIRE_INC_VERSION')) {
30
-	return;
30
+    return;
31 31
 }
32 32
 
33 33
 /** Début de la partie principale d'une boucle */
@@ -71,82 +71,82 @@  discard block
 block discarded – undo
71 71
 
72 72
 function phraser_inclure($texte, $ligne, $result) {
73 73
 
74
-	while (preg_match(BALISE_INCLURE, $texte, $match)) {
75
-		$match = array_pad($match, 3, null);
76
-		$p = strpos($texte, (string) $match[0]);
77
-		$debut = substr($texte, 0, $p);
78
-		if ($p) {
79
-			$result = phraser_idiomes($debut, $ligne, $result);
80
-		}
81
-		$ligne += substr_count($debut, "\n");
82
-		$champ = new Inclure();
83
-		$champ->ligne = $ligne;
84
-		$ligne += substr_count($match[0], "\n");
85
-		$fichier = $match[2];
86
-		# assurer ici la migration .php3 => .php
87
-		# et de l'ancienne syntaxe INCLURE(page.php3) devenue surperflue
88
-		if ($fichier and preg_match(',^(.*[.]php)3$,', $fichier, $r)) {
89
-			$fichier = $r[1];
90
-		}
91
-		$champ->texte = ($fichier !== 'page.php') ? $fichier : '';
92
-		$texte = substr($texte, $p + strlen($match[0]));
93
-		// on assimile {var=val} a une liste de un argument sans fonction
94
-		$pos_apres = 0;
95
-		phraser_args($texte, '/>', '', $result, $champ, $pos_apres);
96
-		if (!$champ->texte or (is_countable($champ->param) ? count($champ->param) : 0) > 1) {
97
-			if (!function_exists('normaliser_inclure')) {
98
-				include_spip('public/normaliser');
99
-			}
100
-			normaliser_inclure($champ);
101
-		}
102
-		$texte = substr($texte, strpos($texte, '>', $pos_apres) + 1);
103
-		$texte = preg_replace(',^</INCLU[DR]E>,', '', $texte);
104
-		$result[] = $champ;
105
-	}
106
-
107
-	return (($texte === '') ? $result : phraser_idiomes($texte, $ligne, $result));
74
+    while (preg_match(BALISE_INCLURE, $texte, $match)) {
75
+        $match = array_pad($match, 3, null);
76
+        $p = strpos($texte, (string) $match[0]);
77
+        $debut = substr($texte, 0, $p);
78
+        if ($p) {
79
+            $result = phraser_idiomes($debut, $ligne, $result);
80
+        }
81
+        $ligne += substr_count($debut, "\n");
82
+        $champ = new Inclure();
83
+        $champ->ligne = $ligne;
84
+        $ligne += substr_count($match[0], "\n");
85
+        $fichier = $match[2];
86
+        # assurer ici la migration .php3 => .php
87
+        # et de l'ancienne syntaxe INCLURE(page.php3) devenue surperflue
88
+        if ($fichier and preg_match(',^(.*[.]php)3$,', $fichier, $r)) {
89
+            $fichier = $r[1];
90
+        }
91
+        $champ->texte = ($fichier !== 'page.php') ? $fichier : '';
92
+        $texte = substr($texte, $p + strlen($match[0]));
93
+        // on assimile {var=val} a une liste de un argument sans fonction
94
+        $pos_apres = 0;
95
+        phraser_args($texte, '/>', '', $result, $champ, $pos_apres);
96
+        if (!$champ->texte or (is_countable($champ->param) ? count($champ->param) : 0) > 1) {
97
+            if (!function_exists('normaliser_inclure')) {
98
+                include_spip('public/normaliser');
99
+            }
100
+            normaliser_inclure($champ);
101
+        }
102
+        $texte = substr($texte, strpos($texte, '>', $pos_apres) + 1);
103
+        $texte = preg_replace(',^</INCLU[DR]E>,', '', $texte);
104
+        $result[] = $champ;
105
+    }
106
+
107
+    return (($texte === '') ? $result : phraser_idiomes($texte, $ligne, $result));
108 108
 }
109 109
 
110 110
 function phraser_polyglotte($texte, $ligne, $result) {
111 111
 
112
-	if (preg_match_all(BALISE_POLYGLOTTE, $texte, $m, PREG_SET_ORDER)) {
113
-		foreach ($m as $match) {
114
-			$p = strpos($texte, (string) $match[0]);
115
-			$debut = substr($texte, 0, $p);
116
-			if ($p) {
117
-				$champ = new Texte();
118
-				$champ->texte = $debut;
119
-				$champ->ligne = $ligne;
120
-				$result[] = $champ;
121
-				$ligne += substr_count($champ->texte, "\n");
122
-			}
123
-
124
-			$champ = new Polyglotte();
125
-			$champ->ligne = $ligne;
126
-			$ligne += substr_count($match[0], "\n");
127
-			$lang = '';
128
-			$bloc = $match[1];
129
-			$texte = substr($texte, $p + strlen($match[0]));
130
-			while (preg_match('/^[[:space:]]*([^[{]*)[[:space:]]*[[{]([a-z_]+)[]}](.*)$/si', $bloc, $regs)) {
131
-				$trad = $regs[1];
132
-				if ($trad or $lang) {
133
-					$champ->traductions[$lang] = $trad;
134
-				}
135
-				$lang = $regs[2];
136
-				$bloc = $regs[3];
137
-			}
138
-			$champ->traductions[$lang] = $bloc;
139
-			$result[] = $champ;
140
-		}
141
-	}
142
-	if ($texte !== '') {
143
-		$champ = new Texte();
144
-		$champ->texte = $texte;
145
-		$champ->ligne = $ligne;
146
-		$result[] = $champ;
147
-	}
148
-
149
-	return $result;
112
+    if (preg_match_all(BALISE_POLYGLOTTE, $texte, $m, PREG_SET_ORDER)) {
113
+        foreach ($m as $match) {
114
+            $p = strpos($texte, (string) $match[0]);
115
+            $debut = substr($texte, 0, $p);
116
+            if ($p) {
117
+                $champ = new Texte();
118
+                $champ->texte = $debut;
119
+                $champ->ligne = $ligne;
120
+                $result[] = $champ;
121
+                $ligne += substr_count($champ->texte, "\n");
122
+            }
123
+
124
+            $champ = new Polyglotte();
125
+            $champ->ligne = $ligne;
126
+            $ligne += substr_count($match[0], "\n");
127
+            $lang = '';
128
+            $bloc = $match[1];
129
+            $texte = substr($texte, $p + strlen($match[0]));
130
+            while (preg_match('/^[[:space:]]*([^[{]*)[[:space:]]*[[{]([a-z_]+)[]}](.*)$/si', $bloc, $regs)) {
131
+                $trad = $regs[1];
132
+                if ($trad or $lang) {
133
+                    $champ->traductions[$lang] = $trad;
134
+                }
135
+                $lang = $regs[2];
136
+                $bloc = $regs[3];
137
+            }
138
+            $champ->traductions[$lang] = $bloc;
139
+            $result[] = $champ;
140
+        }
141
+    }
142
+    if ($texte !== '') {
143
+        $champ = new Texte();
144
+        $champ->texte = $texte;
145
+        $champ->ligne = $ligne;
146
+        $result[] = $champ;
147
+    }
148
+
149
+    return $result;
150 150
 }
151 151
 
152 152
 
@@ -168,43 +168,43 @@  discard block
 block discarded – undo
168 168
  * @return array
169 169
  **/
170 170
 function phraser_idiomes($texte, $ligne, $result) {
171
-	while (preg_match(BALISE_IDIOMES, $texte, $match)) {
172
-		$match = array_pad($match, 8, null);
173
-		$p = strpos($texte, (string) $match[0]);
174
-		$ko = (!$match[3] && ($match[5][0] !== '='));
175
-		$debut = substr($texte, 0, $p + ($ko ? strlen($match[0]) : 0));
176
-		if ($debut) {
177
-			$result = phraser_champs($debut, $ligne, $result);
178
-		}
179
-		$texte = substr($texte, $p + strlen($match[0]));
180
-		$ligne += substr_count($debut, "\n");
181
-		if ($ko) {
182
-			continue;
183
-		} // faux idiome
184
-		$champ = new Idiome();
185
-		$champ->ligne = $ligne;
186
-		$ligne += substr_count($match[0], "\n");
187
-		// Stocker les arguments de la balise de traduction
188
-		$args = [];
189
-		$largs = $match[5];
190
-		while (preg_match(BALISE_IDIOMES_ARGS, $largs, $r)) {
191
-			$args[$r[1]] = phraser_champs($r[2], 0, []);
192
-			$largs = substr($largs, strlen($r[0]));
193
-		}
194
-		$champ->arg = $args;
195
-		$champ->nom_champ = strtolower($match[3]);
196
-		$champ->module = $match[2];
197
-		// pas d'imbrication pour les filtres sur langue
198
-		$pos_apres = 0;
199
-		phraser_args($match[7] ?? '', ':', '', [], $champ, $pos_apres);
200
-		$champ->apres = substr($match[7] ?? '', $pos_apres);
201
-		$result[] = $champ;
202
-	}
203
-	if ($texte !== '') {
204
-		$result = phraser_champs($texte, $ligne, $result);
205
-	}
206
-
207
-	return $result;
171
+    while (preg_match(BALISE_IDIOMES, $texte, $match)) {
172
+        $match = array_pad($match, 8, null);
173
+        $p = strpos($texte, (string) $match[0]);
174
+        $ko = (!$match[3] && ($match[5][0] !== '='));
175
+        $debut = substr($texte, 0, $p + ($ko ? strlen($match[0]) : 0));
176
+        if ($debut) {
177
+            $result = phraser_champs($debut, $ligne, $result);
178
+        }
179
+        $texte = substr($texte, $p + strlen($match[0]));
180
+        $ligne += substr_count($debut, "\n");
181
+        if ($ko) {
182
+            continue;
183
+        } // faux idiome
184
+        $champ = new Idiome();
185
+        $champ->ligne = $ligne;
186
+        $ligne += substr_count($match[0], "\n");
187
+        // Stocker les arguments de la balise de traduction
188
+        $args = [];
189
+        $largs = $match[5];
190
+        while (preg_match(BALISE_IDIOMES_ARGS, $largs, $r)) {
191
+            $args[$r[1]] = phraser_champs($r[2], 0, []);
192
+            $largs = substr($largs, strlen($r[0]));
193
+        }
194
+        $champ->arg = $args;
195
+        $champ->nom_champ = strtolower($match[3]);
196
+        $champ->module = $match[2];
197
+        // pas d'imbrication pour les filtres sur langue
198
+        $pos_apres = 0;
199
+        phraser_args($match[7] ?? '', ':', '', [], $champ, $pos_apres);
200
+        $champ->apres = substr($match[7] ?? '', $pos_apres);
201
+        $result[] = $champ;
202
+    }
203
+    if ($texte !== '') {
204
+        $result = phraser_champs($texte, $ligne, $result);
205
+    }
206
+
207
+    return $result;
208 208
 }
209 209
 
210 210
 /**
@@ -222,47 +222,47 @@  discard block
 block discarded – undo
222 222
  * @return array
223 223
  **/
224 224
 function phraser_champs($texte, $ligne, $result) {
225
-	while (preg_match('/' . NOM_DE_CHAMP . '/S', $texte, $match)) {
226
-		$p = strpos($texte, (string) $match[0]);
227
-		// texte après la balise
228
-		$suite = substr($texte, $p + strlen($match[0]));
229
-
230
-		$debut = substr($texte, 0, $p);
231
-		if ($p) {
232
-			$result = phraser_polyglotte($debut, $ligne, $result);
233
-		}
234
-		$ligne += substr_count($debut, "\n");
235
-		$champ = new Champ();
236
-		$champ->ligne = $ligne;
237
-		$ligne += substr_count($match[0], "\n");
238
-		$champ->nom_boucle = $match[2];
239
-		$champ->nom_champ = $match[3];
240
-		$champ->etoile = $match[5];
241
-
242
-		if ($suite and $suite[0] == '{') {
243
-			phraser_arg($suite, '', [], $champ);
244
-			// ce ltrim est une ereur de conception
245
-			// mais on le conserve par souci de compatibilite
246
-			$texte = ltrim($suite);
247
-			// Il faudrait le normaliser dans l'arbre de syntaxe abstraite
248
-			// pour faire sauter ce cas particulier a la decompilation.
249
-			/* Ce qui suit est malheureusement incomplet pour cela:
225
+    while (preg_match('/' . NOM_DE_CHAMP . '/S', $texte, $match)) {
226
+        $p = strpos($texte, (string) $match[0]);
227
+        // texte après la balise
228
+        $suite = substr($texte, $p + strlen($match[0]));
229
+
230
+        $debut = substr($texte, 0, $p);
231
+        if ($p) {
232
+            $result = phraser_polyglotte($debut, $ligne, $result);
233
+        }
234
+        $ligne += substr_count($debut, "\n");
235
+        $champ = new Champ();
236
+        $champ->ligne = $ligne;
237
+        $ligne += substr_count($match[0], "\n");
238
+        $champ->nom_boucle = $match[2];
239
+        $champ->nom_champ = $match[3];
240
+        $champ->etoile = $match[5];
241
+
242
+        if ($suite and $suite[0] == '{') {
243
+            phraser_arg($suite, '', [], $champ);
244
+            // ce ltrim est une ereur de conception
245
+            // mais on le conserve par souci de compatibilite
246
+            $texte = ltrim($suite);
247
+            // Il faudrait le normaliser dans l'arbre de syntaxe abstraite
248
+            // pour faire sauter ce cas particulier a la decompilation.
249
+            /* Ce qui suit est malheureusement incomplet pour cela:
250 250
 			if ($n = (strlen($suite) - strlen($texte))) {
251 251
 				$champ->apres = array(new Texte);
252 252
 				$champ->apres[0]->texte = substr($suite,0,$n);
253 253
 			}
254 254
 			*/
255
-		} else {
256
-			$texte = $suite;
257
-		}
258
-		phraser_vieux($champ);
259
-		$result[] = $champ;
260
-	}
261
-	if ($texte !== '') {
262
-		$result = phraser_polyglotte($texte, $ligne, $result);
263
-	}
264
-
265
-	return $result;
255
+        } else {
256
+            $texte = $suite;
257
+        }
258
+        phraser_vieux($champ);
259
+        $result[] = $champ;
260
+    }
261
+    if ($texte !== '') {
262
+        $result = phraser_polyglotte($texte, $ligne, $result);
263
+    }
264
+
265
+    return $result;
266 266
 }
267 267
 
268 268
 // Gestion des imbrications:
@@ -271,15 +271,15 @@  discard block
 block discarded – undo
271 271
 // on recommence tant qu'il y a des [...] en substituant a l'appel suivant
272 272
 
273 273
 function phraser_champs_etendus($texte, $ligne, $result) {
274
-	if ($texte === '') {
275
-		return $result;
276
-	}
277
-	$sep = '##';
278
-	while (strpos($texte, (string) $sep) !== false) {
279
-		$sep .= '#';
280
-	}
281
-
282
-	return array_merge($result, phraser_champs_interieurs($texte, $ligne, $sep, []));
274
+    if ($texte === '') {
275
+        return $result;
276
+    }
277
+    $sep = '##';
278
+    while (strpos($texte, (string) $sep) !== false) {
279
+        $sep .= '#';
280
+    }
281
+
282
+    return array_merge($result, phraser_champs_interieurs($texte, $ligne, $sep, []));
283 283
 }
284 284
 
285 285
 /**
@@ -298,275 +298,275 @@  discard block
 block discarded – undo
298 298
  * @return array
299 299
  */
300 300
 function phraser_args(string $texte, $fin, $sep, $result, &$pointeur_champ, &$pos_debut) {
301
-	$length = strlen($texte);
302
-	while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
303
-		$pos_debut++;
304
-	}
305
-	while (($pos_debut < $length) && !str_contains($fin, $texte[$pos_debut])) {
306
-		// phraser_arg modifie directement le $texte, on fait donc avec ici en passant par une sous chaine
307
-		$st = substr($texte, $pos_debut);
308
-		$result = phraser_arg($st, $sep, $result, $pointeur_champ);
309
-		$pos_debut = $length - strlen($st);
310
-		while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
311
-			$pos_debut++;
312
-		}
313
-	}
314
-
315
-	return $result;
301
+    $length = strlen($texte);
302
+    while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
303
+        $pos_debut++;
304
+    }
305
+    while (($pos_debut < $length) && !str_contains($fin, $texte[$pos_debut])) {
306
+        // phraser_arg modifie directement le $texte, on fait donc avec ici en passant par une sous chaine
307
+        $st = substr($texte, $pos_debut);
308
+        $result = phraser_arg($st, $sep, $result, $pointeur_champ);
309
+        $pos_debut = $length - strlen($st);
310
+        while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
311
+            $pos_debut++;
312
+        }
313
+    }
314
+
315
+    return $result;
316 316
 }
317 317
 
318 318
 function phraser_arg(&$texte, $sep, $result, &$pointeur_champ) {
319
-	preg_match(',^(\|?[^}{)|]*)(.*)$,ms', $texte, $match);
320
-	$suite = ltrim($match[2]);
321
-	$fonc = trim($match[1]);
322
-	if ($fonc && $fonc[0] == '|') {
323
-		$fonc = ltrim(substr($fonc, 1));
324
-	}
325
-	$res = [$fonc];
326
-	$err_f = '';
327
-	// cas du filtre sans argument ou du critere /
328
-	if (($suite && ($suite[0] != '{')) || ($fonc && $fonc[0] == '/')) {
329
-		// si pas d'argument, alors il faut une fonction ou un double |
330
-		if (!$match[1]) {
331
-			$err_f = ['zbug_erreur_filtre', ['filtre' => $texte]];
332
-			erreur_squelette($err_f, $pointeur_champ);
333
-			$texte = '';
334
-		} else {
335
-			$texte = $suite;
336
-		}
337
-		if ($err_f) {
338
-			$pointeur_champ->param = false;
339
-		} elseif ($fonc !== '') {
340
-			$pointeur_champ->param[] = $res;
341
-		}
342
-		// pour les balises avec faux filtres qui boudent ce dur larbeur
343
-		$pointeur_champ->fonctions[] = [$fonc, ''];
344
-
345
-		return $result;
346
-	}
347
-	$args = ltrim(substr($suite, 1)); // virer le '(' initial
348
-	$collecte = [];
349
-	while ($args && $args[0] != '}') {
350
-		if ($args[0] == '"') {
351
-			preg_match('/^(")([^"]*)(")(.*)$/ms', $args, $regs);
352
-		} elseif ($args[0] == "'") {
353
-			preg_match("/^(')([^']*)(')(.*)$/ms", $args, $regs);
354
-		} else {
355
-			preg_match('/^([[:space:]]*)([^,([{}]*([(\[{][^])}]*[])}])?[^,}]*)([,}].*)$/ms', $args, $regs);
356
-			if (!isset($regs[2]) or !strlen($regs[2])) {
357
-				$err_f = ['zbug_erreur_filtre', ['filtre' => $args]];
358
-				erreur_squelette($err_f, $pointeur_champ);
359
-				$champ = new Texte();
360
-				$champ->apres = $champ->avant = $args = '';
361
-				break;
362
-			}
363
-		}
364
-		$arg = $regs[2];
365
-		if (trim($regs[1])) {
366
-			$champ = new Texte();
367
-			$champ->texte = $arg;
368
-			$champ->apres = $champ->avant = $regs[1];
369
-			$result[] = $champ;
370
-			$collecte[] = $champ;
371
-			$args = ltrim($regs[count($regs) - 1]);
372
-		} else {
373
-			if (!preg_match('/' . NOM_DE_CHAMP . '([{|])/', $arg, $r)) {
374
-				// 0 est un aveu d'impuissance. A completer
375
-				$arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
376
-
377
-				$args = ltrim($regs[count($regs) - 1]);
378
-				$collecte = array_merge($collecte, $arg);
379
-				$result = array_merge($result, $arg);
380
-			} else {
381
-				$n = strpos($args, (string) $r[0]);
382
-				$pred = substr($args, 0, $n);
383
-				$par = ',}';
384
-				if (preg_match('/^(.*)\($/', $pred, $m)) {
385
-					$pred = $m[1];
386
-					$par = ')';
387
-				}
388
-				if ($pred) {
389
-					$champ = new Texte();
390
-					$champ->texte = $pred;
391
-					$champ->apres = $champ->avant = '';
392
-					$result[] = $champ;
393
-					$collecte[] = $champ;
394
-				}
395
-				$rec = substr($args, $n + strlen($r[0]) - 1);
396
-				$champ = new Champ();
397
-				$champ->nom_boucle = $r[2];
398
-				$champ->nom_champ = $r[3];
399
-				$champ->etoile = $r[5];
400
-				$next = $r[6];
401
-				while ($next == '{') {
402
-					phraser_arg($rec, $sep, [], $champ);
403
-					$args = ltrim($rec);
404
-					$next = $args[0] ?? '';
405
-				}
406
-				while ($next == '|') {
407
-					$pos_apres = 0;
408
-					phraser_args($rec, $par, $sep, [], $champ, $pos_apres);
409
-					$args = substr($rec, $pos_apres);
410
-					$next = $args[0] ?? '';
411
-				}
412
-				// Si erreur de syntaxe dans un sous-argument, propager.
413
-				if ($champ->param === false) {
414
-					$err_f = true;
415
-				} else {
416
-					phraser_vieux($champ);
417
-				}
418
-				if ($par == ')') {
419
-					$args = substr($args, 1);
420
-				}
421
-				$collecte[] = $champ;
422
-				$result[] = $champ;
423
-			}
424
-		}
425
-		if (isset($args[0]) and $args[0] == ',') {
426
-			$args = ltrim(substr($args, 1));
427
-			if ($collecte) {
428
-				$res[] = $collecte;
429
-				$collecte = [];
430
-			}
431
-		}
432
-	}
433
-	if ($collecte) {
434
-		$res[] = $collecte;
435
-		$collecte = [];
436
-	}
437
-	$texte = substr($args, 1);
438
-	$source = substr($suite, 0, strlen($suite) - strlen($texte));
439
-	// propager les erreurs, et ignorer les param vides
440
-	if ($pointeur_champ->param !== false) {
441
-		if ($err_f) {
442
-			$pointeur_champ->param = false;
443
-		} elseif ($fonc !== '' || count($res) > 1) {
444
-			$pointeur_champ->param[] = $res;
445
-		}
446
-	}
447
-	// pour les balises avec faux filtres qui boudent ce dur larbeur
448
-	$pointeur_champ->fonctions[] = [$fonc, $source];
449
-
450
-	return $result;
319
+    preg_match(',^(\|?[^}{)|]*)(.*)$,ms', $texte, $match);
320
+    $suite = ltrim($match[2]);
321
+    $fonc = trim($match[1]);
322
+    if ($fonc && $fonc[0] == '|') {
323
+        $fonc = ltrim(substr($fonc, 1));
324
+    }
325
+    $res = [$fonc];
326
+    $err_f = '';
327
+    // cas du filtre sans argument ou du critere /
328
+    if (($suite && ($suite[0] != '{')) || ($fonc && $fonc[0] == '/')) {
329
+        // si pas d'argument, alors il faut une fonction ou un double |
330
+        if (!$match[1]) {
331
+            $err_f = ['zbug_erreur_filtre', ['filtre' => $texte]];
332
+            erreur_squelette($err_f, $pointeur_champ);
333
+            $texte = '';
334
+        } else {
335
+            $texte = $suite;
336
+        }
337
+        if ($err_f) {
338
+            $pointeur_champ->param = false;
339
+        } elseif ($fonc !== '') {
340
+            $pointeur_champ->param[] = $res;
341
+        }
342
+        // pour les balises avec faux filtres qui boudent ce dur larbeur
343
+        $pointeur_champ->fonctions[] = [$fonc, ''];
344
+
345
+        return $result;
346
+    }
347
+    $args = ltrim(substr($suite, 1)); // virer le '(' initial
348
+    $collecte = [];
349
+    while ($args && $args[0] != '}') {
350
+        if ($args[0] == '"') {
351
+            preg_match('/^(")([^"]*)(")(.*)$/ms', $args, $regs);
352
+        } elseif ($args[0] == "'") {
353
+            preg_match("/^(')([^']*)(')(.*)$/ms", $args, $regs);
354
+        } else {
355
+            preg_match('/^([[:space:]]*)([^,([{}]*([(\[{][^])}]*[])}])?[^,}]*)([,}].*)$/ms', $args, $regs);
356
+            if (!isset($regs[2]) or !strlen($regs[2])) {
357
+                $err_f = ['zbug_erreur_filtre', ['filtre' => $args]];
358
+                erreur_squelette($err_f, $pointeur_champ);
359
+                $champ = new Texte();
360
+                $champ->apres = $champ->avant = $args = '';
361
+                break;
362
+            }
363
+        }
364
+        $arg = $regs[2];
365
+        if (trim($regs[1])) {
366
+            $champ = new Texte();
367
+            $champ->texte = $arg;
368
+            $champ->apres = $champ->avant = $regs[1];
369
+            $result[] = $champ;
370
+            $collecte[] = $champ;
371
+            $args = ltrim($regs[count($regs) - 1]);
372
+        } else {
373
+            if (!preg_match('/' . NOM_DE_CHAMP . '([{|])/', $arg, $r)) {
374
+                // 0 est un aveu d'impuissance. A completer
375
+                $arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
376
+
377
+                $args = ltrim($regs[count($regs) - 1]);
378
+                $collecte = array_merge($collecte, $arg);
379
+                $result = array_merge($result, $arg);
380
+            } else {
381
+                $n = strpos($args, (string) $r[0]);
382
+                $pred = substr($args, 0, $n);
383
+                $par = ',}';
384
+                if (preg_match('/^(.*)\($/', $pred, $m)) {
385
+                    $pred = $m[1];
386
+                    $par = ')';
387
+                }
388
+                if ($pred) {
389
+                    $champ = new Texte();
390
+                    $champ->texte = $pred;
391
+                    $champ->apres = $champ->avant = '';
392
+                    $result[] = $champ;
393
+                    $collecte[] = $champ;
394
+                }
395
+                $rec = substr($args, $n + strlen($r[0]) - 1);
396
+                $champ = new Champ();
397
+                $champ->nom_boucle = $r[2];
398
+                $champ->nom_champ = $r[3];
399
+                $champ->etoile = $r[5];
400
+                $next = $r[6];
401
+                while ($next == '{') {
402
+                    phraser_arg($rec, $sep, [], $champ);
403
+                    $args = ltrim($rec);
404
+                    $next = $args[0] ?? '';
405
+                }
406
+                while ($next == '|') {
407
+                    $pos_apres = 0;
408
+                    phraser_args($rec, $par, $sep, [], $champ, $pos_apres);
409
+                    $args = substr($rec, $pos_apres);
410
+                    $next = $args[0] ?? '';
411
+                }
412
+                // Si erreur de syntaxe dans un sous-argument, propager.
413
+                if ($champ->param === false) {
414
+                    $err_f = true;
415
+                } else {
416
+                    phraser_vieux($champ);
417
+                }
418
+                if ($par == ')') {
419
+                    $args = substr($args, 1);
420
+                }
421
+                $collecte[] = $champ;
422
+                $result[] = $champ;
423
+            }
424
+        }
425
+        if (isset($args[0]) and $args[0] == ',') {
426
+            $args = ltrim(substr($args, 1));
427
+            if ($collecte) {
428
+                $res[] = $collecte;
429
+                $collecte = [];
430
+            }
431
+        }
432
+    }
433
+    if ($collecte) {
434
+        $res[] = $collecte;
435
+        $collecte = [];
436
+    }
437
+    $texte = substr($args, 1);
438
+    $source = substr($suite, 0, strlen($suite) - strlen($texte));
439
+    // propager les erreurs, et ignorer les param vides
440
+    if ($pointeur_champ->param !== false) {
441
+        if ($err_f) {
442
+            $pointeur_champ->param = false;
443
+        } elseif ($fonc !== '' || count($res) > 1) {
444
+            $pointeur_champ->param[] = $res;
445
+        }
446
+    }
447
+    // pour les balises avec faux filtres qui boudent ce dur larbeur
448
+    $pointeur_champ->fonctions[] = [$fonc, $source];
449
+
450
+    return $result;
451 451
 }
452 452
 
453 453
 
454 454
 function phraser_champs_exterieurs($texte, $ligne, $sep, $nested) {
455
-	$res = [];
456
-	while (($p = strpos($texte, (string) "%$sep")) !== false) {
457
-		if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
458
-			break;
459
-		}
460
-		$debut = substr($texte, 0, $p);
461
-		$texte = substr($texte, $p + strlen($m[0]));
462
-		if ($p) {
463
-			$res = phraser_inclure($debut, $ligne, $res);
464
-		}
465
-		$ligne += substr_count($debut, "\n");
466
-		$res[] = $nested[$m[1]];
467
-	}
468
-
469
-	return (($texte === '') ? $res : phraser_inclure($texte, $ligne, $res));
455
+    $res = [];
456
+    while (($p = strpos($texte, (string) "%$sep")) !== false) {
457
+        if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
458
+            break;
459
+        }
460
+        $debut = substr($texte, 0, $p);
461
+        $texte = substr($texte, $p + strlen($m[0]));
462
+        if ($p) {
463
+            $res = phraser_inclure($debut, $ligne, $res);
464
+        }
465
+        $ligne += substr_count($debut, "\n");
466
+        $res[] = $nested[$m[1]];
467
+    }
468
+
469
+    return (($texte === '') ? $res : phraser_inclure($texte, $ligne, $res));
470 470
 }
471 471
 
472 472
 function phraser_champs_interieurs($texte, $ligne, $sep, $result) {
473
-	$i = 0; // en fait count($result)
474
-	$x = '';
475
-
476
-	while (true) {
477
-		$j = $i;
478
-		$n = $ligne;
479
-		while (preg_match(CHAMP_ETENDU, $texte, $match)) {
480
-			$p = strpos($texte, (string) $match[0]);
481
-			$debut = substr($texte, 0, $p);
482
-			if ($p) {
483
-				$result[$i] = $debut;
484
-				$i++;
485
-			}
486
-			$nom = $match[4];
487
-			$champ = new Champ();
488
-			// ca ne marche pas encore en cas de champ imbrique
489
-			$champ->ligne = $x ? 0 : ($n + substr_count($debut, "\n"));
490
-			$champ->nom_boucle = $match[3];
491
-			$champ->nom_champ = $nom;
492
-			$champ->etoile = $match[6];
493
-			// phraser_args indiquera ou commence apres
494
-			$pos_apres = 0;
495
-			$result = phraser_args($match[7], ')', $sep, $result, $champ, $pos_apres);
496
-			phraser_vieux($champ);
497
-			$champ->avant =	phraser_champs_exterieurs($match[1], $n, $sep, $result);
498
-			$debut = substr($match[7], $pos_apres + 1);
499
-			if (!empty($debut)) {
500
-				$n += substr_count(substr($texte, 0, strpos($texte, $debut)), "\n");
501
-			}
502
-			$champ->apres = phraser_champs_exterieurs($debut, $n, $sep, $result);
503
-
504
-			// reinjecter la boucle si c'en est une
505
-			phraser_boucle_placeholder($champ);
506
-
507
-			$result[$i] = $champ;
508
-			$i++;
509
-			$texte = substr($texte, $p + strlen($match[0]));
510
-		}
511
-		if ($texte !== '') {
512
-			$result[$i] = $texte;
513
-			$i++;
514
-		}
515
-		$x = '';
516
-
517
-		while ($j < $i) {
518
-			$z = $result[$j];
519
-			// j'aurais besoin de connaitre le nombre de lignes...
520
-			if (is_object($z)) {
521
-				$x .= "%$sep$j@";
522
-			} else {
523
-				$x .= $z;
524
-			}
525
-			$j++;
526
-		}
527
-		if (preg_match(CHAMP_ETENDU, $x)) {
528
-			$texte = $x;
529
-		} else {
530
-			return phraser_champs_exterieurs($x, $ligne, $sep, $result);
531
-		}
532
-	}
473
+    $i = 0; // en fait count($result)
474
+    $x = '';
475
+
476
+    while (true) {
477
+        $j = $i;
478
+        $n = $ligne;
479
+        while (preg_match(CHAMP_ETENDU, $texte, $match)) {
480
+            $p = strpos($texte, (string) $match[0]);
481
+            $debut = substr($texte, 0, $p);
482
+            if ($p) {
483
+                $result[$i] = $debut;
484
+                $i++;
485
+            }
486
+            $nom = $match[4];
487
+            $champ = new Champ();
488
+            // ca ne marche pas encore en cas de champ imbrique
489
+            $champ->ligne = $x ? 0 : ($n + substr_count($debut, "\n"));
490
+            $champ->nom_boucle = $match[3];
491
+            $champ->nom_champ = $nom;
492
+            $champ->etoile = $match[6];
493
+            // phraser_args indiquera ou commence apres
494
+            $pos_apres = 0;
495
+            $result = phraser_args($match[7], ')', $sep, $result, $champ, $pos_apres);
496
+            phraser_vieux($champ);
497
+            $champ->avant =	phraser_champs_exterieurs($match[1], $n, $sep, $result);
498
+            $debut = substr($match[7], $pos_apres + 1);
499
+            if (!empty($debut)) {
500
+                $n += substr_count(substr($texte, 0, strpos($texte, $debut)), "\n");
501
+            }
502
+            $champ->apres = phraser_champs_exterieurs($debut, $n, $sep, $result);
503
+
504
+            // reinjecter la boucle si c'en est une
505
+            phraser_boucle_placeholder($champ);
506
+
507
+            $result[$i] = $champ;
508
+            $i++;
509
+            $texte = substr($texte, $p + strlen($match[0]));
510
+        }
511
+        if ($texte !== '') {
512
+            $result[$i] = $texte;
513
+            $i++;
514
+        }
515
+        $x = '';
516
+
517
+        while ($j < $i) {
518
+            $z = $result[$j];
519
+            // j'aurais besoin de connaitre le nombre de lignes...
520
+            if (is_object($z)) {
521
+                $x .= "%$sep$j@";
522
+            } else {
523
+                $x .= $z;
524
+            }
525
+            $j++;
526
+        }
527
+        if (preg_match(CHAMP_ETENDU, $x)) {
528
+            $texte = $x;
529
+        } else {
530
+            return phraser_champs_exterieurs($x, $ligne, $sep, $result);
531
+        }
532
+    }
533 533
 }
534 534
 
535 535
 function phraser_vieux(&$champ) {
536
-	$nom = $champ->nom_champ;
537
-	if ($nom == 'EMBED_DOCUMENT') {
538
-		if (!function_exists('phraser_vieux_emb')) {
539
-			include_spip('public/normaliser');
540
-		}
541
-		phraser_vieux_emb($champ);
542
-	} elseif ($nom == 'EXPOSER') {
543
-		if (!function_exists('phraser_vieux_exposer')) {
544
-			include_spip('public/normaliser');
545
-		}
546
-		phraser_vieux_exposer($champ);
547
-	} elseif ($champ->param) {
548
-		if ($nom == 'FORMULAIRE_RECHERCHE') {
549
-			if (!function_exists('phraser_vieux_recherche')) {
550
-				include_spip('public/normaliser');
551
-			}
552
-			phraser_vieux_recherche($champ);
553
-		} elseif (preg_match(',^LOGO_[A-Z]+,', $nom)) {
554
-			if (!function_exists('phraser_vieux_logos')) {
555
-				include_spip('public/normaliser');
556
-			}
557
-			phraser_vieux_logos($champ);
558
-		} elseif ($nom == 'MODELE') {
559
-			if (!function_exists('phraser_vieux_modele')) {
560
-				include_spip('public/normaliser');
561
-			}
562
-			phraser_vieux_modele($champ);
563
-		} elseif ($nom == 'INCLURE' or $nom == 'INCLUDE') {
564
-			if (!function_exists('phraser_vieux_inclu')) {
565
-				include_spip('public/normaliser');
566
-			}
567
-			phraser_vieux_inclu($champ);
568
-		}
569
-	}
536
+    $nom = $champ->nom_champ;
537
+    if ($nom == 'EMBED_DOCUMENT') {
538
+        if (!function_exists('phraser_vieux_emb')) {
539
+            include_spip('public/normaliser');
540
+        }
541
+        phraser_vieux_emb($champ);
542
+    } elseif ($nom == 'EXPOSER') {
543
+        if (!function_exists('phraser_vieux_exposer')) {
544
+            include_spip('public/normaliser');
545
+        }
546
+        phraser_vieux_exposer($champ);
547
+    } elseif ($champ->param) {
548
+        if ($nom == 'FORMULAIRE_RECHERCHE') {
549
+            if (!function_exists('phraser_vieux_recherche')) {
550
+                include_spip('public/normaliser');
551
+            }
552
+            phraser_vieux_recherche($champ);
553
+        } elseif (preg_match(',^LOGO_[A-Z]+,', $nom)) {
554
+            if (!function_exists('phraser_vieux_logos')) {
555
+                include_spip('public/normaliser');
556
+            }
557
+            phraser_vieux_logos($champ);
558
+        } elseif ($nom == 'MODELE') {
559
+            if (!function_exists('phraser_vieux_modele')) {
560
+                include_spip('public/normaliser');
561
+            }
562
+            phraser_vieux_modele($champ);
563
+        } elseif ($nom == 'INCLURE' or $nom == 'INCLUDE') {
564
+            if (!function_exists('phraser_vieux_inclu')) {
565
+                include_spip('public/normaliser');
566
+            }
567
+            phraser_vieux_inclu($champ);
568
+        }
569
+    }
570 570
 }
571 571
 
572 572
 
@@ -594,200 +594,200 @@  discard block
 block discarded – undo
594 594
  **/
595 595
 function phraser_criteres($params, &$result) {
596 596
 
597
-	$err_ci = ''; // indiquera s'il y a eu une erreur
598
-	$args = [];
599
-	$type = $result->type_requete;
600
-	$doublons = [];
601
-	foreach ($params as $v) {
602
-		$var = $v[1][0];
603
-		$param = ($var->type != 'texte') ? '' : $var->texte;
604
-		if (((is_countable($v) ? count($v) : 0) > 2) && (!preg_match(',[^A-Za-z]IN[^A-Za-z],i', $param))) {
605
-			// plus d'un argument et pas le critere IN:
606
-			// detecter comme on peut si c'est le critere implicite LIMIT debut, fin
607
-			if (
608
-				$var->type != 'texte'
609
-				or preg_match('/^(n|n-|(n-)?\d+)$/S', $param)
610
-			) {
611
-				$op = ',';
612
-				$not = false;
613
-				$cond = false;
614
-			} else {
615
-				// Le debut du premier argument est l'operateur
616
-				preg_match('/^([!]?)([a-zA-Z][a-zA-Z0-9_]*)[[:space:]]*(\??)[[:space:]]*(.*)$/ms', $param, $m);
617
-				$op = $m[2];
618
-				$not = (bool) $m[1];
619
-				$cond = (bool) $m[3];
620
-				// virer le premier argument,
621
-				// et mettre son reliquat eventuel
622
-				// Recopier pour ne pas alterer le texte source
623
-				// utile au debusqueur
624
-				if ($m[4]) {
625
-					// une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
626
-					if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
627
-						$c = null;
628
-						eval('$c = ' . $m[4] . ';');
629
-						if (isset($c)) {
630
-							$m[4] = $c;
631
-						}
632
-					}
633
-					$texte = new Texte();
634
-					$texte->texte = $m[4];
635
-					$v[1][0] = $texte;
636
-				} else {
637
-					array_shift($v[1]);
638
-				}
639
-			}
640
-			array_shift($v); // $v[O] est vide
641
-			$crit = new Critere();
642
-			$crit->op = $op;
643
-			$crit->not = $not;
644
-			$crit->cond = $cond;
645
-			$crit->exclus = '';
646
-			$crit->param = $v;
647
-			$args[] = $crit;
648
-		} else {
649
-			if ($var->type != 'texte') {
650
-				// cas 1 seul arg ne commencant pas par du texte brut:
651
-				// erreur ou critere infixe "/"
652
-				if (($v[1][1]->type != 'texte') || (trim($v[1][1]->texte) != '/')) {
653
-					$err_ci = [
654
-						'zbug_critere_inconnu',
655
-						['critere' => $var->nom_champ]
656
-					];
657
-					erreur_squelette($err_ci, $result);
658
-				} else {
659
-					$crit = new Critere();
660
-					$crit->op = '/';
661
-					$crit->not = false;
662
-					$crit->exclus = '';
663
-					$crit->param = [[$v[1][0]], [$v[1][2]]];
664
-					$args[] = $crit;
665
-				}
666
-			} else {
667
-				// traiter qq lexemes particuliers pour faciliter la suite
668
-				// les separateurs
669
-				if ($var->apres) {
670
-					$result->separateur[] = $param;
671
-				} elseif (($param == 'tout') or ($param == 'tous')) {
672
-					$result->modificateur['tout'] = true;
673
-				} elseif ($param == 'plat') {
674
-					$result->modificateur['plat'] = true;
675
-				}
676
-
677
-				// Boucle hierarchie, analyser le critere id_rubrique
678
-				// et les autres critères {id_x} pour forcer {tout} sur
679
-				// ceux-ci pour avoir la rubrique mere...
680
-				// Les autres critères de la boucle hierarchie doivent être
681
-				// traités normalement.
682
-				elseif (
683
-					strcasecmp($type, 'hierarchie') == 0
684
-					and !preg_match(",^id_rubrique\b,", $param)
685
-					and preg_match(',^id_\w+\s*$,', $param)
686
-				) {
687
-					$result->modificateur['tout'] = true;
688
-				} elseif (strcasecmp($type, 'hierarchie') == 0 and $param == 'id_rubrique') {
689
-					// rien a faire sur {id_rubrique} tout seul
690
-				} else {
691
-					// pas d'emplacement statique, faut un dynamique
692
-					// mais il y a 2 cas qui ont les 2 !
693
-					if (($param == 'unique') || (preg_match(',^!?doublons *,', $param))) {
694
-						// cette variable sera inseree dans le code
695
-						// et son nom sert d'indicateur des maintenant
696
-						$result->doublons = '$doublons_index';
697
-						if ($param == 'unique') {
698
-							$param = 'doublons';
699
-						}
700
-					} elseif ($param == 'recherche') {
701
-						// meme chose (a cause de #nom_de_boucle:URL_*)
702
-						$result->hash = ' ';
703
-					}
704
-
705
-					if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
706
-						$crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
707
-					} elseif (
708
-						preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
709
-						')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)
710
-					) {
711
-						$a2 = trim($m[8]);
712
-						if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and ($a2[0] == substr($a2, -1))) {
713
-							$a2 = substr($a2, 1, -1);
714
-						}
715
-						$crit = phraser_critere_infixe(
716
-							$m[2],
717
-							$a2,
718
-							$v,
719
-							(($m[2] == 'lang_select') ? $m[2] : $m[7]),
720
-							$m[6],
721
-							$m[5]
722
-						);
723
-						$crit->exclus = $m[1];
724
-					} elseif (
725
-						preg_match('/^([!]?)\s*(' .
726
-						CHAMP_SQL_PLUS_FONC .
727
-						')\s*(\??)(.*)$/is', $param, $m)
728
-					) {
729
-						// contient aussi les comparaisons implicites !
730
-						// Comme ci-dessus:
731
-						// le premier arg contient l'operateur
732
-						array_shift($v);
733
-						if ($m[6]) {
734
-							$v[0][0] = new Texte();
735
-							$v[0][0]->texte = $m[6];
736
-						} else {
737
-							array_shift($v[0]);
738
-							if (!$v[0]) {
739
-								array_shift($v);
740
-							}
741
-						}
742
-						$crit = new Critere();
743
-						$crit->op = $m[2];
744
-						$crit->param = $v;
745
-						$crit->not = (bool) $m[1];
746
-						$crit->cond = (bool) $m[5];
747
-					} else {
748
-						$err_ci = [
749
-							'zbug_critere_inconnu',
750
-							['critere' => $param]
751
-						];
752
-						erreur_squelette($err_ci, $result);
753
-					}
754
-
755
-					if ((!preg_match(',^!?doublons *,', $param)) || $crit->not) {
756
-						$args[] = $crit;
757
-					} else {
758
-						$doublons[] = $crit;
759
-					}
760
-				}
761
-			}
762
-		}
763
-	}
764
-
765
-	// les doublons non nies doivent etre le dernier critere
766
-	// pour que la variable $doublon_index ait la bonne valeur
767
-	// cf critere_doublon
768
-	if ($doublons) {
769
-		$args = [...$args, ...$doublons];
770
-	}
771
-
772
-	// Si erreur, laisser la chaine dans ce champ pour le HTTP 503
773
-	if (!$err_ci) {
774
-		$result->criteres = $args;
775
-	}
597
+    $err_ci = ''; // indiquera s'il y a eu une erreur
598
+    $args = [];
599
+    $type = $result->type_requete;
600
+    $doublons = [];
601
+    foreach ($params as $v) {
602
+        $var = $v[1][0];
603
+        $param = ($var->type != 'texte') ? '' : $var->texte;
604
+        if (((is_countable($v) ? count($v) : 0) > 2) && (!preg_match(',[^A-Za-z]IN[^A-Za-z],i', $param))) {
605
+            // plus d'un argument et pas le critere IN:
606
+            // detecter comme on peut si c'est le critere implicite LIMIT debut, fin
607
+            if (
608
+                $var->type != 'texte'
609
+                or preg_match('/^(n|n-|(n-)?\d+)$/S', $param)
610
+            ) {
611
+                $op = ',';
612
+                $not = false;
613
+                $cond = false;
614
+            } else {
615
+                // Le debut du premier argument est l'operateur
616
+                preg_match('/^([!]?)([a-zA-Z][a-zA-Z0-9_]*)[[:space:]]*(\??)[[:space:]]*(.*)$/ms', $param, $m);
617
+                $op = $m[2];
618
+                $not = (bool) $m[1];
619
+                $cond = (bool) $m[3];
620
+                // virer le premier argument,
621
+                // et mettre son reliquat eventuel
622
+                // Recopier pour ne pas alterer le texte source
623
+                // utile au debusqueur
624
+                if ($m[4]) {
625
+                    // une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
626
+                    if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
627
+                        $c = null;
628
+                        eval('$c = ' . $m[4] . ';');
629
+                        if (isset($c)) {
630
+                            $m[4] = $c;
631
+                        }
632
+                    }
633
+                    $texte = new Texte();
634
+                    $texte->texte = $m[4];
635
+                    $v[1][0] = $texte;
636
+                } else {
637
+                    array_shift($v[1]);
638
+                }
639
+            }
640
+            array_shift($v); // $v[O] est vide
641
+            $crit = new Critere();
642
+            $crit->op = $op;
643
+            $crit->not = $not;
644
+            $crit->cond = $cond;
645
+            $crit->exclus = '';
646
+            $crit->param = $v;
647
+            $args[] = $crit;
648
+        } else {
649
+            if ($var->type != 'texte') {
650
+                // cas 1 seul arg ne commencant pas par du texte brut:
651
+                // erreur ou critere infixe "/"
652
+                if (($v[1][1]->type != 'texte') || (trim($v[1][1]->texte) != '/')) {
653
+                    $err_ci = [
654
+                        'zbug_critere_inconnu',
655
+                        ['critere' => $var->nom_champ]
656
+                    ];
657
+                    erreur_squelette($err_ci, $result);
658
+                } else {
659
+                    $crit = new Critere();
660
+                    $crit->op = '/';
661
+                    $crit->not = false;
662
+                    $crit->exclus = '';
663
+                    $crit->param = [[$v[1][0]], [$v[1][2]]];
664
+                    $args[] = $crit;
665
+                }
666
+            } else {
667
+                // traiter qq lexemes particuliers pour faciliter la suite
668
+                // les separateurs
669
+                if ($var->apres) {
670
+                    $result->separateur[] = $param;
671
+                } elseif (($param == 'tout') or ($param == 'tous')) {
672
+                    $result->modificateur['tout'] = true;
673
+                } elseif ($param == 'plat') {
674
+                    $result->modificateur['plat'] = true;
675
+                }
676
+
677
+                // Boucle hierarchie, analyser le critere id_rubrique
678
+                // et les autres critères {id_x} pour forcer {tout} sur
679
+                // ceux-ci pour avoir la rubrique mere...
680
+                // Les autres critères de la boucle hierarchie doivent être
681
+                // traités normalement.
682
+                elseif (
683
+                    strcasecmp($type, 'hierarchie') == 0
684
+                    and !preg_match(",^id_rubrique\b,", $param)
685
+                    and preg_match(',^id_\w+\s*$,', $param)
686
+                ) {
687
+                    $result->modificateur['tout'] = true;
688
+                } elseif (strcasecmp($type, 'hierarchie') == 0 and $param == 'id_rubrique') {
689
+                    // rien a faire sur {id_rubrique} tout seul
690
+                } else {
691
+                    // pas d'emplacement statique, faut un dynamique
692
+                    // mais il y a 2 cas qui ont les 2 !
693
+                    if (($param == 'unique') || (preg_match(',^!?doublons *,', $param))) {
694
+                        // cette variable sera inseree dans le code
695
+                        // et son nom sert d'indicateur des maintenant
696
+                        $result->doublons = '$doublons_index';
697
+                        if ($param == 'unique') {
698
+                            $param = 'doublons';
699
+                        }
700
+                    } elseif ($param == 'recherche') {
701
+                        // meme chose (a cause de #nom_de_boucle:URL_*)
702
+                        $result->hash = ' ';
703
+                    }
704
+
705
+                    if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
706
+                        $crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
707
+                    } elseif (
708
+                        preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
709
+                        ')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)
710
+                    ) {
711
+                        $a2 = trim($m[8]);
712
+                        if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and ($a2[0] == substr($a2, -1))) {
713
+                            $a2 = substr($a2, 1, -1);
714
+                        }
715
+                        $crit = phraser_critere_infixe(
716
+                            $m[2],
717
+                            $a2,
718
+                            $v,
719
+                            (($m[2] == 'lang_select') ? $m[2] : $m[7]),
720
+                            $m[6],
721
+                            $m[5]
722
+                        );
723
+                        $crit->exclus = $m[1];
724
+                    } elseif (
725
+                        preg_match('/^([!]?)\s*(' .
726
+                        CHAMP_SQL_PLUS_FONC .
727
+                        ')\s*(\??)(.*)$/is', $param, $m)
728
+                    ) {
729
+                        // contient aussi les comparaisons implicites !
730
+                        // Comme ci-dessus:
731
+                        // le premier arg contient l'operateur
732
+                        array_shift($v);
733
+                        if ($m[6]) {
734
+                            $v[0][0] = new Texte();
735
+                            $v[0][0]->texte = $m[6];
736
+                        } else {
737
+                            array_shift($v[0]);
738
+                            if (!$v[0]) {
739
+                                array_shift($v);
740
+                            }
741
+                        }
742
+                        $crit = new Critere();
743
+                        $crit->op = $m[2];
744
+                        $crit->param = $v;
745
+                        $crit->not = (bool) $m[1];
746
+                        $crit->cond = (bool) $m[5];
747
+                    } else {
748
+                        $err_ci = [
749
+                            'zbug_critere_inconnu',
750
+                            ['critere' => $param]
751
+                        ];
752
+                        erreur_squelette($err_ci, $result);
753
+                    }
754
+
755
+                    if ((!preg_match(',^!?doublons *,', $param)) || $crit->not) {
756
+                        $args[] = $crit;
757
+                    } else {
758
+                        $doublons[] = $crit;
759
+                    }
760
+                }
761
+            }
762
+        }
763
+    }
764
+
765
+    // les doublons non nies doivent etre le dernier critere
766
+    // pour que la variable $doublon_index ait la bonne valeur
767
+    // cf critere_doublon
768
+    if ($doublons) {
769
+        $args = [...$args, ...$doublons];
770
+    }
771
+
772
+    // Si erreur, laisser la chaine dans ce champ pour le HTTP 503
773
+    if (!$err_ci) {
774
+        $result->criteres = $args;
775
+    }
776 776
 }
777 777
 
778 778
 function phraser_critere_infixe($arg1, $arg2, $args, $op, $not, $cond) {
779
-	$args[0] = new Texte();
780
-	$args[0]->texte = $arg1;
781
-	$args[0] = [$args[0]];
782
-	$args[1][0] = new Texte();
783
-	$args[1][0]->texte = $arg2;
784
-	$crit = new Critere();
785
-	$crit->op = $op;
786
-	$crit->not = $not;
787
-	$crit->cond = $cond;
788
-	$crit->param = $args;
789
-
790
-	return $crit;
779
+    $args[0] = new Texte();
780
+    $args[0]->texte = $arg1;
781
+    $args[0] = [$args[0]];
782
+    $args[1][0] = new Texte();
783
+    $args[1][0]->texte = $arg2;
784
+    $crit = new Critere();
785
+    $crit->op = $op;
786
+    $crit->not = $not;
787
+    $crit->cond = $cond;
788
+    $crit->param = $args;
789
+
790
+    return $crit;
791 791
 }
792 792
 
793 793
 /**
@@ -798,12 +798,12 @@  discard block
 block discarded – undo
798 798
  * @return int
799 799
  */
800 800
 function public_compte_ligne($texte, $debut = 0, $fin = null) {
801
-	if (is_null($fin)) {
802
-		return substr_count($texte, "\n", $debut);
803
-	}
804
-	else {
805
-		return substr_count($texte, "\n", $debut, $fin - $debut);
806
-	}
801
+    if (is_null($fin)) {
802
+        return substr_count($texte, "\n", $debut);
803
+    }
804
+    else {
805
+        return substr_count($texte, "\n", $debut, $fin - $debut);
806
+    }
807 807
 }
808 808
 
809 809
 
@@ -819,87 +819,87 @@  discard block
 block discarded – undo
819 819
  * @return array|null
820 820
  */
821 821
 function public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte = 0) {
822
-	$premiere_boucle = null;
823
-	$pos_derniere_boucle_anonyme = $pos_debut_texte;
824
-
825
-	$current_pos = $pos_debut_texte;
826
-	while (($pos_boucle = strpos($texte, BALISE_BOUCLE, $current_pos)) !== false) {
827
-		$current_pos = $pos_boucle + 1;
828
-		$pos_parent = strpos($texte, '(', $pos_boucle);
829
-
830
-		$id_boucle = '';
831
-		if ($pos_parent !== false) {
832
-			$id_boucle = trim(substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)));
833
-		}
834
-		if (
835
-			$pos_parent === false
836
-			or (strlen($id_boucle) and !(is_numeric($id_boucle) or strpos($id_boucle, '_') === 0))
837
-		) {
838
-			$result = new Boucle();
839
-			$result->id_parent = $id_parent;
840
-			$result->descr = $descr;
841
-
842
-			// un id_boucle pour l'affichage de l'erreur
843
-			if (!strlen($id_boucle)) {
844
-				$id_boucle = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
845
-			}
846
-			$result->id_boucle = $id_boucle;
847
-			$err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
848
-			erreur_squelette($err_b, $result);
849
-
850
-			continue;
851
-		}
852
-		else {
853
-			$boucle = [
854
-				'id_boucle' => $id_boucle,
855
-				'id_boucle_err' => $id_boucle,
856
-				'debut_boucle' => $pos_boucle,
857
-				'pos_boucle' => $pos_boucle,
858
-				'pos_parent' => $pos_parent,
859
-				'pos_precond' => false,
860
-				'pos_precond_inside' => false,
861
-				'pos_preaff' => false,
862
-				'pos_preaff_inside' => false,
863
-			];
864
-
865
-			// un id_boucle pour l'affichage de l'erreur sur les boucle anonymes
866
-			if (!strlen($id_boucle)) {
867
-				$boucle['id_boucle_err'] = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
868
-			}
869
-
870
-			// trouver sa position de depart reelle : au <Bxx> ou au <BBxx>
871
-			$precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
872
-			$pos_precond = strpos($texte, $precond_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
873
-			if (
874
-				$pos_precond !== false
875
-				and $pos_precond < $boucle['debut_boucle']
876
-			) {
877
-				$boucle['debut_boucle'] = $pos_precond;
878
-				$boucle['pos_precond'] = $pos_precond;
879
-				$boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
880
-			}
881
-
882
-			$preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
883
-			$pos_preaff = strpos($texte, $preaff_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
884
-			if (
885
-				$pos_preaff !== false
886
-				and $pos_preaff < $boucle['debut_boucle']
887
-			) {
888
-				$boucle['debut_boucle'] = $pos_preaff;
889
-				$boucle['pos_preaff'] = $pos_preaff;
890
-				$boucle['pos_preaff_inside'] = $pos_preaff + strlen($preaff_boucle);
891
-			}
892
-			if (!strlen($id_boucle)) {
893
-				$pos_derniere_boucle_anonyme = $pos_boucle;
894
-			}
895
-
896
-			if (is_null($premiere_boucle) or $premiere_boucle['debut_boucle'] > $boucle['debut_boucle']) {
897
-				$premiere_boucle = $boucle;
898
-			}
899
-		}
900
-	}
901
-
902
-	return $premiere_boucle;
822
+    $premiere_boucle = null;
823
+    $pos_derniere_boucle_anonyme = $pos_debut_texte;
824
+
825
+    $current_pos = $pos_debut_texte;
826
+    while (($pos_boucle = strpos($texte, BALISE_BOUCLE, $current_pos)) !== false) {
827
+        $current_pos = $pos_boucle + 1;
828
+        $pos_parent = strpos($texte, '(', $pos_boucle);
829
+
830
+        $id_boucle = '';
831
+        if ($pos_parent !== false) {
832
+            $id_boucle = trim(substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)));
833
+        }
834
+        if (
835
+            $pos_parent === false
836
+            or (strlen($id_boucle) and !(is_numeric($id_boucle) or strpos($id_boucle, '_') === 0))
837
+        ) {
838
+            $result = new Boucle();
839
+            $result->id_parent = $id_parent;
840
+            $result->descr = $descr;
841
+
842
+            // un id_boucle pour l'affichage de l'erreur
843
+            if (!strlen($id_boucle)) {
844
+                $id_boucle = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
845
+            }
846
+            $result->id_boucle = $id_boucle;
847
+            $err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
848
+            erreur_squelette($err_b, $result);
849
+
850
+            continue;
851
+        }
852
+        else {
853
+            $boucle = [
854
+                'id_boucle' => $id_boucle,
855
+                'id_boucle_err' => $id_boucle,
856
+                'debut_boucle' => $pos_boucle,
857
+                'pos_boucle' => $pos_boucle,
858
+                'pos_parent' => $pos_parent,
859
+                'pos_precond' => false,
860
+                'pos_precond_inside' => false,
861
+                'pos_preaff' => false,
862
+                'pos_preaff_inside' => false,
863
+            ];
864
+
865
+            // un id_boucle pour l'affichage de l'erreur sur les boucle anonymes
866
+            if (!strlen($id_boucle)) {
867
+                $boucle['id_boucle_err'] = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
868
+            }
869
+
870
+            // trouver sa position de depart reelle : au <Bxx> ou au <BBxx>
871
+            $precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
872
+            $pos_precond = strpos($texte, $precond_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
873
+            if (
874
+                $pos_precond !== false
875
+                and $pos_precond < $boucle['debut_boucle']
876
+            ) {
877
+                $boucle['debut_boucle'] = $pos_precond;
878
+                $boucle['pos_precond'] = $pos_precond;
879
+                $boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
880
+            }
881
+
882
+            $preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
883
+            $pos_preaff = strpos($texte, $preaff_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
884
+            if (
885
+                $pos_preaff !== false
886
+                and $pos_preaff < $boucle['debut_boucle']
887
+            ) {
888
+                $boucle['debut_boucle'] = $pos_preaff;
889
+                $boucle['pos_preaff'] = $pos_preaff;
890
+                $boucle['pos_preaff_inside'] = $pos_preaff + strlen($preaff_boucle);
891
+            }
892
+            if (!strlen($id_boucle)) {
893
+                $pos_derniere_boucle_anonyme = $pos_boucle;
894
+            }
895
+
896
+            if (is_null($premiere_boucle) or $premiere_boucle['debut_boucle'] > $boucle['debut_boucle']) {
897
+                $premiere_boucle = $boucle;
898
+            }
899
+        }
900
+    }
901
+
902
+    return $premiere_boucle;
903 903
 }
904 904
 
905 905
 /**
@@ -914,68 +914,68 @@  discard block
 block discarded – undo
914 914
  * @return mixed
915 915
  */
916 916
 function public_trouver_fin_boucle($texte, $id_parent, $boucle, $pos_debut_texte, $result) {
917
-	$id_boucle = $boucle['id_boucle'];
918
-	$pos_courante = $pos_debut_texte;
919
-
920
-	$boucle['pos_postcond'] = false;
921
-	$boucle['pos_postcond_inside'] = false;
922
-	$boucle['pos_altern'] = false;
923
-	$boucle['pos_altern_inside'] = false;
924
-	$boucle['pos_postaff'] = false;
925
-	$boucle['pos_postaff_inside'] = false;
926
-
927
-	$pos_anonyme_next = null;
928
-	// si c'est une boucle anonyme, chercher la position de la prochaine boucle anonyme
929
-	if (!strlen($id_boucle)) {
930
-		$pos_anonyme_next = strpos($texte, BALISE_BOUCLE . '(', $pos_courante);
931
-	}
932
-
933
-	//
934
-	// 1. Recuperer la partie conditionnelle apres
935
-	//
936
-	$apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . '>';
937
-	$pos_apres = strpos($texte, $apres_boucle, $pos_courante);
938
-	if (
939
-		$pos_apres !== false
940
-		and (!$pos_anonyme_next or $pos_apres < $pos_anonyme_next)
941
-	) {
942
-		$boucle['pos_postcond'] = $pos_apres;
943
-		$pos_apres += strlen($apres_boucle);
944
-		$boucle['pos_postcond_inside'] = $pos_apres;
945
-		$pos_courante = $pos_apres ;
946
-	}
947
-
948
-	//
949
-	// 2. Récuperer la partie alternative apres
950
-	//
951
-	$altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . '>';
952
-	$pos_altern = strpos($texte, $altern_boucle, $pos_courante);
953
-	if (
954
-		$pos_altern !== false
955
-		and (!$pos_anonyme_next or $pos_altern < $pos_anonyme_next)
956
-	) {
957
-		$boucle['pos_altern'] = $pos_altern;
958
-		$pos_altern += strlen($altern_boucle);
959
-		$boucle['pos_altern_inside'] = $pos_altern;
960
-		$pos_courante = $pos_altern;
961
-	}
962
-
963
-	//
964
-	// 3. Recuperer la partie footer non alternative
965
-	//
966
-	$postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . '>';
967
-	$pos_postaff = strpos($texte, $postaff_boucle, $pos_courante);
968
-	if (
969
-		$pos_postaff !== false
970
-		and (!$pos_anonyme_next or $pos_postaff < $pos_anonyme_next)
971
-	) {
972
-		$boucle['pos_postaff'] = $pos_postaff;
973
-		$pos_postaff += strlen($postaff_boucle);
974
-		$boucle['pos_postaff_inside'] = $pos_postaff;
975
-		$pos_courante = $pos_postaff ;
976
-	}
977
-
978
-	return $boucle;
917
+    $id_boucle = $boucle['id_boucle'];
918
+    $pos_courante = $pos_debut_texte;
919
+
920
+    $boucle['pos_postcond'] = false;
921
+    $boucle['pos_postcond_inside'] = false;
922
+    $boucle['pos_altern'] = false;
923
+    $boucle['pos_altern_inside'] = false;
924
+    $boucle['pos_postaff'] = false;
925
+    $boucle['pos_postaff_inside'] = false;
926
+
927
+    $pos_anonyme_next = null;
928
+    // si c'est une boucle anonyme, chercher la position de la prochaine boucle anonyme
929
+    if (!strlen($id_boucle)) {
930
+        $pos_anonyme_next = strpos($texte, BALISE_BOUCLE . '(', $pos_courante);
931
+    }
932
+
933
+    //
934
+    // 1. Recuperer la partie conditionnelle apres
935
+    //
936
+    $apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . '>';
937
+    $pos_apres = strpos($texte, $apres_boucle, $pos_courante);
938
+    if (
939
+        $pos_apres !== false
940
+        and (!$pos_anonyme_next or $pos_apres < $pos_anonyme_next)
941
+    ) {
942
+        $boucle['pos_postcond'] = $pos_apres;
943
+        $pos_apres += strlen($apres_boucle);
944
+        $boucle['pos_postcond_inside'] = $pos_apres;
945
+        $pos_courante = $pos_apres ;
946
+    }
947
+
948
+    //
949
+    // 2. Récuperer la partie alternative apres
950
+    //
951
+    $altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . '>';
952
+    $pos_altern = strpos($texte, $altern_boucle, $pos_courante);
953
+    if (
954
+        $pos_altern !== false
955
+        and (!$pos_anonyme_next or $pos_altern < $pos_anonyme_next)
956
+    ) {
957
+        $boucle['pos_altern'] = $pos_altern;
958
+        $pos_altern += strlen($altern_boucle);
959
+        $boucle['pos_altern_inside'] = $pos_altern;
960
+        $pos_courante = $pos_altern;
961
+    }
962
+
963
+    //
964
+    // 3. Recuperer la partie footer non alternative
965
+    //
966
+    $postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . '>';
967
+    $pos_postaff = strpos($texte, $postaff_boucle, $pos_courante);
968
+    if (
969
+        $pos_postaff !== false
970
+        and (!$pos_anonyme_next or $pos_postaff < $pos_anonyme_next)
971
+    ) {
972
+        $boucle['pos_postaff'] = $pos_postaff;
973
+        $pos_postaff += strlen($postaff_boucle);
974
+        $boucle['pos_postaff_inside'] = $pos_postaff;
975
+        $pos_courante = $pos_postaff ;
976
+    }
977
+
978
+    return $boucle;
979 979
 }
980 980
 
981 981
 
@@ -985,21 +985,21 @@  discard block
 block discarded – undo
985 985
  * @param null|object $boucle
986 986
  */
987 987
 function phraser_boucle_placeholder(&$champ, $boucle_placeholder = null, $boucle = null) {
988
-	static $boucles_connues = [];
989
-	// si c'est un appel pour memoriser une boucle, memorisons la
990
-	if (is_string($champ) and !empty($boucle_placeholder) and !empty($boucle)) {
991
-		$boucles_connues[$boucle_placeholder][$champ] = &$boucle;
992
-	}
993
-	else {
994
-		if (!empty($champ->nom_champ) and !empty($boucles_connues[$champ->nom_champ])) {
995
-			$placeholder = $champ->nom_champ;
996
-			$id = reset($champ->param[0][1]);
997
-			$id = $id->texte;
998
-			if (!empty($boucles_connues[$placeholder][$id])) {
999
-				$champ = $boucles_connues[$placeholder][$id];
1000
-			}
1001
-		}
1002
-	}
988
+    static $boucles_connues = [];
989
+    // si c'est un appel pour memoriser une boucle, memorisons la
990
+    if (is_string($champ) and !empty($boucle_placeholder) and !empty($boucle)) {
991
+        $boucles_connues[$boucle_placeholder][$champ] = &$boucle;
992
+    }
993
+    else {
994
+        if (!empty($champ->nom_champ) and !empty($boucles_connues[$champ->nom_champ])) {
995
+            $placeholder = $champ->nom_champ;
996
+            $id = reset($champ->param[0][1]);
997
+            $id = $id->texte;
998
+            if (!empty($boucles_connues[$placeholder][$id])) {
999
+                $champ = $boucles_connues[$placeholder][$id];
1000
+            }
1001
+        }
1002
+    }
1003 1003
 }
1004 1004
 
1005 1005
 
@@ -1012,274 +1012,274 @@  discard block
 block discarded – undo
1012 1012
  * @return string
1013 1013
  */
1014 1014
 function public_generer_boucle_placeholder($id_boucle, &$boucle, $boucle_placeholder, $nb_lignes) {
1015
-	$placeholder = "[(#{$boucle_placeholder}{" . $id_boucle . '})' . str_pad('', $nb_lignes, "\n") . ']';
1016
-	//memoriser la boucle a reinjecter
1017
-	$id_boucle = "$id_boucle";
1018
-	phraser_boucle_placeholder($id_boucle, $boucle_placeholder, $boucle);
1019
-	return $placeholder;
1015
+    $placeholder = "[(#{$boucle_placeholder}{" . $id_boucle . '})' . str_pad('', $nb_lignes, "\n") . ']';
1016
+    //memoriser la boucle a reinjecter
1017
+    $id_boucle = "$id_boucle";
1018
+    phraser_boucle_placeholder($id_boucle, $boucle_placeholder, $boucle);
1019
+    return $placeholder;
1020 1020
 }
1021 1021
 
1022 1022
 function public_phraser_html_dist($texte, $id_parent, &$boucles, $descr, $ligne_debut_texte = 1, $boucle_placeholder = null) {
1023 1023
 
1024
-	$all_res = [];
1025
-	// definir un placholder pour les boucles dont on est sur d'avoir aucune occurence dans le squelette
1026
-	if (is_null($boucle_placeholder)) {
1027
-		do {
1028
-			$boucle_placeholder = 'BOUCLE_PLACEHOLDER_' . strtoupper(md5(uniqid()));
1029
-		} while (strpos($texte, $boucle_placeholder) !== false);
1030
-	}
1031
-
1032
-	$ligne_debut_initial = $ligne_debut_texte;
1033
-	$pos_debut_texte = 0;
1034
-	while ($boucle = public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte)) {
1035
-		$err_b = ''; // indiquera s'il y a eu une erreur
1036
-		$result = new Boucle();
1037
-		$result->id_parent = $id_parent;
1038
-		$result->descr = $descr;
1039
-
1040
-		$pos_courante = $boucle['pos_boucle'];
1041
-		$pos_parent = $boucle['pos_parent'];
1042
-		$id_boucle_search = $id_boucle = $boucle['id_boucle'];
1043
-
1044
-		$ligne_preaff = $ligne_avant = $ligne_milieu = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_parent);
1045
-
1046
-		// boucle anonyme ?
1047
-		if (!strlen($id_boucle)) {
1048
-			$id_boucle = '_anon_L' . $ligne_milieu . '_' . substr(md5('anonyme:' . $id_parent . ':' . json_encode($boucle, JSON_THROW_ON_ERROR)), 0, 8);
1049
-		}
1050
-
1051
-		$pos_debut_boucle = $pos_courante;
1052
-
1053
-		$pos_milieu = $pos_parent;
1054
-
1055
-		// Regarder si on a une partie conditionnelle avant <B_xxx>
1056
-		if ($boucle['pos_precond'] !== false) {
1057
-			$pos_debut_boucle = $boucle['pos_precond'];
1058
-
1059
-			$pos_avant = $boucle['pos_precond_inside'];
1060
-			$result->avant = substr($texte, $pos_avant, $pos_courante - $pos_avant);
1061
-			$ligne_avant = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_avant);
1062
-		}
1063
-
1064
-		// Regarder si on a une partie inconditionnelle avant <BB_xxx>
1065
-		if ($boucle['pos_preaff'] !== false) {
1066
-			$end_preaff = $pos_debut_boucle;
1067
-
1068
-			$pos_preaff = $boucle['pos_preaff_inside'];
1069
-			$result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
1070
-			$ligne_preaff = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_preaff);
1071
-		}
1072
-
1073
-		$result->id_boucle = $id_boucle;
1074
-
1075
-		if (
1076
-			!preg_match(SPEC_BOUCLE, $texte, $match, 0, $pos_milieu)
1077
-			or ($pos_match = strpos($texte, (string) $match[0], $pos_milieu)) === false
1078
-			or $pos_match > $pos_milieu
1079
-		) {
1080
-			$err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
1081
-			erreur_squelette($err_b, $result);
1082
-
1083
-			$ligne_debut_texte += public_compte_ligne($texte, $pos_debut_texte, $pos_courante + 1);
1084
-			$pos_debut_texte = $pos_courante + 1;
1085
-			continue;
1086
-		}
1087
-
1088
-		$result->type_requete = $match[0];
1089
-		$pos_milieu += strlen($match[0]);
1090
-		$pos_courante = $pos_milieu; // on s'en sert pour compter les lignes plus precisemment
1091
-
1092
-		$type = $match[1];
1093
-		$jointures = trim($match[2]);
1094
-		$table_optionnelle = ($match[3]);
1095
-		if ($jointures) {
1096
-			// on affecte pas ici les jointures explicites, mais dans la compilation
1097
-			// ou elles seront completees des jointures declarees
1098
-			$result->jointures_explicites = $jointures;
1099
-		}
1100
-
1101
-		if ($table_optionnelle) {
1102
-			$result->table_optionnelle = $type;
1103
-		}
1104
-
1105
-		// 1ere passe sur les criteres, vu comme des arguments sans fct
1106
-		// Resultat mis dans result->param
1107
-		$pos_fin_criteres = $pos_milieu;
1108
-		phraser_args($texte, '/>', '', $all_res, $result, $pos_fin_criteres);
1109
-
1110
-		// En 2e passe result->criteres contiendra un tableau
1111
-		// pour l'instant on met le source (chaine) :
1112
-		// si elle reste ici au final, c'est qu'elle contient une erreur
1113
-		$pos_courante = $pos_fin_criteres; // on s'en sert pour compter les lignes plus precisemment
1114
-		$result->criteres = substr($texte, $pos_milieu, $pos_fin_criteres - $pos_milieu);
1115
-		$pos_milieu = $pos_fin_criteres;
1116
-
1117
-		//
1118
-		// Recuperer la fin :
1119
-		//
1120
-		if ($texte[$pos_milieu] === '/') {
1121
-			// boucle autofermante : pas de partie conditionnelle apres
1122
-			$pos_courante += 2;
1123
-			$result->milieu = '';
1124
-		} else {
1125
-			$pos_milieu += 1;
1126
-
1127
-			$fin_boucle = BALISE_FIN_BOUCLE . $id_boucle_search . '>';
1128
-			$pos_fin = strpos($texte, $fin_boucle, $pos_milieu);
1129
-			if ($pos_fin === false) {
1130
-				$err_b = [
1131
-					'zbug_erreur_boucle_fermant',
1132
-					['id' => $id_boucle]
1133
-				];
1134
-				erreur_squelette($err_b, $result);
1135
-				$pos_courante += strlen($fin_boucle);
1136
-			}
1137
-			else {
1138
-				// verifier une eventuelle imbrication d'une boucle homonyme
1139
-				// (interdite, generera une erreur plus loin, mais permet de signaler la bonne erreur)
1140
-				$search_debut_boucle = BALISE_BOUCLE . $id_boucle_search . '(';
1141
-				$search_from = $pos_milieu;
1142
-				$nb_open = 1;
1143
-				$nb_close = 1;
1144
-				$maxiter = 0;
1145
-				do {
1146
-					while (
1147
-						$nb_close < $nb_open
1148
-						and $p = strpos($texte, $fin_boucle, $pos_fin + 1)
1149
-					) {
1150
-						$nb_close++;
1151
-						$pos_fin = $p;
1152
-					}
1153
-					// si on a pas trouve assez de boucles fermantes, sortir de la, on a fait de notre mieux
1154
-					if ($nb_close < $nb_open) {
1155
-						break;
1156
-					}
1157
-					while (
1158
-						$p = strpos($texte, $search_debut_boucle, $search_from)
1159
-						and $p < $pos_fin
1160
-					) {
1161
-						$nb_open++;
1162
-						$search_from = $p + 1;
1163
-					}
1164
-				} while ($nb_close < $nb_open and $maxiter++ < 5);
1165
-
1166
-				$pos_courante = $pos_fin + strlen($fin_boucle);
1167
-			}
1168
-			$result->milieu = substr($texte, $pos_milieu, $pos_fin - $pos_milieu);
1169
-		}
1170
-
1171
-		$ligne_suite = $ligne_apres = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_courante);
1172
-		$boucle = public_trouver_fin_boucle($texte, $id_parent, $boucle, $pos_courante, $result);
1173
-
1174
-		//
1175
-		// 1. Partie conditionnelle apres ?
1176
-		//
1177
-		if ($boucle['pos_postcond']) {
1178
-			$result->apres = substr($texte, $pos_courante, $boucle['pos_postcond'] - $pos_courante);
1179
-			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postcond_inside']);
1180
-			$pos_courante = $boucle['pos_postcond_inside'] ;
1181
-		}
1182
-
1183
-
1184
-		//
1185
-		// 2. Partie alternative apres ?
1186
-		//
1187
-		$ligne_altern = $ligne_suite;
1188
-		if ($boucle['pos_altern']) {
1189
-			$result->altern = substr($texte, $pos_courante, $boucle['pos_altern'] - $pos_courante);
1190
-			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_altern_inside']);
1191
-			$pos_courante = $boucle['pos_altern_inside'];
1192
-		}
1193
-
1194
-		//
1195
-		// 3. Partie footer non alternative ?
1196
-		//
1197
-		$ligne_postaff = $ligne_suite;
1198
-		if ($boucle['pos_postaff']) {
1199
-			$result->postaff = substr($texte, $pos_courante, $boucle['pos_postaff'] - $pos_courante);
1200
-			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postaff_inside']);
1201
-			$pos_courante = $boucle['pos_postaff_inside'];
1202
-		}
1203
-
1204
-		$result->ligne = $ligne_preaff;
1205
-
1206
-		if ($p = strpos($type, ':')) {
1207
-			$result->sql_serveur = substr($type, 0, $p);
1208
-			$type = substr($type, $p + 1);
1209
-		}
1210
-		$soustype = strtolower($type);
1211
-
1212
-		if (!isset($GLOBALS['table_des_tables'][$soustype])) {
1213
-			$soustype = $type;
1214
-		}
1215
-
1216
-		$result->type_requete = $soustype;
1217
-		// Lancer la 2e passe sur les criteres si la 1ere etait bonne
1218
-		if (!is_array($result->param)) {
1219
-			$err_b = true;
1220
-		} else {
1221
-			phraser_criteres($result->param, $result);
1222
-			if (strncasecmp($soustype, TYPE_RECURSIF, strlen(TYPE_RECURSIF)) == 0) {
1223
-				$result->type_requete = TYPE_RECURSIF;
1224
-				$args = $result->param;
1225
-				array_unshift(
1226
-					$args,
1227
-					substr($type, strlen(TYPE_RECURSIF))
1228
-				);
1229
-				$result->param = $args;
1230
-			}
1231
-		}
1232
-
1233
-		$descr['id_mere_contexte'] = $id_boucle;
1234
-		$result->milieu = public_phraser_html_dist($result->milieu, $id_boucle, $boucles, $descr, $ligne_milieu, $boucle_placeholder);
1235
-		// reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre
1236
-		// ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle
1237
-		// si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite
1238
-		if (empty($boucles[$id_boucle])) {
1239
-			$boucles[$id_boucle] = null;
1240
-		}
1241
-		$result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff, $boucle_placeholder);
1242
-		$result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant, $boucle_placeholder);
1243
-		$result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres, $boucle_placeholder);
1244
-		$result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern, $boucle_placeholder);
1245
-		$result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff, $boucle_placeholder);
1246
-
1247
-		// Prevenir le generateur de code que le squelette est faux
1248
-		if ($err_b) {
1249
-			$result->type_requete = false;
1250
-		}
1251
-
1252
-		// Verifier qu'il n'y a pas double definition
1253
-		// apres analyse des sous-parties (pas avant).
1254
-		if (!empty($boucles[$id_boucle])) {
1255
-			if ($boucles[$id_boucle]->type_requete !== false) {
1256
-				$err_b_d = [
1257
-					'zbug_erreur_boucle_double',
1258
-					['id' => $id_boucle]
1259
-				];
1260
-				erreur_squelette($err_b_d, $result);
1261
-				// Prevenir le generateur de code que le squelette est faux
1262
-				$boucles[$id_boucle]->type_requete = false;
1263
-			}
1264
-		} else {
1265
-			$boucles[$id_boucle] = $result;
1266
-		}
1267
-
1268
-		// remplacer la boucle par un placeholder qui compte le meme nombre de lignes
1269
-		$placeholder = public_generer_boucle_placeholder($id_boucle, $boucles[$id_boucle], $boucle_placeholder, $ligne_suite - $ligne_debut_texte);
1270
-		$longueur_boucle = $pos_courante - $boucle['debut_boucle'];
1271
-		$texte = substr_replace($texte, $placeholder, $boucle['debut_boucle'], $longueur_boucle);
1272
-		$pos_courante = $pos_courante - $longueur_boucle + strlen($placeholder);
1273
-
1274
-		// phraser la partie avant le debut de la boucle
1275
-		#$all_res = phraser_champs_etendus(substr($texte, $pos_debut_texte, $boucle['debut_boucle'] - $pos_debut_texte), $ligne_debut_texte, $all_res);
1276
-		#$all_res[] = &$boucles[$id_boucle];
1277
-
1278
-		$ligne_debut_texte = $ligne_suite;
1279
-		$pos_debut_texte = $pos_courante;
1280
-	}
1281
-
1282
-	$all_res = phraser_champs_etendus($texte, $ligne_debut_initial, $all_res);
1283
-
1284
-	return $all_res;
1024
+    $all_res = [];
1025
+    // definir un placholder pour les boucles dont on est sur d'avoir aucune occurence dans le squelette
1026
+    if (is_null($boucle_placeholder)) {
1027
+        do {
1028
+            $boucle_placeholder = 'BOUCLE_PLACEHOLDER_' . strtoupper(md5(uniqid()));
1029
+        } while (strpos($texte, $boucle_placeholder) !== false);
1030
+    }
1031
+
1032
+    $ligne_debut_initial = $ligne_debut_texte;
1033
+    $pos_debut_texte = 0;
1034
+    while ($boucle = public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte)) {
1035
+        $err_b = ''; // indiquera s'il y a eu une erreur
1036
+        $result = new Boucle();
1037
+        $result->id_parent = $id_parent;
1038
+        $result->descr = $descr;
1039
+
1040
+        $pos_courante = $boucle['pos_boucle'];
1041
+        $pos_parent = $boucle['pos_parent'];
1042
+        $id_boucle_search = $id_boucle = $boucle['id_boucle'];
1043
+
1044
+        $ligne_preaff = $ligne_avant = $ligne_milieu = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_parent);
1045
+
1046
+        // boucle anonyme ?
1047
+        if (!strlen($id_boucle)) {
1048
+            $id_boucle = '_anon_L' . $ligne_milieu . '_' . substr(md5('anonyme:' . $id_parent . ':' . json_encode($boucle, JSON_THROW_ON_ERROR)), 0, 8);
1049
+        }
1050
+
1051
+        $pos_debut_boucle = $pos_courante;
1052
+
1053
+        $pos_milieu = $pos_parent;
1054
+
1055
+        // Regarder si on a une partie conditionnelle avant <B_xxx>
1056
+        if ($boucle['pos_precond'] !== false) {
1057
+            $pos_debut_boucle = $boucle['pos_precond'];
1058
+
1059
+            $pos_avant = $boucle['pos_precond_inside'];
1060
+            $result->avant = substr($texte, $pos_avant, $pos_courante - $pos_avant);
1061
+            $ligne_avant = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_avant);
1062
+        }
1063
+
1064
+        // Regarder si on a une partie inconditionnelle avant <BB_xxx>
1065
+        if ($boucle['pos_preaff'] !== false) {
1066
+            $end_preaff = $pos_debut_boucle;
1067
+
1068
+            $pos_preaff = $boucle['pos_preaff_inside'];
1069
+            $result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
1070
+            $ligne_preaff = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_preaff);
1071
+        }
1072
+
1073
+        $result->id_boucle = $id_boucle;
1074
+
1075
+        if (
1076
+            !preg_match(SPEC_BOUCLE, $texte, $match, 0, $pos_milieu)
1077
+            or ($pos_match = strpos($texte, (string) $match[0], $pos_milieu)) === false
1078
+            or $pos_match > $pos_milieu
1079
+        ) {
1080
+            $err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
1081
+            erreur_squelette($err_b, $result);
1082
+
1083
+            $ligne_debut_texte += public_compte_ligne($texte, $pos_debut_texte, $pos_courante + 1);
1084
+            $pos_debut_texte = $pos_courante + 1;
1085
+            continue;
1086
+        }
1087
+
1088
+        $result->type_requete = $match[0];
1089
+        $pos_milieu += strlen($match[0]);
1090
+        $pos_courante = $pos_milieu; // on s'en sert pour compter les lignes plus precisemment
1091
+
1092
+        $type = $match[1];
1093
+        $jointures = trim($match[2]);
1094
+        $table_optionnelle = ($match[3]);
1095
+        if ($jointures) {
1096
+            // on affecte pas ici les jointures explicites, mais dans la compilation
1097
+            // ou elles seront completees des jointures declarees
1098
+            $result->jointures_explicites = $jointures;
1099
+        }
1100
+
1101
+        if ($table_optionnelle) {
1102
+            $result->table_optionnelle = $type;
1103
+        }
1104
+
1105
+        // 1ere passe sur les criteres, vu comme des arguments sans fct
1106
+        // Resultat mis dans result->param
1107
+        $pos_fin_criteres = $pos_milieu;
1108
+        phraser_args($texte, '/>', '', $all_res, $result, $pos_fin_criteres);
1109
+
1110
+        // En 2e passe result->criteres contiendra un tableau
1111
+        // pour l'instant on met le source (chaine) :
1112
+        // si elle reste ici au final, c'est qu'elle contient une erreur
1113
+        $pos_courante = $pos_fin_criteres; // on s'en sert pour compter les lignes plus precisemment
1114
+        $result->criteres = substr($texte, $pos_milieu, $pos_fin_criteres - $pos_milieu);
1115
+        $pos_milieu = $pos_fin_criteres;
1116
+
1117
+        //
1118
+        // Recuperer la fin :
1119
+        //
1120
+        if ($texte[$pos_milieu] === '/') {
1121
+            // boucle autofermante : pas de partie conditionnelle apres
1122
+            $pos_courante += 2;
1123
+            $result->milieu = '';
1124
+        } else {
1125
+            $pos_milieu += 1;
1126
+
1127
+            $fin_boucle = BALISE_FIN_BOUCLE . $id_boucle_search . '>';
1128
+            $pos_fin = strpos($texte, $fin_boucle, $pos_milieu);
1129
+            if ($pos_fin === false) {
1130
+                $err_b = [
1131
+                    'zbug_erreur_boucle_fermant',
1132
+                    ['id' => $id_boucle]
1133
+                ];
1134
+                erreur_squelette($err_b, $result);
1135
+                $pos_courante += strlen($fin_boucle);
1136
+            }
1137
+            else {
1138
+                // verifier une eventuelle imbrication d'une boucle homonyme
1139
+                // (interdite, generera une erreur plus loin, mais permet de signaler la bonne erreur)
1140
+                $search_debut_boucle = BALISE_BOUCLE . $id_boucle_search . '(';
1141
+                $search_from = $pos_milieu;
1142
+                $nb_open = 1;
1143
+                $nb_close = 1;
1144
+                $maxiter = 0;
1145
+                do {
1146
+                    while (
1147
+                        $nb_close < $nb_open
1148
+                        and $p = strpos($texte, $fin_boucle, $pos_fin + 1)
1149
+                    ) {
1150
+                        $nb_close++;
1151
+                        $pos_fin = $p;
1152
+                    }
1153
+                    // si on a pas trouve assez de boucles fermantes, sortir de la, on a fait de notre mieux
1154
+                    if ($nb_close < $nb_open) {
1155
+                        break;
1156
+                    }
1157
+                    while (
1158
+                        $p = strpos($texte, $search_debut_boucle, $search_from)
1159
+                        and $p < $pos_fin
1160
+                    ) {
1161
+                        $nb_open++;
1162
+                        $search_from = $p + 1;
1163
+                    }
1164
+                } while ($nb_close < $nb_open and $maxiter++ < 5);
1165
+
1166
+                $pos_courante = $pos_fin + strlen($fin_boucle);
1167
+            }
1168
+            $result->milieu = substr($texte, $pos_milieu, $pos_fin - $pos_milieu);
1169
+        }
1170
+
1171
+        $ligne_suite = $ligne_apres = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_courante);
1172
+        $boucle = public_trouver_fin_boucle($texte, $id_parent, $boucle, $pos_courante, $result);
1173
+
1174
+        //
1175
+        // 1. Partie conditionnelle apres ?
1176
+        //
1177
+        if ($boucle['pos_postcond']) {
1178
+            $result->apres = substr($texte, $pos_courante, $boucle['pos_postcond'] - $pos_courante);
1179
+            $ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postcond_inside']);
1180
+            $pos_courante = $boucle['pos_postcond_inside'] ;
1181
+        }
1182
+
1183
+
1184
+        //
1185
+        // 2. Partie alternative apres ?
1186
+        //
1187
+        $ligne_altern = $ligne_suite;
1188
+        if ($boucle['pos_altern']) {
1189
+            $result->altern = substr($texte, $pos_courante, $boucle['pos_altern'] - $pos_courante);
1190
+            $ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_altern_inside']);
1191
+            $pos_courante = $boucle['pos_altern_inside'];
1192
+        }
1193
+
1194
+        //
1195
+        // 3. Partie footer non alternative ?
1196
+        //
1197
+        $ligne_postaff = $ligne_suite;
1198
+        if ($boucle['pos_postaff']) {
1199
+            $result->postaff = substr($texte, $pos_courante, $boucle['pos_postaff'] - $pos_courante);
1200
+            $ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postaff_inside']);
1201
+            $pos_courante = $boucle['pos_postaff_inside'];
1202
+        }
1203
+
1204
+        $result->ligne = $ligne_preaff;
1205
+
1206
+        if ($p = strpos($type, ':')) {
1207
+            $result->sql_serveur = substr($type, 0, $p);
1208
+            $type = substr($type, $p + 1);
1209
+        }
1210
+        $soustype = strtolower($type);
1211
+
1212
+        if (!isset($GLOBALS['table_des_tables'][$soustype])) {
1213
+            $soustype = $type;
1214
+        }
1215
+
1216
+        $result->type_requete = $soustype;
1217
+        // Lancer la 2e passe sur les criteres si la 1ere etait bonne
1218
+        if (!is_array($result->param)) {
1219
+            $err_b = true;
1220
+        } else {
1221
+            phraser_criteres($result->param, $result);
1222
+            if (strncasecmp($soustype, TYPE_RECURSIF, strlen(TYPE_RECURSIF)) == 0) {
1223
+                $result->type_requete = TYPE_RECURSIF;
1224
+                $args = $result->param;
1225
+                array_unshift(
1226
+                    $args,
1227
+                    substr($type, strlen(TYPE_RECURSIF))
1228
+                );
1229
+                $result->param = $args;
1230
+            }
1231
+        }
1232
+
1233
+        $descr['id_mere_contexte'] = $id_boucle;
1234
+        $result->milieu = public_phraser_html_dist($result->milieu, $id_boucle, $boucles, $descr, $ligne_milieu, $boucle_placeholder);
1235
+        // reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre
1236
+        // ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle
1237
+        // si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite
1238
+        if (empty($boucles[$id_boucle])) {
1239
+            $boucles[$id_boucle] = null;
1240
+        }
1241
+        $result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff, $boucle_placeholder);
1242
+        $result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant, $boucle_placeholder);
1243
+        $result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres, $boucle_placeholder);
1244
+        $result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern, $boucle_placeholder);
1245
+        $result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff, $boucle_placeholder);
1246
+
1247
+        // Prevenir le generateur de code que le squelette est faux
1248
+        if ($err_b) {
1249
+            $result->type_requete = false;
1250
+        }
1251
+
1252
+        // Verifier qu'il n'y a pas double definition
1253
+        // apres analyse des sous-parties (pas avant).
1254
+        if (!empty($boucles[$id_boucle])) {
1255
+            if ($boucles[$id_boucle]->type_requete !== false) {
1256
+                $err_b_d = [
1257
+                    'zbug_erreur_boucle_double',
1258
+                    ['id' => $id_boucle]
1259
+                ];
1260
+                erreur_squelette($err_b_d, $result);
1261
+                // Prevenir le generateur de code que le squelette est faux
1262
+                $boucles[$id_boucle]->type_requete = false;
1263
+            }
1264
+        } else {
1265
+            $boucles[$id_boucle] = $result;
1266
+        }
1267
+
1268
+        // remplacer la boucle par un placeholder qui compte le meme nombre de lignes
1269
+        $placeholder = public_generer_boucle_placeholder($id_boucle, $boucles[$id_boucle], $boucle_placeholder, $ligne_suite - $ligne_debut_texte);
1270
+        $longueur_boucle = $pos_courante - $boucle['debut_boucle'];
1271
+        $texte = substr_replace($texte, $placeholder, $boucle['debut_boucle'], $longueur_boucle);
1272
+        $pos_courante = $pos_courante - $longueur_boucle + strlen($placeholder);
1273
+
1274
+        // phraser la partie avant le debut de la boucle
1275
+        #$all_res = phraser_champs_etendus(substr($texte, $pos_debut_texte, $boucle['debut_boucle'] - $pos_debut_texte), $ligne_debut_texte, $all_res);
1276
+        #$all_res[] = &$boucles[$id_boucle];
1277
+
1278
+        $ligne_debut_texte = $ligne_suite;
1279
+        $pos_debut_texte = $pos_courante;
1280
+    }
1281
+
1282
+    $all_res = phraser_champs_etendus($texte, $ligne_debut_initial, $all_res);
1283
+
1284
+    return $all_res;
1285 1285
 }
Please login to merge, or discard this patch.
ecrire/public/normaliser.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -52,7 +52,7 @@  discard block
 block discarded – undo
52 52
 			array_shift($p->param);
53 53
 			$p->etoile = '*';
54 54
 			spip_log("filtre de logo obsolete $nom", 'vieilles_defs');
55
-		} elseif (preg_match('/^' . NOM_DE_CHAMP . '(.*)$/sS', $nom, $m)) {
55
+		} elseif (preg_match('/^'.NOM_DE_CHAMP.'(.*)$/sS', $nom, $m)) {
56 56
 			$champ = new Champ();
57 57
 			$champ->nom_boucle = $m[2];
58 58
 			$champ->nom_champ = $m[3];
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
 		$p->param[0][1] = [$c];
129 129
 		$p->param[0][0] = '';
130 130
 		$p->fonctions = [];
131
-		spip_log('FORMULAIRE_RECHERCHE avec filtre ' . $c->texte, 'vieilles_defs');
131
+		spip_log('FORMULAIRE_RECHERCHE avec filtre '.$c->texte, 'vieilles_defs');
132 132
 	}
133 133
 }
134 134
 
Please login to merge, or discard this patch.
Indentation   +159 added lines, -159 removed lines patch added patch discarded remove patch
@@ -11,7 +11,7 @@  discard block
 block discarded – undo
11 11
 \***************************************************************************/
12 12
 
13 13
 if (!defined('_ECRIRE_INC_VERSION')) {
14
-	return;
14
+    return;
15 15
 }
16 16
 
17 17
 // Les fonctions de ce fichier sont appelees en certains points
@@ -25,193 +25,193 @@  discard block
 block discarded – undo
25 25
 // -> https://www.spip.net/fr_article901.html
26 26
 
27 27
 function phraser_vieux_logos(&$p) {
28
-	if ($p->param[0][0]) {
29
-		$args = [''];
30
-	} else {
31
-		$args = array_shift($p->param);
32
-	}
33
-
34
-	foreach ($p->param as $couple) {
35
-		$nom = trim($couple[0]);
36
-		if ($nom == '') {
37
-			array_shift($p->param);
38
-			break;
39
-		}
40
-		$r = phraser_logo_faux_filtres($nom);
41
-		if ($r === 0) {
42
-			$c = new Texte();
43
-			$c->texte = $nom;
44
-			$args[] = [$c];
45
-			array_shift($p->param);
46
-			spip_log("filtre de logo obsolete $nom", 'vieilles_defs');
47
-		} elseif ($r === 2) {
48
-			$p->etoile = '**';
49
-			array_shift($p->param);
50
-			spip_log("filtre de logo obsolete $nom", 'vieilles_defs');
51
-		} elseif ($r === 1) {
52
-			array_shift($p->param);
53
-			$p->etoile = '*';
54
-			spip_log("filtre de logo obsolete $nom", 'vieilles_defs');
55
-		} elseif (preg_match('/^' . NOM_DE_CHAMP . '(.*)$/sS', $nom, $m)) {
56
-			$champ = new Champ();
57
-			$champ->nom_boucle = $m[2];
58
-			$champ->nom_champ = $m[3];
59
-			$champ->etoile = $m[5];
60
-			$champ = [$champ];
61
-			if ($m[6]) {
62
-				$r = new Texte();
63
-				$r->texte = $m[6];
64
-				$champ[] = $r;
65
-			}
66
-			$args[] = $champ;
67
-			array_shift($p->param);
68
-			spip_log("filtre de logo obsolete $nom", 'vieilles_defs');
69
-		} // le cas else est la seule incompatibilite
70
-	}
71
-	array_unshift($p->param, $args);
28
+    if ($p->param[0][0]) {
29
+        $args = [''];
30
+    } else {
31
+        $args = array_shift($p->param);
32
+    }
33
+
34
+    foreach ($p->param as $couple) {
35
+        $nom = trim($couple[0]);
36
+        if ($nom == '') {
37
+            array_shift($p->param);
38
+            break;
39
+        }
40
+        $r = phraser_logo_faux_filtres($nom);
41
+        if ($r === 0) {
42
+            $c = new Texte();
43
+            $c->texte = $nom;
44
+            $args[] = [$c];
45
+            array_shift($p->param);
46
+            spip_log("filtre de logo obsolete $nom", 'vieilles_defs');
47
+        } elseif ($r === 2) {
48
+            $p->etoile = '**';
49
+            array_shift($p->param);
50
+            spip_log("filtre de logo obsolete $nom", 'vieilles_defs');
51
+        } elseif ($r === 1) {
52
+            array_shift($p->param);
53
+            $p->etoile = '*';
54
+            spip_log("filtre de logo obsolete $nom", 'vieilles_defs');
55
+        } elseif (preg_match('/^' . NOM_DE_CHAMP . '(.*)$/sS', $nom, $m)) {
56
+            $champ = new Champ();
57
+            $champ->nom_boucle = $m[2];
58
+            $champ->nom_champ = $m[3];
59
+            $champ->etoile = $m[5];
60
+            $champ = [$champ];
61
+            if ($m[6]) {
62
+                $r = new Texte();
63
+                $r->texte = $m[6];
64
+                $champ[] = $r;
65
+            }
66
+            $args[] = $champ;
67
+            array_shift($p->param);
68
+            spip_log("filtre de logo obsolete $nom", 'vieilles_defs');
69
+        } // le cas else est la seule incompatibilite
70
+    }
71
+    array_unshift($p->param, $args);
72 72
 }
73 73
 
74 74
 
75 75
 function phraser_logo_faux_filtres($nom) {
76
-	switch ($nom) {
77
-		case 'top':
78
-		case 'left':
79
-		case 'right':
80
-		case 'center':
81
-		case 'bottom':
82
-			return 0;
83
-		case 'lien':
84
-			return 1;
85
-		case 'fichier':
86
-			return 2;
87
-		default:
88
-			return $nom;
89
-	}
76
+    switch ($nom) {
77
+        case 'top':
78
+        case 'left':
79
+        case 'right':
80
+        case 'center':
81
+        case 'bottom':
82
+            return 0;
83
+        case 'lien':
84
+            return 1;
85
+        case 'fichier':
86
+            return 2;
87
+        default:
88
+            return $nom;
89
+    }
90 90
 }
91 91
 
92 92
 
93 93
 // La balise embed_document est a present le modele emb
94 94
 
95 95
 function phraser_vieux_emb(&$p) {
96
-	if (!is_array($p->param)) {
97
-		$p->param = [];
98
-	}
99
-
100
-	// Produire le premier argument {emb}
101
-	$texte = new Texte();
102
-	$texte->texte = 'emb';
103
-	$param = ['', [$texte]];
104
-
105
-	// Transformer les filtres en arguments
106
-	for ($i = 0; $i < (is_countable($p->param) ? count($p->param) : 0); $i++) {
107
-		if ($p->param[$i][0]) {
108
-			if (!strstr($p->param[$i][0], '=')) {
109
-				break;
110
-			}# on a rencontre un vrai filtre, c'est fini
111
-			$texte = new Texte();
112
-			$texte->texte = $p->param[$i][0];
113
-			$param[] = [$texte];
114
-		}
115
-		array_shift($p->param);
116
-	}
117
-	array_unshift($p->param, $param);
118
-	spip_log('balise EMBED_DOCUMENT obsolete', 'vieilles_defs');
119
-	$p->nom_champ = 'MODELE';
96
+    if (!is_array($p->param)) {
97
+        $p->param = [];
98
+    }
99
+
100
+    // Produire le premier argument {emb}
101
+    $texte = new Texte();
102
+    $texte->texte = 'emb';
103
+    $param = ['', [$texte]];
104
+
105
+    // Transformer les filtres en arguments
106
+    for ($i = 0; $i < (is_countable($p->param) ? count($p->param) : 0); $i++) {
107
+        if ($p->param[$i][0]) {
108
+            if (!strstr($p->param[$i][0], '=')) {
109
+                break;
110
+            }# on a rencontre un vrai filtre, c'est fini
111
+            $texte = new Texte();
112
+            $texte->texte = $p->param[$i][0];
113
+            $param[] = [$texte];
114
+        }
115
+        array_shift($p->param);
116
+    }
117
+    array_unshift($p->param, $param);
118
+    spip_log('balise EMBED_DOCUMENT obsolete', 'vieilles_defs');
119
+    $p->nom_champ = 'MODELE';
120 120
 }
121 121
 
122 122
 // Vieux formulaire de recherch
123 123
 
124 124
 function phraser_vieux_recherche($p) {
125
-	if ($p->param[0][0]) {
126
-		$c = new Texte();
127
-		$c->texte = $p->param[0][0];
128
-		$p->param[0][1] = [$c];
129
-		$p->param[0][0] = '';
130
-		$p->fonctions = [];
131
-		spip_log('FORMULAIRE_RECHERCHE avec filtre ' . $c->texte, 'vieilles_defs');
132
-	}
125
+    if ($p->param[0][0]) {
126
+        $c = new Texte();
127
+        $c->texte = $p->param[0][0];
128
+        $p->param[0][1] = [$c];
129
+        $p->param[0][0] = '';
130
+        $p->fonctions = [];
131
+        spip_log('FORMULAIRE_RECHERCHE avec filtre ' . $c->texte, 'vieilles_defs');
132
+    }
133 133
 }
134 134
 
135 135
 // Gerer la notation [(#EXPOSER|on,off)]
136 136
 function phraser_vieux_exposer($p) {
137
-	if ($a = $p->fonctions) {
138
-		preg_match('#([^,]*)(,(.*))?#', $a[0][0], $regs);
139
-		$args = [];
140
-		if ($regs[1]) {
141
-			$a = new Texte();
142
-			$a->texte = $regs[1];
143
-			$args = ['', [$a]];
144
-			if ($regs[3]) {
145
-				$a = new Texte();
146
-				$a->texte = $regs[3];
147
-				$args[] = [$a];
148
-			}
149
-		}
150
-		$p->param[0] = $args;
151
-		$p->fonctions = [];
152
-		$p->nom_champ = 'EXPOSE';
153
-	}
137
+    if ($a = $p->fonctions) {
138
+        preg_match('#([^,]*)(,(.*))?#', $a[0][0], $regs);
139
+        $args = [];
140
+        if ($regs[1]) {
141
+            $a = new Texte();
142
+            $a->texte = $regs[1];
143
+            $args = ['', [$a]];
144
+            if ($regs[3]) {
145
+                $a = new Texte();
146
+                $a->texte = $regs[3];
147
+                $args[] = [$a];
148
+            }
149
+        }
150
+        $p->param[0] = $args;
151
+        $p->fonctions = [];
152
+        $p->nom_champ = 'EXPOSE';
153
+    }
154 154
 }
155 155
 
156 156
 function phraser_vieux_modele($p) {
157
- normaliser_args_inclumodel($p);
157
+    normaliser_args_inclumodel($p);
158 158
 }
159 159
 
160 160
 function phraser_vieux_inclu($p) {
161
- normaliser_args_inclumodel($p);
161
+    normaliser_args_inclumodel($p);
162 162
 }
163 163
 
164 164
 function normaliser_args_inclumodel($p) {
165
-	$params = $p->param;
166
-	if (!$params) {
167
-		return;
168
-	}
169
-	$args = $params[0];
170
-	if ($args[0]) {
171
-		return;
172
-	} // filtre immediat
173
-	array_shift($p->param);
174
-	foreach ($p->param as $l) {
175
-		if (!array_shift($l)) {
176
-			$args = array_merge($args, $l);
177
-			array_shift($p->param);
178
-		} else {
179
-			break;
180
-		} // filtre
181
-	}
182
-	array_unshift($p->param, $args);
165
+    $params = $p->param;
166
+    if (!$params) {
167
+        return;
168
+    }
169
+    $args = $params[0];
170
+    if ($args[0]) {
171
+        return;
172
+    } // filtre immediat
173
+    array_shift($p->param);
174
+    foreach ($p->param as $l) {
175
+        if (!array_shift($l)) {
176
+            $args = array_merge($args, $l);
177
+            array_shift($p->param);
178
+        } else {
179
+            break;
180
+        } // filtre
181
+    }
182
+    array_unshift($p->param, $args);
183 183
 }
184 184
 
185 185
 function normaliser_inclure($champ) {
186
-	normaliser_args_inclumodel($champ);
187
-	$l = $champ->param[0];
188
-	if (is_array($l) and !$l[0]) {
189
-		foreach ($l as $k => $p) {
190
-			if ($p and $p[0]->type == 'texte' and !strpos($p[0]->texte, '=')) {
191
-				$p[0]->texte = trim($p[0]->texte);
192
-			}
193
-		}
194
-		foreach ($l as $k => $p) {
195
-			if (
196
-				!$p or $p[0]->type != 'texte' or
197
-				!preg_match('/^fond\s*=\s*(.*)$/', $p[0]->texte, $r)
198
-			) {
199
-				continue;
200
-			}
201
-
202
-			if ($r[1]) {
203
-				$p[0]->texte = $r[1];
204
-			} else {
205
-				unset($p[0]);
206
-			}
207
-			$champ->texte = $p;
208
-			unset($champ->param[0][$k]);
209
-			if ((is_countable($champ->param[0]) ? count($champ->param[0]) : 0) == 1) {
210
-				array_shift($champ->param);
211
-			}
212
-
213
-			return;
214
-		}
215
-	}
216
-	spip_log('inclure sans fond ni fichier');
186
+    normaliser_args_inclumodel($champ);
187
+    $l = $champ->param[0];
188
+    if (is_array($l) and !$l[0]) {
189
+        foreach ($l as $k => $p) {
190
+            if ($p and $p[0]->type == 'texte' and !strpos($p[0]->texte, '=')) {
191
+                $p[0]->texte = trim($p[0]->texte);
192
+            }
193
+        }
194
+        foreach ($l as $k => $p) {
195
+            if (
196
+                !$p or $p[0]->type != 'texte' or
197
+                !preg_match('/^fond\s*=\s*(.*)$/', $p[0]->texte, $r)
198
+            ) {
199
+                continue;
200
+            }
201
+
202
+            if ($r[1]) {
203
+                $p[0]->texte = $r[1];
204
+            } else {
205
+                unset($p[0]);
206
+            }
207
+            $champ->texte = $p;
208
+            unset($champ->param[0][$k]);
209
+            if ((is_countable($champ->param[0]) ? count($champ->param[0]) : 0) == 1) {
210
+                array_shift($champ->param);
211
+            }
212
+
213
+            return;
214
+        }
215
+    }
216
+    spip_log('inclure sans fond ni fichier');
217 217
 }
Please login to merge, or discard this patch.
ecrire/public/boucles.php 2 patches
Indentation   +24 added lines, -24 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
 
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
  *     Code PHP compilé de la boucle
33 33
  **/
34 34
 function boucle_DEFAUT_dist($id_boucle, &$boucles) {
35
-	return calculer_boucle($id_boucle, $boucles);
35
+    return calculer_boucle($id_boucle, $boucles);
36 36
 }
37 37
 
38 38
 
@@ -51,7 +51,7 @@  discard block
 block discarded – undo
51 51
  *     Code PHP compilé de la boucle
52 52
  **/
53 53
 function boucle_BOUCLE_dist($id_boucle, &$boucles) {
54
-	return calculer_boucle($id_boucle, $boucles);
54
+    return calculer_boucle($id_boucle, $boucles);
55 55
 }
56 56
 
57 57
 
@@ -81,30 +81,30 @@  discard block
 block discarded – undo
81 81
  *     Code PHP compilé de la boucle
82 82
  **/
83 83
 function boucle_HIERARCHIE_dist($id_boucle, &$boucles) {
84
-	$boucle = &$boucles[$id_boucle];
85
-	$id_table = $boucle->id_table . '.id_rubrique';
84
+    $boucle = &$boucles[$id_boucle];
85
+    $id_table = $boucle->id_table . '.id_rubrique';
86 86
 
87
-	// Si la boucle mere est une boucle RUBRIQUES il faut ignorer la feuille
88
-	// sauf en presence du critere {tout} (vu par phraser_html)
89
-	// ou {id_article} qui positionne aussi le {tout}
87
+    // Si la boucle mere est une boucle RUBRIQUES il faut ignorer la feuille
88
+    // sauf en presence du critere {tout} (vu par phraser_html)
89
+    // ou {id_article} qui positionne aussi le {tout}
90 90
 
91
-	$boucle->hierarchie = 'if (!($id_rubrique = intval('
92
-		. calculer_argument_precedent($boucle->id_boucle, 'id_rubrique', $boucles)
93
-		. ")))\n\t\treturn '';\n\t"
94
-		. "include_spip('inc/rubriques');\n\t"
95
-		. '$hierarchie = calcul_hierarchie_in($id_rubrique,'
96
-		. (isset($boucle->modificateur['tout']) ? 'true' : 'false')
97
-		. ");\n\t"
98
-		. 'if (!$hierarchie) return "";' . "\n\t";
91
+    $boucle->hierarchie = 'if (!($id_rubrique = intval('
92
+        . calculer_argument_precedent($boucle->id_boucle, 'id_rubrique', $boucles)
93
+        . ")))\n\t\treturn '';\n\t"
94
+        . "include_spip('inc/rubriques');\n\t"
95
+        . '$hierarchie = calcul_hierarchie_in($id_rubrique,'
96
+        . (isset($boucle->modificateur['tout']) ? 'true' : 'false')
97
+        . ");\n\t"
98
+        . 'if (!$hierarchie) return "";' . "\n\t";
99 99
 
100
-	$boucle->where[] = ["'IN'", "'$id_table'", '"($hierarchie)"'];
100
+    $boucle->where[] = ["'IN'", "'$id_table'", '"($hierarchie)"'];
101 101
 
102
-	$order = "FIELD($id_table, \$hierarchie)";
103
-	if (!isset($boucle->default_order[0]) or $boucle->default_order[0] != ' DESC') {
104
-		$boucle->default_order[] = "\"$order\"";
105
-	} else {
106
-		$boucle->default_order[0] = "\"$order DESC\"";
107
-	}
102
+    $order = "FIELD($id_table, \$hierarchie)";
103
+    if (!isset($boucle->default_order[0]) or $boucle->default_order[0] != ' DESC') {
104
+        $boucle->default_order[] = "\"$order\"";
105
+    } else {
106
+        $boucle->default_order[0] = "\"$order DESC\"";
107
+    }
108 108
 
109
-	return calculer_boucle($id_boucle, $boucles);
109
+    return calculer_boucle($id_boucle, $boucles);
110 110
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -82,7 +82,7 @@  discard block
 block discarded – undo
82 82
  **/
83 83
 function boucle_HIERARCHIE_dist($id_boucle, &$boucles) {
84 84
 	$boucle = &$boucles[$id_boucle];
85
-	$id_table = $boucle->id_table . '.id_rubrique';
85
+	$id_table = $boucle->id_table.'.id_rubrique';
86 86
 
87 87
 	// Si la boucle mere est une boucle RUBRIQUES il faut ignorer la feuille
88 88
 	// sauf en presence du critere {tout} (vu par phraser_html)
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
 		. '$hierarchie = calcul_hierarchie_in($id_rubrique,'
96 96
 		. (isset($boucle->modificateur['tout']) ? 'true' : 'false')
97 97
 		. ");\n\t"
98
-		. 'if (!$hierarchie) return "";' . "\n\t";
98
+		. 'if (!$hierarchie) return "";'."\n\t";
99 99
 
100 100
 	$boucle->where[] = ["'IN'", "'$id_table'", '"($hierarchie)"'];
101 101
 
Please login to merge, or discard this patch.