Completed
Push — master ( 4fa0dc...b74578 )
by cam
01:19
created
ecrire/public/assembler.php 1 patch
Indentation   +633 added lines, -633 removed lines patch added patch discarded remove patch
@@ -19,178 +19,178 @@  discard block
 block discarded – undo
19 19
  **/
20 20
 
21 21
 if (!defined('_ECRIRE_INC_VERSION')) {
22
-	return;
22
+    return;
23 23
 }
24 24
 
25 25
 // En cas de modification, il faut aussi actualiser la regexp de nettoyer_uri_var() dans inc/utils.php
26 26
 if (!defined('_CONTEXTE_IGNORE_VARIABLES')) {
27
-	define('_CONTEXTE_IGNORE_VARIABLES', '/(^var_|^PHPSESSID$|^fbclid$|^utm_)/');
27
+    define('_CONTEXTE_IGNORE_VARIABLES', '/(^var_|^PHPSESSID$|^fbclid$|^utm_)/');
28 28
 }
29 29
 
30 30
 function assembler($fond, string $connect = '') {
31 31
 
32
-	$chemin_cache = null;
33
-	$lastmodified = null;
34
-	$res = null;
35
-	// flag_preserver est modifie ici, et utilise en globale
36
-	// use_cache sert a informer le bouton d'admin pr savoir s'il met un *
37
-	// contexte est utilise en globale dans le formulaire d'admin
38
-
39
-	$GLOBALS['contexte'] = calculer_contexte();
40
-	$page = ['contexte_implicite' => calculer_contexte_implicite()];
41
-	$page['contexte_implicite']['cache'] = $fond . preg_replace(
42
-		',\.[a-zA-Z0-9]*$,',
43
-		'',
44
-		preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI'])
45
-	);
46
-	// Cette fonction est utilisee deux fois
47
-	$cacher = charger_fonction('cacher', 'public', true);
48
-	// Les quatre derniers parametres sont modifies par la fonction:
49
-	// emplacement, validite, et, s'il est valide, contenu & age
50
-	if ($cacher) {
51
-		$res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified);
52
-	} else {
53
-		$GLOBALS['use_cache'] = -1;
54
-	}
55
-	// Si un resultat est retourne, c'est un message d'impossibilite
56
-	if ($res) {
57
-		return ['texte' => $res];
58
-	}
59
-
60
-	if (!$chemin_cache || !$lastmodified) {
61
-		$lastmodified = time();
62
-	}
63
-
64
-	$headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD');
65
-	$calculer_page = true;
66
-
67
-	// Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client})
68
-	// une perennite valide a meme reponse qu'une requete HEAD (par defaut les
69
-	// pages sont dynamiques)
70
-	if (
71
-		isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
72
-		and (!defined('_VAR_MODE') or !_VAR_MODE)
73
-		and $chemin_cache
74
-		and isset($page['entetes'])
75
-		and isset($page['entetes']['Cache-Control'])
76
-		and strstr($page['entetes']['Cache-Control'], 'max-age=')
77
-		and !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/')
78
-	) {
79
-		$since = preg_replace(
80
-			'/;.*/',
81
-			'',
82
-			$_SERVER['HTTP_IF_MODIFIED_SINCE']
83
-		);
84
-		$since = str_replace('GMT', '', $since);
85
-		if (trim($since) == gmdate('D, d M Y H:i:s', $lastmodified)) {
86
-			$page['status'] = 304;
87
-			$headers_only = true;
88
-			$calculer_page = false;
89
-		}
90
-	}
91
-
92
-	// Si requete HEAD ou Last-modified compatible, ignorer le texte
93
-	// et pas de content-type (pour contrer le bouton admin de inc-public)
94
-	if (!$calculer_page) {
95
-		$page['texte'] = '';
96
-	} else {
97
-		// si la page est prise dans le cache
98
-		if (!$GLOBALS['use_cache']) {
99
-			// Informer les boutons d'admin du contexte
100
-			// (fourni par urls_decoder_url ci-dessous lors de la mise en cache)
101
-			$GLOBALS['contexte'] = $page['contexte'];
102
-
103
-			// vider les globales url propres qui ne doivent plus etre utilisees en cas
104
-			// d'inversion url => objet
105
-			// plus necessaire si on utilise bien la fonction urls_decoder_url
106
-			#unset($_SERVER['REDIRECT_url_propre']);
107
-			#unset($_ENV['url_propre']);
108
-		} else {
109
-			// Compat ascendante :
110
-			// 1. $contexte est global
111
-			// (a evacuer car urls_decoder_url gere ce probleme ?)
112
-			// et calculer la page
113
-			if (!test_espace_prive()) {
114
-				include_spip('inc/urls');
115
-				[$fond, $GLOBALS['contexte'], $url_redirect] = urls_decoder_url(
116
-					nettoyer_uri(),
117
-					$fond,
118
-					$GLOBALS['contexte'],
119
-					true
120
-				);
121
-			}
122
-			// squelette par defaut
123
-			if (!strlen($fond ?? '')) {
124
-				$fond = 'sommaire';
125
-			}
126
-
127
-			// produire la page : peut mettre a jour $lastmodified
128
-			$produire_page = charger_fonction('produire_page', 'public');
129
-			$page = $produire_page(
130
-				$fond,
131
-				$GLOBALS['contexte'],
132
-				$GLOBALS['use_cache'],
133
-				$chemin_cache,
134
-				null,
135
-				$page,
136
-				$lastmodified,
137
-				$connect
138
-			);
139
-			if ($page === '') {
140
-				$erreur = _T(
141
-					'info_erreur_squelette2',
142
-					['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES]
143
-				);
144
-				erreur_squelette($erreur);
145
-				// eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
146
-				$page = ['texte' => '', 'erreur' => $erreur];
147
-			}
148
-		}
149
-
150
-		if ($page and $chemin_cache) {
151
-			$page['cache'] = $chemin_cache;
152
-		}
153
-
154
-		auto_content_type($page);
155
-
156
-		$GLOBALS['flag_preserver'] |= headers_sent();
157
-
158
-		// Definir les entetes si ce n'est fait
159
-		if (!$GLOBALS['flag_preserver']) {
160
-			// Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions
161
-			if (
162
-				trim($page['texte']) === ''
163
-				and _VAR_MODE !== 'debug'
164
-				and !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur
165
-			) {
166
-				$GLOBALS['contexte']['fond_erreur'] = $fond;
167
-				$page = message_page_indisponible($page, $GLOBALS['contexte']);
168
-			}
169
-			// pas de cache client en mode 'observation'
170
-			if (defined('_VAR_MODE') and _VAR_MODE) {
171
-				$page['entetes']['Cache-Control'] = 'no-cache,must-revalidate';
172
-				$page['entetes']['Pragma'] = 'no-cache';
173
-			}
174
-		}
175
-	}
176
-
177
-	// Entete Last-Modified:
178
-	// eviter d'etre incoherent en envoyant un lastmodified identique
179
-	// a celui qu'on a refuse d'honorer plus haut (cf. #655)
180
-	if (
181
-		$lastmodified
182
-		and !isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
183
-		and !isset($page['entetes']['Last-Modified'])
184
-	) {
185
-		$page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT';
186
-	}
187
-
188
-	// fermer la connexion apres les headers si requete HEAD
189
-	if ($headers_only) {
190
-		$page['entetes']['Connection'] = 'close';
191
-	}
192
-
193
-	return $page;
32
+    $chemin_cache = null;
33
+    $lastmodified = null;
34
+    $res = null;
35
+    // flag_preserver est modifie ici, et utilise en globale
36
+    // use_cache sert a informer le bouton d'admin pr savoir s'il met un *
37
+    // contexte est utilise en globale dans le formulaire d'admin
38
+
39
+    $GLOBALS['contexte'] = calculer_contexte();
40
+    $page = ['contexte_implicite' => calculer_contexte_implicite()];
41
+    $page['contexte_implicite']['cache'] = $fond . preg_replace(
42
+        ',\.[a-zA-Z0-9]*$,',
43
+        '',
44
+        preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI'])
45
+    );
46
+    // Cette fonction est utilisee deux fois
47
+    $cacher = charger_fonction('cacher', 'public', true);
48
+    // Les quatre derniers parametres sont modifies par la fonction:
49
+    // emplacement, validite, et, s'il est valide, contenu & age
50
+    if ($cacher) {
51
+        $res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified);
52
+    } else {
53
+        $GLOBALS['use_cache'] = -1;
54
+    }
55
+    // Si un resultat est retourne, c'est un message d'impossibilite
56
+    if ($res) {
57
+        return ['texte' => $res];
58
+    }
59
+
60
+    if (!$chemin_cache || !$lastmodified) {
61
+        $lastmodified = time();
62
+    }
63
+
64
+    $headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD');
65
+    $calculer_page = true;
66
+
67
+    // Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client})
68
+    // une perennite valide a meme reponse qu'une requete HEAD (par defaut les
69
+    // pages sont dynamiques)
70
+    if (
71
+        isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
72
+        and (!defined('_VAR_MODE') or !_VAR_MODE)
73
+        and $chemin_cache
74
+        and isset($page['entetes'])
75
+        and isset($page['entetes']['Cache-Control'])
76
+        and strstr($page['entetes']['Cache-Control'], 'max-age=')
77
+        and !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/')
78
+    ) {
79
+        $since = preg_replace(
80
+            '/;.*/',
81
+            '',
82
+            $_SERVER['HTTP_IF_MODIFIED_SINCE']
83
+        );
84
+        $since = str_replace('GMT', '', $since);
85
+        if (trim($since) == gmdate('D, d M Y H:i:s', $lastmodified)) {
86
+            $page['status'] = 304;
87
+            $headers_only = true;
88
+            $calculer_page = false;
89
+        }
90
+    }
91
+
92
+    // Si requete HEAD ou Last-modified compatible, ignorer le texte
93
+    // et pas de content-type (pour contrer le bouton admin de inc-public)
94
+    if (!$calculer_page) {
95
+        $page['texte'] = '';
96
+    } else {
97
+        // si la page est prise dans le cache
98
+        if (!$GLOBALS['use_cache']) {
99
+            // Informer les boutons d'admin du contexte
100
+            // (fourni par urls_decoder_url ci-dessous lors de la mise en cache)
101
+            $GLOBALS['contexte'] = $page['contexte'];
102
+
103
+            // vider les globales url propres qui ne doivent plus etre utilisees en cas
104
+            // d'inversion url => objet
105
+            // plus necessaire si on utilise bien la fonction urls_decoder_url
106
+            #unset($_SERVER['REDIRECT_url_propre']);
107
+            #unset($_ENV['url_propre']);
108
+        } else {
109
+            // Compat ascendante :
110
+            // 1. $contexte est global
111
+            // (a evacuer car urls_decoder_url gere ce probleme ?)
112
+            // et calculer la page
113
+            if (!test_espace_prive()) {
114
+                include_spip('inc/urls');
115
+                [$fond, $GLOBALS['contexte'], $url_redirect] = urls_decoder_url(
116
+                    nettoyer_uri(),
117
+                    $fond,
118
+                    $GLOBALS['contexte'],
119
+                    true
120
+                );
121
+            }
122
+            // squelette par defaut
123
+            if (!strlen($fond ?? '')) {
124
+                $fond = 'sommaire';
125
+            }
126
+
127
+            // produire la page : peut mettre a jour $lastmodified
128
+            $produire_page = charger_fonction('produire_page', 'public');
129
+            $page = $produire_page(
130
+                $fond,
131
+                $GLOBALS['contexte'],
132
+                $GLOBALS['use_cache'],
133
+                $chemin_cache,
134
+                null,
135
+                $page,
136
+                $lastmodified,
137
+                $connect
138
+            );
139
+            if ($page === '') {
140
+                $erreur = _T(
141
+                    'info_erreur_squelette2',
142
+                    ['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES]
143
+                );
144
+                erreur_squelette($erreur);
145
+                // eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
146
+                $page = ['texte' => '', 'erreur' => $erreur];
147
+            }
148
+        }
149
+
150
+        if ($page and $chemin_cache) {
151
+            $page['cache'] = $chemin_cache;
152
+        }
153
+
154
+        auto_content_type($page);
155
+
156
+        $GLOBALS['flag_preserver'] |= headers_sent();
157
+
158
+        // Definir les entetes si ce n'est fait
159
+        if (!$GLOBALS['flag_preserver']) {
160
+            // Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions
161
+            if (
162
+                trim($page['texte']) === ''
163
+                and _VAR_MODE !== 'debug'
164
+                and !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur
165
+            ) {
166
+                $GLOBALS['contexte']['fond_erreur'] = $fond;
167
+                $page = message_page_indisponible($page, $GLOBALS['contexte']);
168
+            }
169
+            // pas de cache client en mode 'observation'
170
+            if (defined('_VAR_MODE') and _VAR_MODE) {
171
+                $page['entetes']['Cache-Control'] = 'no-cache,must-revalidate';
172
+                $page['entetes']['Pragma'] = 'no-cache';
173
+            }
174
+        }
175
+    }
176
+
177
+    // Entete Last-Modified:
178
+    // eviter d'etre incoherent en envoyant un lastmodified identique
179
+    // a celui qu'on a refuse d'honorer plus haut (cf. #655)
180
+    if (
181
+        $lastmodified
182
+        and !isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
183
+        and !isset($page['entetes']['Last-Modified'])
184
+    ) {
185
+        $page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT';
186
+    }
187
+
188
+    // fermer la connexion apres les headers si requete HEAD
189
+    if ($headers_only) {
190
+        $page['entetes']['Connection'] = 'close';
191
+    }
192
+
193
+    return $page;
194 194
 }
195 195
 
196 196
 /**
@@ -207,19 +207,19 @@  discard block
 block discarded – undo
207 207
  */
208 208
 function calculer_contexte() {
209 209
 
210
-	$contexte = [];
211
-	foreach ($_GET as $var => $val) {
212
-		if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
213
-			$contexte[$var] = $val;
214
-		}
215
-	}
216
-	foreach ($_POST as $var => $val) {
217
-		if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
218
-			$contexte[$var] = $val;
219
-		}
220
-	}
221
-
222
-	return $contexte;
210
+    $contexte = [];
211
+    foreach ($_GET as $var => $val) {
212
+        if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
213
+            $contexte[$var] = $val;
214
+        }
215
+    }
216
+    foreach ($_POST as $var => $val) {
217
+        if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
218
+            $contexte[$var] = $val;
219
+        }
220
+    }
221
+
222
+    return $contexte;
223 223
 }
224 224
 
225 225
 /**
@@ -230,25 +230,25 @@  discard block
 block discarded – undo
230 230
  * @return array
231 231
  */
232 232
 function calculer_contexte_implicite() {
233
-	static $notes = null;
234
-	if (is_null($notes)) {
235
-		$notes = charger_fonction('notes', 'inc', true);
236
-	}
237
-	$contexte_implicite = [
238
-		'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ?
239
-		'host' => ($_SERVER['HTTP_HOST'] ?? null),
240
-		'https' => ($_SERVER['HTTPS'] ?? ''),
241
-		'espace' => test_espace_prive(),
242
-		'marqueur' => ($GLOBALS['marqueur'] ?? ''),
243
-		'marqueur_skel' => ($GLOBALS['marqueur_skel'] ?? ''),
244
-		'notes' => $notes ? $notes('', 'contexter_cache') : '',
245
-		'spip_version_code' => $GLOBALS['spip_version_code'],
246
-	];
247
-	if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
248
-		$contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST'];
249
-	}
250
-
251
-	return $contexte_implicite;
233
+    static $notes = null;
234
+    if (is_null($notes)) {
235
+        $notes = charger_fonction('notes', 'inc', true);
236
+    }
237
+    $contexte_implicite = [
238
+        'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ?
239
+        'host' => ($_SERVER['HTTP_HOST'] ?? null),
240
+        'https' => ($_SERVER['HTTPS'] ?? ''),
241
+        'espace' => test_espace_prive(),
242
+        'marqueur' => ($GLOBALS['marqueur'] ?? ''),
243
+        'marqueur_skel' => ($GLOBALS['marqueur_skel'] ?? ''),
244
+        'notes' => $notes ? $notes('', 'contexter_cache') : '',
245
+        'spip_version_code' => $GLOBALS['spip_version_code'],
246
+    ];
247
+    if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
248
+        $contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST'];
249
+    }
250
+
251
+    return $contexte_implicite;
252 252
 }
253 253
 
254 254
 //
@@ -257,55 +257,55 @@  discard block
 block discarded – undo
257 257
 
258 258
 function auto_content_type($page) {
259 259
 
260
-	if (!isset($GLOBALS['flag_preserver'])) {
261
-		$GLOBALS['flag_preserver'] = ($page && preg_match(
262
-			'/header\s*\(\s*.content\-type:/isx',
263
-			$page['texte']
264
-		) || (isset($page['entetes']['Content-Type'])));
265
-	}
260
+    if (!isset($GLOBALS['flag_preserver'])) {
261
+        $GLOBALS['flag_preserver'] = ($page && preg_match(
262
+            '/header\s*\(\s*.content\-type:/isx',
263
+            $page['texte']
264
+        ) || (isset($page['entetes']['Content-Type'])));
265
+    }
266 266
 }
267 267
 
268 268
 function inclure_page($fond, $contexte, string $connect = '') {
269
-	$use_cache = null;
270
-	$chemin_cache = null;
271
-	$lastinclude = null;
272
-	$res = null;
273
-	static $cacher, $produire_page;
274
-
275
-	// enlever le fond de contexte inclus car sinon il prend la main
276
-	// dans les sous inclusions -> boucle infinie d'inclusion identique
277
-	// (cette precaution n'est probablement plus utile)
278
-	unset($contexte['fond']);
279
-	$page = ['contexte_implicite' => calculer_contexte_implicite()];
280
-	$page['contexte_implicite']['cache'] = $fond;
281
-	if (is_null($cacher)) {
282
-		$cacher = charger_fonction('cacher', 'public', true);
283
-	}
284
-	// Les quatre derniers parametres sont modifies par la fonction:
285
-	// emplacement, validite, et, s'il est valide, contenu & age
286
-	if ($cacher) {
287
-		$res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude);
288
-	} else {
289
-		$use_cache = -1;
290
-	}
291
-	// $res = message d'erreur : on sort de la
292
-	if ($res) {
293
-		return ['texte' => $res];
294
-	}
295
-
296
-	// Si use_cache ne vaut pas 0, la page doit etre calculee
297
-	// produire la page : peut mettre a jour $lastinclude
298
-	// le contexte_cache envoye a cacher() a ete conserve et est passe a produire
299
-	if ($use_cache) {
300
-		if (is_null($produire_page)) {
301
-			$produire_page = charger_fonction('produire_page', 'public');
302
-		}
303
-		$page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, $contexte, $page, $lastinclude, $connect);
304
-	}
305
-	// dans tous les cas, mettre a jour $GLOBALS['lastmodified']
306
-	$GLOBALS['lastmodified'] = max(($GLOBALS['lastmodified'] ?? 0), $lastinclude);
307
-
308
-	return $page;
269
+    $use_cache = null;
270
+    $chemin_cache = null;
271
+    $lastinclude = null;
272
+    $res = null;
273
+    static $cacher, $produire_page;
274
+
275
+    // enlever le fond de contexte inclus car sinon il prend la main
276
+    // dans les sous inclusions -> boucle infinie d'inclusion identique
277
+    // (cette precaution n'est probablement plus utile)
278
+    unset($contexte['fond']);
279
+    $page = ['contexte_implicite' => calculer_contexte_implicite()];
280
+    $page['contexte_implicite']['cache'] = $fond;
281
+    if (is_null($cacher)) {
282
+        $cacher = charger_fonction('cacher', 'public', true);
283
+    }
284
+    // Les quatre derniers parametres sont modifies par la fonction:
285
+    // emplacement, validite, et, s'il est valide, contenu & age
286
+    if ($cacher) {
287
+        $res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude);
288
+    } else {
289
+        $use_cache = -1;
290
+    }
291
+    // $res = message d'erreur : on sort de la
292
+    if ($res) {
293
+        return ['texte' => $res];
294
+    }
295
+
296
+    // Si use_cache ne vaut pas 0, la page doit etre calculee
297
+    // produire la page : peut mettre a jour $lastinclude
298
+    // le contexte_cache envoye a cacher() a ete conserve et est passe a produire
299
+    if ($use_cache) {
300
+        if (is_null($produire_page)) {
301
+            $produire_page = charger_fonction('produire_page', 'public');
302
+        }
303
+        $page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, $contexte, $page, $lastinclude, $connect);
304
+    }
305
+    // dans tous les cas, mettre a jour $GLOBALS['lastmodified']
306
+    $GLOBALS['lastmodified'] = max(($GLOBALS['lastmodified'] ?? 0), $lastinclude);
307
+
308
+    return $page;
309 309
 }
310 310
 
311 311
 /**
@@ -323,41 +323,41 @@  discard block
 block discarded – undo
323 323
  * @return array
324 324
  */
325 325
 function public_produire_page_dist(
326
-	$fond,
327
-	$contexte,
328
-	$use_cache,
329
-	$chemin_cache,
330
-	$contexte_cache,
331
-	&$page,
332
-	&$lastinclude,
333
-	$connect = ''
326
+    $fond,
327
+    $contexte,
328
+    $use_cache,
329
+    $chemin_cache,
330
+    $contexte_cache,
331
+    &$page,
332
+    &$lastinclude,
333
+    $connect = ''
334 334
 ) {
335
-	static $parametrer, $cacher;
336
-	if (!$parametrer) {
337
-		$parametrer = charger_fonction('parametrer', 'public');
338
-	}
339
-	$page = $parametrer($fond, $contexte, $chemin_cache, $connect);
340
-	// et on l'enregistre sur le disque
341
-	if (
342
-		$chemin_cache
343
-		and $use_cache > -1
344
-		and is_array($page)
345
-		and count($page)
346
-		and isset($page['entetes']['X-Spip-Cache'])
347
-		and $page['entetes']['X-Spip-Cache'] > 0
348
-	) {
349
-		if (is_null($cacher)) {
350
-			$cacher = charger_fonction('cacher', 'public', true);
351
-		}
352
-		$lastinclude = time();
353
-		if ($cacher) {
354
-			$cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude);
355
-		} else {
356
-			$use_cache = -1;
357
-		}
358
-	}
359
-
360
-	return $page;
335
+    static $parametrer, $cacher;
336
+    if (!$parametrer) {
337
+        $parametrer = charger_fonction('parametrer', 'public');
338
+    }
339
+    $page = $parametrer($fond, $contexte, $chemin_cache, $connect);
340
+    // et on l'enregistre sur le disque
341
+    if (
342
+        $chemin_cache
343
+        and $use_cache > -1
344
+        and is_array($page)
345
+        and count($page)
346
+        and isset($page['entetes']['X-Spip-Cache'])
347
+        and $page['entetes']['X-Spip-Cache'] > 0
348
+    ) {
349
+        if (is_null($cacher)) {
350
+            $cacher = charger_fonction('cacher', 'public', true);
351
+        }
352
+        $lastinclude = time();
353
+        if ($cacher) {
354
+            $cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude);
355
+        } else {
356
+            $use_cache = -1;
357
+        }
358
+    }
359
+
360
+    return $page;
361 361
 }
362 362
 
363 363
 // Fonction inseree par le compilateur dans le code compile.
@@ -371,14 +371,14 @@  discard block
 block discarded – undo
371 371
 // 4: langue
372 372
 
373 373
 function inserer_balise_dynamique($contexte_exec, $contexte_compil) {
374
-	arguments_balise_dyn_depuis_modele(null, 'reset');
375
-
376
-	if (!is_array($contexte_exec)) {
377
-		echo $contexte_exec;
378
-	} // message d'erreur etc
379
-	else {
380
-		inclure_balise_dynamique($contexte_exec, true, $contexte_compil);
381
-	}
374
+    arguments_balise_dyn_depuis_modele(null, 'reset');
375
+
376
+    if (!is_array($contexte_exec)) {
377
+        echo $contexte_exec;
378
+    } // message d'erreur etc
379
+    else {
380
+        inclure_balise_dynamique($contexte_exec, true, $contexte_compil);
381
+    }
382 382
 }
383 383
 
384 384
 /**
@@ -391,101 +391,101 @@  discard block
 block discarded – undo
391 391
  * @return string|void
392 392
  */
393 393
 function inclure_balise_dynamique($texte, $echo = true, $contexte_compil = []) {
394
-	if (is_array($texte)) {
395
-		[$fond, $delainc, $contexte_inclus] = $texte;
396
-
397
-		// delais a l'ancienne, c'est pratiquement mort
398
-		$d = $GLOBALS['delais'] ?? null;
399
-		$GLOBALS['delais'] = $delainc;
400
-
401
-		$page = recuperer_fond(
402
-			$fond,
403
-			$contexte_inclus,
404
-			['trim' => false, 'raw' => true, 'compil' => $contexte_compil]
405
-		);
406
-
407
-		$texte = $page['texte'];
408
-
409
-		$GLOBALS['delais'] = $d;
410
-		// Faire remonter les entetes
411
-		if (
412
-			isset($page['entetes'])
413
-			and is_array($page['entetes'])
414
-		) {
415
-			// mais pas toutes
416
-			unset($page['entetes']['X-Spip-Cache']);
417
-			unset($page['entetes']['Content-Type']);
418
-			if (isset($GLOBALS['page']) and is_array($GLOBALS['page'])) {
419
-				if (!is_array($GLOBALS['page']['entetes'])) {
420
-					$GLOBALS['page']['entetes'] = [];
421
-				}
422
-				$GLOBALS['page']['entetes'] =
423
-					array_merge($GLOBALS['page']['entetes'], $page['entetes']);
424
-			}
425
-		}
426
-		// _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines
427
-		if (
428
-			isset($page['contexte']['_pipelines'])
429
-			and is_array($page['contexte']['_pipelines'])
430
-			and count($page['contexte']['_pipelines'])
431
-		) {
432
-			foreach ($page['contexte']['_pipelines'] as $pipe => $args) {
433
-				$args['contexte'] = $page['contexte'];
434
-				unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul
435
-				$texte = pipeline(
436
-					$pipe,
437
-					[
438
-						'data' => $texte,
439
-						'args' => $args
440
-					]
441
-				);
442
-			}
443
-		}
444
-	}
445
-
446
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
447
-		// compatibilite : avant on donnait le numero de ligne ou rien.
448
-		$ligne = intval($contexte_compil[3] ?? $contexte_compil);
449
-		$GLOBALS['debug_objets']['resultat'][$ligne] = $texte;
450
-	}
451
-	if ($echo) {
452
-		echo $texte;
453
-	} else {
454
-		return $texte;
455
-	}
394
+    if (is_array($texte)) {
395
+        [$fond, $delainc, $contexte_inclus] = $texte;
396
+
397
+        // delais a l'ancienne, c'est pratiquement mort
398
+        $d = $GLOBALS['delais'] ?? null;
399
+        $GLOBALS['delais'] = $delainc;
400
+
401
+        $page = recuperer_fond(
402
+            $fond,
403
+            $contexte_inclus,
404
+            ['trim' => false, 'raw' => true, 'compil' => $contexte_compil]
405
+        );
406
+
407
+        $texte = $page['texte'];
408
+
409
+        $GLOBALS['delais'] = $d;
410
+        // Faire remonter les entetes
411
+        if (
412
+            isset($page['entetes'])
413
+            and is_array($page['entetes'])
414
+        ) {
415
+            // mais pas toutes
416
+            unset($page['entetes']['X-Spip-Cache']);
417
+            unset($page['entetes']['Content-Type']);
418
+            if (isset($GLOBALS['page']) and is_array($GLOBALS['page'])) {
419
+                if (!is_array($GLOBALS['page']['entetes'])) {
420
+                    $GLOBALS['page']['entetes'] = [];
421
+                }
422
+                $GLOBALS['page']['entetes'] =
423
+                    array_merge($GLOBALS['page']['entetes'], $page['entetes']);
424
+            }
425
+        }
426
+        // _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines
427
+        if (
428
+            isset($page['contexte']['_pipelines'])
429
+            and is_array($page['contexte']['_pipelines'])
430
+            and count($page['contexte']['_pipelines'])
431
+        ) {
432
+            foreach ($page['contexte']['_pipelines'] as $pipe => $args) {
433
+                $args['contexte'] = $page['contexte'];
434
+                unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul
435
+                $texte = pipeline(
436
+                    $pipe,
437
+                    [
438
+                        'data' => $texte,
439
+                        'args' => $args
440
+                    ]
441
+                );
442
+            }
443
+        }
444
+    }
445
+
446
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
447
+        // compatibilite : avant on donnait le numero de ligne ou rien.
448
+        $ligne = intval($contexte_compil[3] ?? $contexte_compil);
449
+        $GLOBALS['debug_objets']['resultat'][$ligne] = $texte;
450
+    }
451
+    if ($echo) {
452
+        echo $texte;
453
+    } else {
454
+        return $texte;
455
+    }
456 456
 }
457 457
 
458 458
 function message_page_indisponible($page, $contexte) {
459
-	static $deja = false;
460
-	if ($deja) {
461
-		return 'erreur';
462
-	}
463
-	$codes = [
464
-		'404' => '404 Not Found',
465
-		'503' => '503 Service Unavailable',
466
-	];
467
-
468
-	$contexte['status'] = ($page !== false) ? '404' : '503';
469
-	$contexte['code'] = $codes[$contexte['status']];
470
-	$contexte['fond'] = '404'; // gere les 2 erreurs
471
-	if (!isset($contexte['lang'])) {
472
-		include_spip('inc/lang');
473
-		$contexte['lang'] = $GLOBALS['spip_lang'];
474
-	}
475
-
476
-	$deja = true;
477
-	// passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent
478
-	// ex restriction d'acces => 401
479
-	$contexte = pipeline('page_indisponible', $contexte);
480
-
481
-	// produire la page d'erreur
482
-	$page = inclure_page($contexte['fond'], $contexte);
483
-	if (!$page) {
484
-		$page = inclure_page('404', $contexte);
485
-	}
486
-	$page['status'] = $contexte['status'];
487
-
488
-	return $page;
459
+    static $deja = false;
460
+    if ($deja) {
461
+        return 'erreur';
462
+    }
463
+    $codes = [
464
+        '404' => '404 Not Found',
465
+        '503' => '503 Service Unavailable',
466
+    ];
467
+
468
+    $contexte['status'] = ($page !== false) ? '404' : '503';
469
+    $contexte['code'] = $codes[$contexte['status']];
470
+    $contexte['fond'] = '404'; // gere les 2 erreurs
471
+    if (!isset($contexte['lang'])) {
472
+        include_spip('inc/lang');
473
+        $contexte['lang'] = $GLOBALS['spip_lang'];
474
+    }
475
+
476
+    $deja = true;
477
+    // passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent
478
+    // ex restriction d'acces => 401
479
+    $contexte = pipeline('page_indisponible', $contexte);
480
+
481
+    // produire la page d'erreur
482
+    $page = inclure_page($contexte['fond'], $contexte);
483
+    if (!$page) {
484
+        $page = inclure_page('404', $contexte);
485
+    }
486
+    $page['status'] = $contexte['status'];
487
+
488
+    return $page;
489 489
 }
490 490
 
491 491
 /**
@@ -497,44 +497,44 @@  discard block
 block discarded – undo
497 497
  * @return mixed
498 498
  */
499 499
 function arguments_balise_dyn_depuis_modele($arg, $operation = 'set') {
500
-	static $balise_dyn_appellee_par_modele = null;
501
-	switch ($operation) {
502
-		case 'read':
503
-			return $balise_dyn_appellee_par_modele;
504
-		case 'reset':
505
-			$balise_dyn_appellee_par_modele = null;
506
-			return null;
507
-		case 'set':
508
-		default:
509
-			$balise_dyn_appellee_par_modele = $arg;
510
-			return $arg;
511
-	}
500
+    static $balise_dyn_appellee_par_modele = null;
501
+    switch ($operation) {
502
+        case 'read':
503
+            return $balise_dyn_appellee_par_modele;
504
+        case 'reset':
505
+            $balise_dyn_appellee_par_modele = null;
506
+            return null;
507
+        case 'set':
508
+        default:
509
+            $balise_dyn_appellee_par_modele = $arg;
510
+            return $arg;
511
+    }
512 512
 }
513 513
 
514 514
 // temporairement ici : a mettre dans le futur inc/modeles
515 515
 // creer_contexte_de_modele('left', 'autostart=true', ...) renvoie un array()
516 516
 function creer_contexte_de_modele($args) {
517
-	$contexte = [];
518
-	foreach ($args as $var => $val) {
519
-		if (is_int($var)) { // argument pas formate
520
-			if (in_array($val, ['left', 'right', 'center'])) {
521
-				$var = 'align';
522
-				$contexte[$var] = $val;
523
-			} else {
524
-				$args = explode('=', $val);
525
-				if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args
526
-				$contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1);
527
-				} else // notation abregee
528
-				{
529
-					$contexte[trim($val)] = trim($val);
530
-				}
531
-			}
532
-		} else {
533
-			$contexte[$var] = $val;
534
-		}
535
-	}
536
-
537
-	return $contexte;
517
+    $contexte = [];
518
+    foreach ($args as $var => $val) {
519
+        if (is_int($var)) { // argument pas formate
520
+            if (in_array($val, ['left', 'right', 'center'])) {
521
+                $var = 'align';
522
+                $contexte[$var] = $val;
523
+            } else {
524
+                $args = explode('=', $val);
525
+                if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args
526
+                $contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1);
527
+                } else // notation abregee
528
+                {
529
+                    $contexte[trim($val)] = trim($val);
530
+                }
531
+            }
532
+        } else {
533
+            $contexte[$var] = $val;
534
+        }
535
+    }
536
+
537
+    return $contexte;
538 538
 }
539 539
 
540 540
 /**
@@ -549,43 +549,43 @@  discard block
 block discarded – undo
549 549
  * @return string
550 550
  */
551 551
 function styliser_modele($modele, $id, $contexte = null) {
552
-	static $styliseurs = null;
553
-	if (is_null($styliseurs)) {
554
-		$tables_objet = lister_tables_objets_sql();
555
-		foreach ($tables_objet as $table => $desc) {
556
-			if (
557
-				isset($desc['modeles']) and $desc['modeles']
558
-				and isset($desc['modeles_styliser']) and $desc['modeles_styliser']
559
-				and function_exists($desc['modeles_styliser'])
560
-			) {
561
-				$primary = id_table_objet($table);
562
-				foreach ($desc['modeles'] as $m) {
563
-					$styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']];
564
-				}
565
-			}
566
-		}
567
-	}
568
-
569
-	if (isset($styliseurs[$modele])) {
570
-		$styliseur = $styliseurs[$modele]['callback'];
571
-		$primary = $styliseurs[$modele]['primary'];
572
-		if (is_null($id) and $contexte) {
573
-			if (isset($contexte['id'])) {
574
-				$id = $contexte['id'];
575
-			} elseif (isset($contexte[$primary])) {
576
-				$id = $contexte[$primary];
577
-			}
578
-		}
579
-		if (is_null($id)) {
580
-			$msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]);
581
-			erreur_squelette($msg);
582
-			// on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant
583
-			$id = 0;
584
-		}
585
-		$modele = $styliseur($modele, $id);
586
-	}
587
-
588
-	return $modele;
552
+    static $styliseurs = null;
553
+    if (is_null($styliseurs)) {
554
+        $tables_objet = lister_tables_objets_sql();
555
+        foreach ($tables_objet as $table => $desc) {
556
+            if (
557
+                isset($desc['modeles']) and $desc['modeles']
558
+                and isset($desc['modeles_styliser']) and $desc['modeles_styliser']
559
+                and function_exists($desc['modeles_styliser'])
560
+            ) {
561
+                $primary = id_table_objet($table);
562
+                foreach ($desc['modeles'] as $m) {
563
+                    $styliseurs[$m] = ['primary' => $primary, 'callback' => $desc['modeles_styliser']];
564
+                }
565
+            }
566
+        }
567
+    }
568
+
569
+    if (isset($styliseurs[$modele])) {
570
+        $styliseur = $styliseurs[$modele]['callback'];
571
+        $primary = $styliseurs[$modele]['primary'];
572
+        if (is_null($id) and $contexte) {
573
+            if (isset($contexte['id'])) {
574
+                $id = $contexte['id'];
575
+            } elseif (isset($contexte[$primary])) {
576
+                $id = $contexte[$primary];
577
+            }
578
+        }
579
+        if (is_null($id)) {
580
+            $msg = "modeles/$modele : " . _T('zbug_parametres_inclus_incorrects', ['param' => "id/$primary"]);
581
+            erreur_squelette($msg);
582
+            // on passe id=0 au routeur pour tomber sur le modele par defaut et eviter une seconde erreur sur un modele inexistant
583
+            $id = 0;
584
+        }
585
+        $modele = $styliseur($modele, $id);
586
+    }
587
+
588
+    return $modele;
589 589
 }
590 590
 
591 591
 /**
@@ -602,102 +602,102 @@  discard block
 block discarded – undo
602 602
  */
603 603
 function inclure_modele($type, $id, $params, $lien, string $connect = '', $env = []) {
604 604
 
605
-	static $compteur;
606
-	if (++$compteur > 10) {
607
-		return '';
608
-	} # ne pas boucler indefiniment
609
-
610
-	$type = strtolower($type);
611
-	$type = styliser_modele($type, $id);
612
-
613
-	$fond = $class = '';
614
-
615
-	$params = array_filter(explode('|', $params));
616
-	if ($params) {
617
-		$soustype = current($params);
618
-		$soustype = strtolower(trim($soustype));
619
-		if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) {
620
-			$soustype = next($params);
621
-			$soustype = strtolower($soustype);
622
-		}
623
-
624
-		if (preg_match(',^[a-z0-9_]+$,', $soustype)) {
625
-			if (!trouve_modele($fond = ($type . '_' . $soustype))) {
626
-				$fond = '';
627
-				$class = $soustype;
628
-			}
629
-			// enlever le sous type des params
630
-			$params = array_diff($params, [$soustype]);
631
-		}
632
-	}
633
-
634
-	// Si ca marche pas en precisant le sous-type, prendre le type
635
-	if (!$fond and !trouve_modele($fond = $type)) {
636
-		spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE);
637
-
638
-		return false;
639
-	}
640
-	$fond = 'modeles/' . $fond;
641
-	// Creer le contexte
642
-	$contexte = $env;
643
-	$contexte['dir_racine'] = _DIR_RACINE; # eviter de mixer un cache racine et un cache ecrire (meme si pour l'instant les modeles ne sont pas caches, le resultat etant different il faut que le contexte en tienne compte
644
-
645
-	// Le numero du modele est mis dans l'environnement
646
-	// d'une part sous l'identifiant "id"
647
-	// et d'autre part sous l'identifiant de la cle primaire
648
-	// par la fonction id_table_objet,
649
-	// (<article1> =>> article =>> id_article =>> id_article=1)
650
-	$_id = id_table_objet($type);
651
-	$contexte['id'] = $contexte[$_id] = $id;
652
-
653
-	if (isset($class)) {
654
-		$contexte['class'] = $class;
655
-	}
656
-
657
-	// Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url]
658
-	if ($lien) {
659
-		# un eventuel guillemet (") sera reechappe par #ENV
660
-		$contexte['lien'] = str_replace('&quot;', '"', $lien['href']);
661
-		$contexte['lien_class'] = $lien['class'];
662
-		$contexte['lien_mime'] = $lien['mime'];
663
-		$contexte['lien_title'] = $lien['title'];
664
-		$contexte['lien_hreflang'] = $lien['hreflang'];
665
-	}
666
-
667
-	// Traiter les parametres
668
-	// par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en>
669
-	$arg_list = creer_contexte_de_modele($params);
670
-	$contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args
671
-	$contexte = array_merge($contexte, $arg_list);
672
-
673
-	// Appliquer le modele avec le contexte
674
-	$retour = recuperer_fond($fond, $contexte, [], $connect);
675
-
676
-	// Regarder si le modele tient compte des liens (il *doit* alors indiquer
677
-	// spip_lien_ok dans les classes de son conteneur de premier niveau ;
678
-	// sinon, s'il y a un lien, on l'ajoute classiquement
679
-	if (
680
-		strstr(
681
-			' ' . ($classes = extraire_attribut($retour, 'class')) . ' ',
682
-			'spip_lien_ok'
683
-		)
684
-	) {
685
-		$retour = inserer_attribut(
686
-			$retour,
687
-			'class',
688
-			trim(str_replace(' spip_lien_ok ', ' ', " $classes "))
689
-		);
690
-	} else {
691
-		if ($lien) {
692
-			$retour = '<a href="' . $lien['href'] . '" class="' . $lien['class'] . '">' . $retour . '</a>';
693
-		}
694
-	}
695
-
696
-	$compteur--;
697
-
698
-	return (isset($arg_list['ajax']) and $arg_list['ajax'] == 'ajax')
699
-		? encoder_contexte_ajax($contexte, '', $retour)
700
-		: $retour;
605
+    static $compteur;
606
+    if (++$compteur > 10) {
607
+        return '';
608
+    } # ne pas boucler indefiniment
609
+
610
+    $type = strtolower($type);
611
+    $type = styliser_modele($type, $id);
612
+
613
+    $fond = $class = '';
614
+
615
+    $params = array_filter(explode('|', $params));
616
+    if ($params) {
617
+        $soustype = current($params);
618
+        $soustype = strtolower(trim($soustype));
619
+        if (in_array($soustype, ['left', 'right', 'center', 'ajax'])) {
620
+            $soustype = next($params);
621
+            $soustype = strtolower($soustype);
622
+        }
623
+
624
+        if (preg_match(',^[a-z0-9_]+$,', $soustype)) {
625
+            if (!trouve_modele($fond = ($type . '_' . $soustype))) {
626
+                $fond = '';
627
+                $class = $soustype;
628
+            }
629
+            // enlever le sous type des params
630
+            $params = array_diff($params, [$soustype]);
631
+        }
632
+    }
633
+
634
+    // Si ca marche pas en precisant le sous-type, prendre le type
635
+    if (!$fond and !trouve_modele($fond = $type)) {
636
+        spip_log("Modele $type introuvable", _LOG_INFO_IMPORTANTE);
637
+
638
+        return false;
639
+    }
640
+    $fond = 'modeles/' . $fond;
641
+    // Creer le contexte
642
+    $contexte = $env;
643
+    $contexte['dir_racine'] = _DIR_RACINE; # eviter de mixer un cache racine et un cache ecrire (meme si pour l'instant les modeles ne sont pas caches, le resultat etant different il faut que le contexte en tienne compte
644
+
645
+    // Le numero du modele est mis dans l'environnement
646
+    // d'une part sous l'identifiant "id"
647
+    // et d'autre part sous l'identifiant de la cle primaire
648
+    // par la fonction id_table_objet,
649
+    // (<article1> =>> article =>> id_article =>> id_article=1)
650
+    $_id = id_table_objet($type);
651
+    $contexte['id'] = $contexte[$_id] = $id;
652
+
653
+    if (isset($class)) {
654
+        $contexte['class'] = $class;
655
+    }
656
+
657
+    // Si un lien a ete passe en parametre, ex: [<modele1>->url] ou [<modele1|title_du_lien{hreflang}->url]
658
+    if ($lien) {
659
+        # un eventuel guillemet (") sera reechappe par #ENV
660
+        $contexte['lien'] = str_replace('&quot;', '"', $lien['href']);
661
+        $contexte['lien_class'] = $lien['class'];
662
+        $contexte['lien_mime'] = $lien['mime'];
663
+        $contexte['lien_title'] = $lien['title'];
664
+        $contexte['lien_hreflang'] = $lien['hreflang'];
665
+    }
666
+
667
+    // Traiter les parametres
668
+    // par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en>
669
+    $arg_list = creer_contexte_de_modele($params);
670
+    $contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args
671
+    $contexte = array_merge($contexte, $arg_list);
672
+
673
+    // Appliquer le modele avec le contexte
674
+    $retour = recuperer_fond($fond, $contexte, [], $connect);
675
+
676
+    // Regarder si le modele tient compte des liens (il *doit* alors indiquer
677
+    // spip_lien_ok dans les classes de son conteneur de premier niveau ;
678
+    // sinon, s'il y a un lien, on l'ajoute classiquement
679
+    if (
680
+        strstr(
681
+            ' ' . ($classes = extraire_attribut($retour, 'class')) . ' ',
682
+            'spip_lien_ok'
683
+        )
684
+    ) {
685
+        $retour = inserer_attribut(
686
+            $retour,
687
+            'class',
688
+            trim(str_replace(' spip_lien_ok ', ' ', " $classes "))
689
+        );
690
+    } else {
691
+        if ($lien) {
692
+            $retour = '<a href="' . $lien['href'] . '" class="' . $lien['class'] . '">' . $retour . '</a>';
693
+        }
694
+    }
695
+
696
+    $compteur--;
697
+
698
+    return (isset($arg_list['ajax']) and $arg_list['ajax'] == 'ajax')
699
+        ? encoder_contexte_ajax($contexte, '', $retour)
700
+        : $retour;
701 701
 }
702 702
 
703 703
 // Un inclure_page qui marche aussi pour l'espace prive
@@ -706,105 +706,105 @@  discard block
 block discarded – undo
706 706
 // 	recuperer_fond($fond,$contexte,array('raw'=>true))
707 707
 function evaluer_fond($fond, $contexte = [], string $connect = '') {
708 708
 
709
-	$page = inclure_page($fond, $contexte, $connect);
710
-
711
-	if (!$page) {
712
-		return $page;
713
-	}
714
-	// eval $page et affecte $res
715
-	include _ROOT_RESTREINT . 'public/evaluer_page.php';
716
-
717
-	// Lever un drapeau (global) si le fond utilise #SESSION
718
-	// a destination de public/parametrer
719
-	// pour remonter vers les inclusions appelantes
720
-	// il faut bien lever ce drapeau apres avoir evalue le fond
721
-	// pour ne pas faire descendre le flag vers les inclusions appelees
722
-	if (
723
-		isset($page['invalideurs'])
724
-		and isset($page['invalideurs']['session'])
725
-	) {
726
-		$GLOBALS['cache_utilise_session'] = $page['invalideurs']['session'];
727
-	}
728
-
729
-	return $page;
709
+    $page = inclure_page($fond, $contexte, $connect);
710
+
711
+    if (!$page) {
712
+        return $page;
713
+    }
714
+    // eval $page et affecte $res
715
+    include _ROOT_RESTREINT . 'public/evaluer_page.php';
716
+
717
+    // Lever un drapeau (global) si le fond utilise #SESSION
718
+    // a destination de public/parametrer
719
+    // pour remonter vers les inclusions appelantes
720
+    // il faut bien lever ce drapeau apres avoir evalue le fond
721
+    // pour ne pas faire descendre le flag vers les inclusions appelees
722
+    if (
723
+        isset($page['invalideurs'])
724
+        and isset($page['invalideurs']['session'])
725
+    ) {
726
+        $GLOBALS['cache_utilise_session'] = $page['invalideurs']['session'];
727
+    }
728
+
729
+    return $page;
730 730
 }
731 731
 
732 732
 
733 733
 function page_base_href(&$texte) {
734
-	static $set_html_base = null;
735
-	if (is_null($set_html_base)) {
736
-		if (!defined('_SET_HTML_BASE')) {
737
-			// si la profondeur est superieure a 1
738
-			// est que ce n'est pas une url page ni une url action
739
-			// activer par defaut
740
-		$set_html_base = ((
741
-				$GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2)
742
-				and _request(_SPIP_PAGE) !== 'login'
743
-				and !_request('action')) ? true : false);
744
-		} else {
745
-			$set_html_base = _SET_HTML_BASE;
746
-		}
747
-	}
748
-
749
-	if (
750
-		$set_html_base
751
-		and isset($GLOBALS['html']) and $GLOBALS['html']
752
-		and $GLOBALS['profondeur_url'] > 0
753
-		and ($poshead = strpos($texte, '</head>')) !== false
754
-	) {
755
-		$head = substr($texte, 0, $poshead);
756
-		$insert = false;
757
-		$href_base = false;
758
-		if (strpos($head, '<base') === false) {
759
-			$insert = true;
760
-		} else {
761
-			// si aucun <base ...> n'a de href il faut en inserer un
762
-			// sinon juste re-ecrire les ancres si besoin
763
-			$insert = true;
764
-			include_spip('inc/filtres');
765
-			$bases = extraire_balises($head, 'base');
766
-			foreach ($bases as $base) {
767
-				if ($href_base = extraire_attribut($base, 'href')) {
768
-					$insert = false;
769
-					break;
770
-				}
771
-			}
772
-		}
773
-
774
-		if ($insert) {
775
-			include_spip('inc/filtres_mini');
776
-			// ajouter un base qui reglera tous les liens relatifs
777
-			$href_base = url_absolue('./');
778
-			$base = "\n<base href=\"$href_base\" />";
779
-			if (($pos = strpos($head, '<head>')) !== false) {
780
-				$head = substr_replace($head, $base, $pos + 6, 0);
781
-			} elseif (preg_match(',<head[^>]*>,i', $head, $r)) {
782
-				$head = str_replace($r[0], $r[0] . $base, $head);
783
-			}
784
-			$texte = $head . substr($texte, $poshead);
785
-		}
786
-		if ($href_base) {
787
-			// gerer les ancres
788
-			$base = $_SERVER['REQUEST_URI'];
789
-			// pas de guillemets ni < dans l'URL qu'on insere dans le HTML
790
-			if (strpos($base, "'") or strpos($base, '"') or strpos($base, '<')) {
791
-				$base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base);
792
-			}
793
-			if (strpos($texte, "href='#") !== false) {
794
-				$texte = str_replace("href='#", "href='$base#", $texte);
795
-			}
796
-			if (strpos($texte, 'href="#') !== false) {
797
-				$texte = str_replace('href="#', "href=\"$base#", $texte);
798
-			}
799
-		}
800
-	}
734
+    static $set_html_base = null;
735
+    if (is_null($set_html_base)) {
736
+        if (!defined('_SET_HTML_BASE')) {
737
+            // si la profondeur est superieure a 1
738
+            // est que ce n'est pas une url page ni une url action
739
+            // activer par defaut
740
+        $set_html_base = ((
741
+                $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2)
742
+                and _request(_SPIP_PAGE) !== 'login'
743
+                and !_request('action')) ? true : false);
744
+        } else {
745
+            $set_html_base = _SET_HTML_BASE;
746
+        }
747
+    }
748
+
749
+    if (
750
+        $set_html_base
751
+        and isset($GLOBALS['html']) and $GLOBALS['html']
752
+        and $GLOBALS['profondeur_url'] > 0
753
+        and ($poshead = strpos($texte, '</head>')) !== false
754
+    ) {
755
+        $head = substr($texte, 0, $poshead);
756
+        $insert = false;
757
+        $href_base = false;
758
+        if (strpos($head, '<base') === false) {
759
+            $insert = true;
760
+        } else {
761
+            // si aucun <base ...> n'a de href il faut en inserer un
762
+            // sinon juste re-ecrire les ancres si besoin
763
+            $insert = true;
764
+            include_spip('inc/filtres');
765
+            $bases = extraire_balises($head, 'base');
766
+            foreach ($bases as $base) {
767
+                if ($href_base = extraire_attribut($base, 'href')) {
768
+                    $insert = false;
769
+                    break;
770
+                }
771
+            }
772
+        }
773
+
774
+        if ($insert) {
775
+            include_spip('inc/filtres_mini');
776
+            // ajouter un base qui reglera tous les liens relatifs
777
+            $href_base = url_absolue('./');
778
+            $base = "\n<base href=\"$href_base\" />";
779
+            if (($pos = strpos($head, '<head>')) !== false) {
780
+                $head = substr_replace($head, $base, $pos + 6, 0);
781
+            } elseif (preg_match(',<head[^>]*>,i', $head, $r)) {
782
+                $head = str_replace($r[0], $r[0] . $base, $head);
783
+            }
784
+            $texte = $head . substr($texte, $poshead);
785
+        }
786
+        if ($href_base) {
787
+            // gerer les ancres
788
+            $base = $_SERVER['REQUEST_URI'];
789
+            // pas de guillemets ni < dans l'URL qu'on insere dans le HTML
790
+            if (strpos($base, "'") or strpos($base, '"') or strpos($base, '<')) {
791
+                $base = str_replace(["'",'"','<'], ['%27','%22','%3C'], $base);
792
+            }
793
+            if (strpos($texte, "href='#") !== false) {
794
+                $texte = str_replace("href='#", "href='$base#", $texte);
795
+            }
796
+            if (strpos($texte, 'href="#') !== false) {
797
+                $texte = str_replace('href="#', "href=\"$base#", $texte);
798
+            }
799
+        }
800
+    }
801 801
 }
802 802
 
803 803
 
804 804
 // Envoyer les entetes, en retenant ceux qui sont a usage interne
805 805
 // et demarrent par X-Spip-...
806 806
 function envoyer_entetes($entetes) {
807
-	foreach ($entetes as $k => $v) { #	if (strncmp($k, 'X-Spip-', 7))
808
-	@header(strlen($v) ? "$k: $v" : $k);
809
-	}
807
+    foreach ($entetes as $k => $v) { #	if (strncmp($k, 'X-Spip-', 7))
808
+    @header(strlen($v) ? "$k: $v" : $k);
809
+    }
810 810
 }
Please login to merge, or discard this patch.
ecrire/public/decompiler.php 1 patch
Indentation   +176 added lines, -176 removed lines patch added patch discarded remove patch
@@ -12,129 +12,129 @@  discard block
 block discarded – undo
12 12
 \***************************************************************************/
13 13
 
14 14
 if (!defined('_ECRIRE_INC_VERSION')) {
15
-	return;
15
+    return;
16 16
 }
17 17
 
18 18
 // Decompilation de l'arbre de syntaxe abstraite d'un squelette SPIP
19 19
 
20 20
 function decompiler_boucle($struct, $fmt = '', $prof = 0) {
21
-	$nom = $struct->id_boucle;
22
-	$preaff = decompiler_($struct->preaff, $fmt, $prof);
23
-	$avant = decompiler_($struct->avant, $fmt, $prof);
24
-	$apres = decompiler_($struct->apres, $fmt, $prof);
25
-	$altern = decompiler_($struct->altern, $fmt, $prof);
26
-	$milieu = decompiler_($struct->milieu, $fmt, $prof);
27
-	$postaff = decompiler_($struct->postaff, $fmt, $prof);
28
-
29
-	$type = $struct->sql_serveur ? "$struct->sql_serveur:" : '';
30
-	$type .= ($struct->type_requete ?: $struct->table_optionnelle);
31
-
32
-	if ($struct->jointures_explicites) {
33
-		$type .= ' ' . $struct->jointures_explicites;
34
-	}
35
-	if ($struct->table_optionnelle) {
36
-		$type .= '?';
37
-	}
38
-	// Revoir le cas de la boucle recursive
39
-
40
-	$crit = $struct->param;
41
-	if ($crit && !is_array($crit[0])) {
42
-		$type = strtolower($type) . array_shift($crit);
43
-	}
44
-	$crit = decompiler_criteres($struct, $fmt, $prof);
45
-
46
-	$f = 'format_boucle_' . $fmt;
47
-
48
-	return $f($preaff, $avant, $nom, $type, $crit, $milieu, $apres, $altern, $postaff, $prof);
21
+    $nom = $struct->id_boucle;
22
+    $preaff = decompiler_($struct->preaff, $fmt, $prof);
23
+    $avant = decompiler_($struct->avant, $fmt, $prof);
24
+    $apres = decompiler_($struct->apres, $fmt, $prof);
25
+    $altern = decompiler_($struct->altern, $fmt, $prof);
26
+    $milieu = decompiler_($struct->milieu, $fmt, $prof);
27
+    $postaff = decompiler_($struct->postaff, $fmt, $prof);
28
+
29
+    $type = $struct->sql_serveur ? "$struct->sql_serveur:" : '';
30
+    $type .= ($struct->type_requete ?: $struct->table_optionnelle);
31
+
32
+    if ($struct->jointures_explicites) {
33
+        $type .= ' ' . $struct->jointures_explicites;
34
+    }
35
+    if ($struct->table_optionnelle) {
36
+        $type .= '?';
37
+    }
38
+    // Revoir le cas de la boucle recursive
39
+
40
+    $crit = $struct->param;
41
+    if ($crit && !is_array($crit[0])) {
42
+        $type = strtolower($type) . array_shift($crit);
43
+    }
44
+    $crit = decompiler_criteres($struct, $fmt, $prof);
45
+
46
+    $f = 'format_boucle_' . $fmt;
47
+
48
+    return $f($preaff, $avant, $nom, $type, $crit, $milieu, $apres, $altern, $postaff, $prof);
49 49
 }
50 50
 
51 51
 function decompiler_include($struct, $fmt = '', $prof = 0) {
52
-	$res = [];
53
-	foreach ($struct->param ?: [] as $couple) {
54
-		array_shift($couple);
55
-		foreach ($couple as $v) {
56
-			$res[] = decompiler_($v, $fmt, $prof);
57
-		}
58
-	}
59
-	$file = is_string($struct->texte) ? $struct->texte :
60
-		decompiler_($struct->texte, $fmt, $prof);
61
-	$f = 'format_inclure_' . $fmt;
62
-
63
-	return $f($file, $res, $prof);
52
+    $res = [];
53
+    foreach ($struct->param ?: [] as $couple) {
54
+        array_shift($couple);
55
+        foreach ($couple as $v) {
56
+            $res[] = decompiler_($v, $fmt, $prof);
57
+        }
58
+    }
59
+    $file = is_string($struct->texte) ? $struct->texte :
60
+        decompiler_($struct->texte, $fmt, $prof);
61
+    $f = 'format_inclure_' . $fmt;
62
+
63
+    return $f($file, $res, $prof);
64 64
 }
65 65
 
66 66
 function decompiler_texte($struct, $fmt = '', $prof = 0) {
67
-	$f = 'format_texte_' . $fmt;
67
+    $f = 'format_texte_' . $fmt;
68 68
 
69
-	return strlen($struct->texte) ? $f($struct->texte, $prof) : '';
69
+    return strlen($struct->texte) ? $f($struct->texte, $prof) : '';
70 70
 }
71 71
 
72 72
 function decompiler_polyglotte($struct, $fmt = '', $prof = 0) {
73
-	$f = 'format_polyglotte_' . $fmt;
73
+    $f = 'format_polyglotte_' . $fmt;
74 74
 
75
-	return $f($struct->traductions, $prof);
75
+    return $f($struct->traductions, $prof);
76 76
 }
77 77
 
78 78
 function decompiler_idiome($struct, $fmt = '', $prof = 0) {
79
-	$args = [];
80
-	foreach ($struct->arg as $k => $v) {
81
-		$args[$k] = public_decompiler($v, $fmt, $prof);
82
-	}
79
+    $args = [];
80
+    foreach ($struct->arg as $k => $v) {
81
+        $args[$k] = public_decompiler($v, $fmt, $prof);
82
+    }
83 83
 
84
-	$filtres = decompiler_liste($struct->param, $fmt, $prof);
84
+    $filtres = decompiler_liste($struct->param, $fmt, $prof);
85 85
 
86
-	$f = 'format_idiome_' . $fmt;
86
+    $f = 'format_idiome_' . $fmt;
87 87
 
88
-	return $f($struct->nom_champ, $struct->module, $args, $filtres, $prof);
88
+    return $f($struct->nom_champ, $struct->module, $args, $filtres, $prof);
89 89
 }
90 90
 
91 91
 function decompiler_champ($struct, $fmt = '', $prof = 0) {
92
-	$avant = decompiler_($struct->avant, $fmt, $prof);
93
-	$apres = decompiler_($struct->apres, $fmt, $prof);
94
-	$args = $filtres = '';
95
-	if ($p = $struct->param) {
96
-		if ($p[0][0] === '') {
97
-			$args = decompiler_liste([array_shift($p)], $fmt, $prof);
98
-		}
99
-		$filtres = decompiler_liste($p, $fmt, $prof);
100
-	}
101
-	$f = 'format_champ_' . $fmt;
102
-
103
-	return $f($struct->nom_champ, $struct->nom_boucle, $struct->etoile, $avant, $apres, $args, $filtres, $prof);
92
+    $avant = decompiler_($struct->avant, $fmt, $prof);
93
+    $apres = decompiler_($struct->apres, $fmt, $prof);
94
+    $args = $filtres = '';
95
+    if ($p = $struct->param) {
96
+        if ($p[0][0] === '') {
97
+            $args = decompiler_liste([array_shift($p)], $fmt, $prof);
98
+        }
99
+        $filtres = decompiler_liste($p, $fmt, $prof);
100
+    }
101
+    $f = 'format_champ_' . $fmt;
102
+
103
+    return $f($struct->nom_champ, $struct->nom_boucle, $struct->etoile, $avant, $apres, $args, $filtres, $prof);
104 104
 }
105 105
 
106 106
 function decompiler_liste($sources, $fmt = '', $prof = 0) {
107
-	if (!is_array($sources)) {
108
-		return '';
109
-	}
110
-	$f = 'format_liste_' . $fmt;
111
-	$res = '';
112
-	foreach ($sources as $arg) {
113
-		if (!is_array($arg)) {
114
-			continue; // ne devrait pas arriver.
115
-		} else {
116
-			$r = array_shift($arg);
117
-		}
118
-		$args = [];
119
-		foreach ($arg as $v) {
120
-			// cas des arguments entoures de ' ou "
121
-			if (
122
-				(is_countable($v) ? count($v) : 0) == 1
123
-				&& $v[0]->type == 'texte'
124
-				&& strlen($v[0]->apres) == 1
125
-				&& $v[0]->apres == $v[0]->avant
126
-			) {
127
-				$args[] = $v[0]->avant . $v[0]->texte . $v[0]->apres;
128
-			} else {
129
-				$args[] = decompiler_($v, $fmt, 0 - $prof);
130
-			}
131
-		}
132
-		if ($r !== '' || $args) {
133
-			$res .= $f($r, $args, $prof);
134
-		}
135
-	}
136
-
137
-	return $res;
107
+    if (!is_array($sources)) {
108
+        return '';
109
+    }
110
+    $f = 'format_liste_' . $fmt;
111
+    $res = '';
112
+    foreach ($sources as $arg) {
113
+        if (!is_array($arg)) {
114
+            continue; // ne devrait pas arriver.
115
+        } else {
116
+            $r = array_shift($arg);
117
+        }
118
+        $args = [];
119
+        foreach ($arg as $v) {
120
+            // cas des arguments entoures de ' ou "
121
+            if (
122
+                (is_countable($v) ? count($v) : 0) == 1
123
+                && $v[0]->type == 'texte'
124
+                && strlen($v[0]->apres) == 1
125
+                && $v[0]->apres == $v[0]->avant
126
+            ) {
127
+                $args[] = $v[0]->avant . $v[0]->texte . $v[0]->apres;
128
+            } else {
129
+                $args[] = decompiler_($v, $fmt, 0 - $prof);
130
+            }
131
+        }
132
+        if ($r !== '' || $args) {
133
+            $res .= $f($r, $args, $prof);
134
+        }
135
+    }
136
+
137
+    return $res;
138 138
 }
139 139
 
140 140
 // Decompilation des criteres: on triche et on deroge:
@@ -142,93 +142,93 @@  discard block
 block discarded – undo
142 142
 // - le champ apres signale le critere {"separateur"} ou {'separateur'}
143 143
 // - les champs sont implicitement etendus (crochets implicites mais interdits)
144 144
 function decompiler_criteres($boucle, $fmt = '', $prof = 0) {
145
-	$sources = $boucle->param;
146
-	if (!is_array($sources)) {
147
-		return '';
148
-	}
149
-	$res = '';
150
-	$f = 'format_critere_' . $fmt;
151
-	foreach ($sources as $crit) {
152
-		if (!is_array($crit)) {
153
-			continue;
154
-		} // boucle recursive
155
-		array_shift($crit);
156
-		$args = [];
157
-		foreach ($crit as $i => $v) {
158
-			if (
159
-				(is_countable($v) ? count($v) : 0) == 1
160
-				&& $v[0]->type == 'texte'
161
-				&& $v[0]->apres
162
-			) {
163
-				$args[] = [['texte', ($v[0]->apres . $v[0]->texte . $v[0]->apres)]];
164
-			} else {
165
-				$res2 = [];
166
-				foreach ($v as $k => $p) {
167
-					if (
168
-						isset($p->type)
169
-						&& function_exists($d = 'decompiler_' . $p->type)
170
-					) {
171
-						$r = $d($p, $fmt, (0 - $prof));
172
-						$res2[] = [$p->type, $r];
173
-					} else {
174
-						spip_log("critere $i / $k mal forme");
175
-					}
176
-				}
177
-				$args[] = $res2;
178
-			}
179
-		}
180
-		$res .= $f($args);
181
-	}
182
-
183
-	return $res;
145
+    $sources = $boucle->param;
146
+    if (!is_array($sources)) {
147
+        return '';
148
+    }
149
+    $res = '';
150
+    $f = 'format_critere_' . $fmt;
151
+    foreach ($sources as $crit) {
152
+        if (!is_array($crit)) {
153
+            continue;
154
+        } // boucle recursive
155
+        array_shift($crit);
156
+        $args = [];
157
+        foreach ($crit as $i => $v) {
158
+            if (
159
+                (is_countable($v) ? count($v) : 0) == 1
160
+                && $v[0]->type == 'texte'
161
+                && $v[0]->apres
162
+            ) {
163
+                $args[] = [['texte', ($v[0]->apres . $v[0]->texte . $v[0]->apres)]];
164
+            } else {
165
+                $res2 = [];
166
+                foreach ($v as $k => $p) {
167
+                    if (
168
+                        isset($p->type)
169
+                        && function_exists($d = 'decompiler_' . $p->type)
170
+                    ) {
171
+                        $r = $d($p, $fmt, (0 - $prof));
172
+                        $res2[] = [$p->type, $r];
173
+                    } else {
174
+                        spip_log("critere $i / $k mal forme");
175
+                    }
176
+                }
177
+                $args[] = $res2;
178
+            }
179
+        }
180
+        $res .= $f($args);
181
+    }
182
+
183
+    return $res;
184 184
 }
185 185
 
186 186
 
187 187
 function decompiler_($liste, $fmt = '', $prof = 0) {
188
-	if (!is_array($liste)) {
189
-		return '';
190
-	}
191
-	$prof2 = ($prof < 0) ? ($prof - 1) : ($prof + 1);
192
-	$contenu = [];
193
-	foreach ($liste as $k => $p) {
194
-		if (!isset($p->type)) {
195
-			continue;
196
-		} #??????
197
-		$d = 'decompiler_' . $p->type;
198
-		$next = $liste[$k + 1] ?? false;
199
-		// Forcer le champ etendu si son source (pas les reecritures)
200
-		// contenait des args et s'il est suivi d'espaces,
201
-		// le champ simple les eliminant est un bug helas perenne.
202
-
203
-		if (
204
-			$next
205
-			&& $next->type == 'texte'
206
-			&& $p->type == 'champ'
207
-			&& !$p->apres
208
-			&& !$p->avant
209
-			&& $p->fonctions
210
-		) {
211
-			$n = strlen($next->texte) - strlen(ltrim($next->texte));
212
-			if ($n) {
213
-				$champ = new Texte();
214
-				$champ->texte = substr($next->texte, 0, $n);
215
-				$champ->ligne = $p->ligne;
216
-				$p->apres = [$champ];
217
-				$next->texte = substr($next->texte, $n);
218
-			}
219
-		}
220
-		$contenu[] = [$d($p, $fmt, $prof2), $p->type];
221
-	}
222
-	$f = 'format_suite_' . $fmt;
223
-
224
-	return $f($contenu);
188
+    if (!is_array($liste)) {
189
+        return '';
190
+    }
191
+    $prof2 = ($prof < 0) ? ($prof - 1) : ($prof + 1);
192
+    $contenu = [];
193
+    foreach ($liste as $k => $p) {
194
+        if (!isset($p->type)) {
195
+            continue;
196
+        } #??????
197
+        $d = 'decompiler_' . $p->type;
198
+        $next = $liste[$k + 1] ?? false;
199
+        // Forcer le champ etendu si son source (pas les reecritures)
200
+        // contenait des args et s'il est suivi d'espaces,
201
+        // le champ simple les eliminant est un bug helas perenne.
202
+
203
+        if (
204
+            $next
205
+            && $next->type == 'texte'
206
+            && $p->type == 'champ'
207
+            && !$p->apres
208
+            && !$p->avant
209
+            && $p->fonctions
210
+        ) {
211
+            $n = strlen($next->texte) - strlen(ltrim($next->texte));
212
+            if ($n) {
213
+                $champ = new Texte();
214
+                $champ->texte = substr($next->texte, 0, $n);
215
+                $champ->ligne = $p->ligne;
216
+                $p->apres = [$champ];
217
+                $next->texte = substr($next->texte, $n);
218
+            }
219
+        }
220
+        $contenu[] = [$d($p, $fmt, $prof2), $p->type];
221
+    }
222
+    $f = 'format_suite_' . $fmt;
223
+
224
+    return $f($contenu);
225 225
 }
226 226
 
227 227
 function public_decompiler($liste, $fmt = '', $prof = 0, $quoi = '') {
228
-	if (!include_spip('public/format_' . $fmt)) {
229
-		return "'$fmt'?";
230
-	}
231
-	$f = 'decompiler_' . $quoi;
228
+    if (!include_spip('public/format_' . $fmt)) {
229
+        return "'$fmt'?";
230
+    }
231
+    $f = 'decompiler_' . $quoi;
232 232
 
233
-	return $f($liste, $fmt, $prof);
233
+    return $f($liste, $fmt, $prof);
234 234
 }
Please login to merge, or discard this patch.
ecrire/public/criteres.php 1 patch
Indentation   +1696 added lines, -1696 removed lines patch added patch discarded remove patch
@@ -20,7 +20,7 @@  discard block
 block discarded – undo
20 20
  **/
21 21
 
22 22
 if (!defined('_ECRIRE_INC_VERSION')) {
23
-	return;
23
+    return;
24 24
 }
25 25
 
26 26
 /**
@@ -46,12 +46,12 @@  discard block
 block discarded – undo
46 46
  **/
47 47
 function critere_racine_dist($idb, &$boucles, $crit) {
48 48
 
49
-	$not = $crit->not;
50
-	$boucle = &$boucles[$idb];
51
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
49
+    $not = $crit->not;
50
+    $boucle = &$boucles[$idb];
51
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
52 52
 
53
-	$c = ["'='", "'$boucle->id_table." . "$id_parent'", 0];
54
-	$boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
53
+    $c = ["'='", "'$boucle->id_table." . "$id_parent'", 0];
54
+    $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
55 55
 }
56 56
 
57 57
 
@@ -68,15 +68,15 @@  discard block
 block discarded – undo
68 68
  * @return void|array
69 69
  **/
70 70
 function critere_exclus_dist($idb, &$boucles, $crit) {
71
-	$not = $crit->not;
72
-	$boucle = &$boucles[$idb];
73
-	$id = $boucle->primary;
74
-
75
-	if ($not || !$id) {
76
-		return ['zbug_critere_inconnu', ['critere' => $not . $crit->op]];
77
-	}
78
-	$arg = kwote(calculer_argument_precedent($idb, $id, $boucles));
79
-	$boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg];
71
+    $not = $crit->not;
72
+    $boucle = &$boucles[$idb];
73
+    $id = $boucle->primary;
74
+
75
+    if ($not || !$id) {
76
+        return ['zbug_critere_inconnu', ['critere' => $not . $crit->op]];
77
+    }
78
+    $arg = kwote(calculer_argument_precedent($idb, $id, $boucles));
79
+    $boucle->where[] = ["'!='", "'$boucle->id_table." . "$id'", $arg];
80 80
 }
81 81
 
82 82
 
@@ -96,73 +96,73 @@  discard block
 block discarded – undo
96 96
  * @return void|array
97 97
  **/
98 98
 function critere_doublons_dist($idb, &$boucles, $crit) {
99
-	$boucle = &$boucles[$idb];
100
-	$primary = $boucle->primary;
101
-
102
-	// la table nécessite une clé primaire, non composée
103
-	if (!$primary || strpos($primary, ',')) {
104
-		return ['zbug_doublon_sur_table_sans_cle_primaire'];
105
-	}
106
-
107
-	$not = ($crit->not ? '' : 'NOT');
108
-
109
-	// le doublon s'applique sur un type de boucle (article)
110
-	$nom = "'" . $boucle->type_requete . "'";
111
-
112
-	// compléter le nom avec un nom précisé {doublons nom}
113
-	// on obtient $nom = "'article' . 'nom'"
114
-	if (isset($crit->param[0])) {
115
-		$nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
116
-	}
117
-
118
-	// code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP)
119
-	$init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n";
120
-	$init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n";
121
-
122
-	// on crée un sql_in avec la clé primaire de la table
123
-	// et la collection des doublons déjà emmagasinés dans le tableau
124
-	// $doublons et son index, ici $nom
125
-
126
-	// debut du code "sql_in('articles.id_article', "
127
-	$debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', ";
128
-	// lecture des données du doublon "$doublons[$doublon_index[] = "
129
-	// Attention : boucle->doublons désigne une variable qu'on affecte
130
-	$debut_doub = '$doublons[' . ($not ? $boucle->doublons . '[]= ' : (''));
131
-
132
-	// le debut complet du code des doublons
133
-	$debut_doub = $debut_in . $debut_doub;
134
-
135
-	// nom du doublon "('article' . 'nom')]"
136
-	$fin_doub = "($nom)]";
137
-
138
-	// si on trouve un autre critère doublon,
139
-	// on fusionne pour avoir un seul IN, et on s'en va !
140
-	foreach ($boucle->where as $k => $w) {
141
-		if (str_starts_with($w[0], $debut_doub)) {
142
-			// fusionner le sql_in (du where)
143
-			$boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr($w[0], strlen($debut_in));
144
-			// fusionner l'initialisation (du hash) pour faire plus joli
145
-			$x = strpos($boucle->hash, $init_comment);
146
-			$len = strlen($init_comment);
147
-			$boucle->hash =
148
-				substr($boucle->hash, 0, $x + $len) . $init_code . substr($boucle->hash, $x + $len);
149
-
150
-			return;
151
-		}
152
-	}
153
-
154
-	// mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante
155
-	$boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"];
156
-
157
-	// déclarer le doublon s'il n'existe pas encore
158
-	$boucle->hash .= $init_comment . $init_code;
159
-
160
-
161
-	# la ligne suivante avait l'intention d'eviter une collecte deja faite
162
-	# mais elle fait planter une boucle a 2 critere doublons:
163
-	# {!doublons A}{doublons B}
164
-	# (de http://article.gmane.org/gmane.comp.web.spip.devel/31034)
165
-	#	if ($crit->not) $boucle->doublons = "";
99
+    $boucle = &$boucles[$idb];
100
+    $primary = $boucle->primary;
101
+
102
+    // la table nécessite une clé primaire, non composée
103
+    if (!$primary || strpos($primary, ',')) {
104
+        return ['zbug_doublon_sur_table_sans_cle_primaire'];
105
+    }
106
+
107
+    $not = ($crit->not ? '' : 'NOT');
108
+
109
+    // le doublon s'applique sur un type de boucle (article)
110
+    $nom = "'" . $boucle->type_requete . "'";
111
+
112
+    // compléter le nom avec un nom précisé {doublons nom}
113
+    // on obtient $nom = "'article' . 'nom'"
114
+    if (isset($crit->param[0])) {
115
+        $nom .= '.' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
116
+    }
117
+
118
+    // code qui déclarera l'index du stockage de nos doublons (pour éviter une notice PHP)
119
+    $init_comment = "\n\n\t// Initialise le(s) critère(s) doublons\n";
120
+    $init_code = "\tif (!isset(\$doublons[\$d = $nom])) { \$doublons[\$d] = ''; }\n";
121
+
122
+    // on crée un sql_in avec la clé primaire de la table
123
+    // et la collection des doublons déjà emmagasinés dans le tableau
124
+    // $doublons et son index, ici $nom
125
+
126
+    // debut du code "sql_in('articles.id_article', "
127
+    $debut_in = "sql_in('" . $boucle->id_table . '.' . $primary . "', ";
128
+    // lecture des données du doublon "$doublons[$doublon_index[] = "
129
+    // Attention : boucle->doublons désigne une variable qu'on affecte
130
+    $debut_doub = '$doublons[' . ($not ? $boucle->doublons . '[]= ' : (''));
131
+
132
+    // le debut complet du code des doublons
133
+    $debut_doub = $debut_in . $debut_doub;
134
+
135
+    // nom du doublon "('article' . 'nom')]"
136
+    $fin_doub = "($nom)]";
137
+
138
+    // si on trouve un autre critère doublon,
139
+    // on fusionne pour avoir un seul IN, et on s'en va !
140
+    foreach ($boucle->where as $k => $w) {
141
+        if (str_starts_with($w[0], $debut_doub)) {
142
+            // fusionner le sql_in (du where)
143
+            $boucle->where[$k][0] = $debut_doub . $fin_doub . ' . ' . substr($w[0], strlen($debut_in));
144
+            // fusionner l'initialisation (du hash) pour faire plus joli
145
+            $x = strpos($boucle->hash, $init_comment);
146
+            $len = strlen($init_comment);
147
+            $boucle->hash =
148
+                substr($boucle->hash, 0, $x + $len) . $init_code . substr($boucle->hash, $x + $len);
149
+
150
+            return;
151
+        }
152
+    }
153
+
154
+    // mettre l'ensemble dans un tableau pour que ce ne soit pas vu comme une constante
155
+    $boucle->where[] = [$debut_doub . $fin_doub . ", '" . $not . "')"];
156
+
157
+    // déclarer le doublon s'il n'existe pas encore
158
+    $boucle->hash .= $init_comment . $init_code;
159
+
160
+
161
+    # la ligne suivante avait l'intention d'eviter une collecte deja faite
162
+    # mais elle fait planter une boucle a 2 critere doublons:
163
+    # {!doublons A}{doublons B}
164
+    # (de http://article.gmane.org/gmane.comp.web.spip.devel/31034)
165
+    #	if ($crit->not) $boucle->doublons = "";
166 166
 }
167 167
 
168 168
 
@@ -183,14 +183,14 @@  discard block
 block discarded – undo
183 183
  * @return void
184 184
  **/
185 185
 function critere_lang_select_dist($idb, &$boucles, $crit) {
186
-	if (!isset($crit->param[1][0]) || !($param = $crit->param[1][0]->texte)) {
187
-		$param = 'oui';
188
-	}
189
-	if ($crit->not) {
190
-		$param = ($param == 'oui') ? 'non' : 'oui';
191
-	}
192
-	$boucle = &$boucles[$idb];
193
-	$boucle->lang_select = $param;
186
+    if (!isset($crit->param[1][0]) || !($param = $crit->param[1][0]->texte)) {
187
+        $param = 'oui';
188
+    }
189
+    if ($crit->not) {
190
+        $param = ($param == 'oui') ? 'non' : 'oui';
191
+    }
192
+    $boucle = &$boucles[$idb];
193
+    $boucle->lang_select = $param;
194 194
 }
195 195
 
196 196
 
@@ -212,15 +212,15 @@  discard block
 block discarded – undo
212 212
  * @return void
213 213
  **/
214 214
 function critere_debut_dist($idb, &$boucles, $crit) {
215
-	[$un, $deux] = $crit->param;
216
-	$un = $un[0]->texte;
217
-	$deux = $deux[0]->texte;
218
-	if ($deux) {
219
-		$boucles[$idb]->limit =
220
-			'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"';
221
-	} else {
222
-		calculer_critere_DEFAUT_dist($idb, $boucles, $crit);
223
-	}
215
+    [$un, $deux] = $crit->param;
216
+    $un = $un[0]->texte;
217
+    $deux = $deux[0]->texte;
218
+    if ($deux) {
219
+        $boucles[$idb]->limit =
220
+            'intval($Pile[0]["debut' . $un . '"]) . ",' . $deux . '"';
221
+    } else {
222
+        calculer_critere_DEFAUT_dist($idb, $boucles, $crit);
223
+    }
224 224
 }
225 225
 
226 226
 
@@ -254,59 +254,59 @@  discard block
 block discarded – undo
254 254
  **/
255 255
 function critere_pagination_dist($idb, &$boucles, $crit) {
256 256
 
257
-	$boucle = &$boucles[$idb];
258
-	// definition de la taille de la page
259
-	$pas = isset($crit->param[0][0])
260
-		? calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent)
261
-		: "''";
262
-
263
-	if (!preg_match(_CODE_QUOTE, $pas, $r)) {
264
-		$pas = "((\$a = intval($pas)) ? \$a : 10)";
265
-	} else {
266
-		$r = (int) $r[2];
267
-		$pas = (string) ($r ?: 10);
268
-	}
269
-
270
-	// Calcul du nommage de la pagination si il existe.
271
-	// La nouvelle syntaxe {pagination 20, nom} est prise en compte et privilégiée mais on reste
272
-	// compatible avec l'ancienne car certains cas fonctionnent correctement
273
-	$type = "'$idb'";
274
-	// Calcul d'un nommage spécifique de la pagination si précisé.
275
-	// Syntaxe {pagination 20, nom}
276
-	if (isset($crit->param[0][1])) {
277
-		$type = calculer_liste([$crit->param[0][1]], $idb, $boucles, $boucle->id_parent);
278
-	} // Ancienne syntaxe {pagination 20 nom} pour compatibilité
279
-	elseif (isset($crit->param[1][0])) {
280
-		$type = calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
281
-	}
282
-
283
-	$debut = ($type[0] !== "'") ? "'debut'.$type" : ("'debut" . substr($type, 1));
284
-	$boucle->modificateur['debut_nom'] = $type;
285
-	$partie =
286
-		// tester si le numero de page demande est de la forme '@yyy'
287
-		'isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : _request(' . $debut . ");\n"
288
-		. "\tif (\$debut_boucle && \$debut_boucle[0] === '@') {\n"
289
-		. "\t\t" . '$debut_boucle = $Pile[0][' . $debut . '] = quete_debut_pagination(\'' . $boucle->primary . '\',$Pile[0][\'@' . $boucle->primary . '\'] = substr($debut_boucle,1),' . $pas . ',$iter);' . "\n"
290
-		. "\t\t" . '$iter->seek(0);' . "\n"
291
-		. "\t}\n"
292
-		. "\t" . '$debut_boucle = intval($debut_boucle)';
293
-
294
-	$boucle->hash .= '
257
+    $boucle = &$boucles[$idb];
258
+    // definition de la taille de la page
259
+    $pas = isset($crit->param[0][0])
260
+        ? calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent)
261
+        : "''";
262
+
263
+    if (!preg_match(_CODE_QUOTE, $pas, $r)) {
264
+        $pas = "((\$a = intval($pas)) ? \$a : 10)";
265
+    } else {
266
+        $r = (int) $r[2];
267
+        $pas = (string) ($r ?: 10);
268
+    }
269
+
270
+    // Calcul du nommage de la pagination si il existe.
271
+    // La nouvelle syntaxe {pagination 20, nom} est prise en compte et privilégiée mais on reste
272
+    // compatible avec l'ancienne car certains cas fonctionnent correctement
273
+    $type = "'$idb'";
274
+    // Calcul d'un nommage spécifique de la pagination si précisé.
275
+    // Syntaxe {pagination 20, nom}
276
+    if (isset($crit->param[0][1])) {
277
+        $type = calculer_liste([$crit->param[0][1]], $idb, $boucles, $boucle->id_parent);
278
+    } // Ancienne syntaxe {pagination 20 nom} pour compatibilité
279
+    elseif (isset($crit->param[1][0])) {
280
+        $type = calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent);
281
+    }
282
+
283
+    $debut = ($type[0] !== "'") ? "'debut'.$type" : ("'debut" . substr($type, 1));
284
+    $boucle->modificateur['debut_nom'] = $type;
285
+    $partie =
286
+        // tester si le numero de page demande est de la forme '@yyy'
287
+        'isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : _request(' . $debut . ");\n"
288
+        . "\tif (\$debut_boucle && \$debut_boucle[0] === '@') {\n"
289
+        . "\t\t" . '$debut_boucle = $Pile[0][' . $debut . '] = quete_debut_pagination(\'' . $boucle->primary . '\',$Pile[0][\'@' . $boucle->primary . '\'] = substr($debut_boucle,1),' . $pas . ',$iter);' . "\n"
290
+        . "\t\t" . '$iter->seek(0);' . "\n"
291
+        . "\t}\n"
292
+        . "\t" . '$debut_boucle = intval($debut_boucle)';
293
+
294
+    $boucle->hash .= '
295 295
 	$command[\'pagination\'] = array((isset($Pile[0][' . $debut . ']) ? $Pile[0][' . $debut . '] : null), ' . $pas . ');';
296 296
 
297
-	$boucle->total_parties = $pas;
298
-	calculer_parties($boucles, $idb, $partie, 'p+');
299
-	// ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id
300
-	// sauf si pas de primaire, ou si primaire composee
301
-	// dans ce cas, on ne sait pas gerer une pagination indirecte
302
-	$t = $boucle->id_table . '.' . $boucle->primary;
303
-	if (
304
-		$boucle->primary
305
-		&& !preg_match('/[,\s]/', $boucle->primary)
306
-		&& !in_array($t, $boucle->select)
307
-	) {
308
-		$boucle->select[] = $t;
309
-	}
297
+    $boucle->total_parties = $pas;
298
+    calculer_parties($boucles, $idb, $partie, 'p+');
299
+    // ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id
300
+    // sauf si pas de primaire, ou si primaire composee
301
+    // dans ce cas, on ne sait pas gerer une pagination indirecte
302
+    $t = $boucle->id_table . '.' . $boucle->primary;
303
+    if (
304
+        $boucle->primary
305
+        && !preg_match('/[,\s]/', $boucle->primary)
306
+        && !in_array($t, $boucle->select)
307
+    ) {
308
+        $boucle->select[] = $t;
309
+    }
310 310
 }
311 311
 
312 312
 
@@ -328,24 +328,24 @@  discard block
 block discarded – undo
328 328
  **/
329 329
 function critere_recherche_dist($idb, &$boucles, $crit) {
330 330
 
331
-	$boucle = &$boucles[$idb];
331
+    $boucle = &$boucles[$idb];
332 332
 
333
-	if (!$boucle->primary || strpos($boucle->primary, ',')) {
334
-		erreur_squelette(_T('zbug_critere_sur_table_sans_cle_primaire', ['critere' => 'recherche']), $boucle);
333
+    if (!$boucle->primary || strpos($boucle->primary, ',')) {
334
+        erreur_squelette(_T('zbug_critere_sur_table_sans_cle_primaire', ['critere' => 'recherche']), $boucle);
335 335
 
336
-		return;
337
-	}
336
+        return;
337
+    }
338 338
 
339
-	if (isset($crit->param[0])) {
340
-		$quoi = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
341
-	} else {
342
-		$quoi = '(isset($Pile[0]["recherche"])?$Pile[0]["recherche"]:(isset($GLOBALS["recherche"])?$GLOBALS["recherche"]:""))';
343
-	}
339
+    if (isset($crit->param[0])) {
340
+        $quoi = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
341
+    } else {
342
+        $quoi = '(isset($Pile[0]["recherche"])?$Pile[0]["recherche"]:(isset($GLOBALS["recherche"])?$GLOBALS["recherche"]:""))';
343
+    }
344 344
 
345
-	$_modificateur = var_export($boucle->modificateur, true);
346
-	$boucle->hash .= '
345
+    $_modificateur = var_export($boucle->modificateur, true);
346
+    $boucle->hash .= '
347 347
 	// RECHERCHE'
348
-		. ($crit->cond ? '
348
+        . ($crit->cond ? '
349 349
 	if (!strlen(' . $quoi . ')){
350 350
 		list($rech_select, $rech_where) = array("0 as points","");
351 351
 	} else' : '') . '
@@ -356,21 +356,21 @@  discard block
 block discarded – undo
356 356
 	';
357 357
 
358 358
 
359
-	$t = $boucle->id_table . '.' . $boucle->primary;
360
-	if (!in_array($t, $boucles[$idb]->select)) {
361
-		$boucle->select[] = $t;
362
-	} # pour postgres, neuneu ici
363
-	// jointure uniquement sur le serveur principal
364
-	// (on ne peut joindre une table d'un serveur distant avec la table des resultats du serveur principal)
365
-	if (!$boucle->sql_serveur) {
366
-		$boucle->join['resultats'] = ["'" . $boucle->id_table . "'", "'id'", "'" . $boucle->primary . "'"];
367
-		$boucle->from['resultats'] = 'spip_resultats';
368
-	}
369
-	$boucle->select[] = '$rech_select';
370
-	//$boucle->where[]= "\$rech_where?'resultats.id=".$boucle->id_table.".".$boucle->primary."':''";
371
-
372
-	// et la recherche trouve
373
-	$boucle->where[] = '$rech_where?$rech_where:\'\'';
359
+    $t = $boucle->id_table . '.' . $boucle->primary;
360
+    if (!in_array($t, $boucles[$idb]->select)) {
361
+        $boucle->select[] = $t;
362
+    } # pour postgres, neuneu ici
363
+    // jointure uniquement sur le serveur principal
364
+    // (on ne peut joindre une table d'un serveur distant avec la table des resultats du serveur principal)
365
+    if (!$boucle->sql_serveur) {
366
+        $boucle->join['resultats'] = ["'" . $boucle->id_table . "'", "'id'", "'" . $boucle->primary . "'"];
367
+        $boucle->from['resultats'] = 'spip_resultats';
368
+    }
369
+    $boucle->select[] = '$rech_select';
370
+    //$boucle->where[]= "\$rech_where?'resultats.id=".$boucle->id_table.".".$boucle->primary."':''";
371
+
372
+    // et la recherche trouve
373
+    $boucle->where[] = '$rech_where?$rech_where:\'\'';
374 374
 }
375 375
 
376 376
 /**
@@ -387,25 +387,25 @@  discard block
 block discarded – undo
387 387
  * @return void
388 388
  **/
389 389
 function critere_traduction_dist($idb, &$boucles, $crit) {
390
-	$boucle = &$boucles[$idb];
391
-	$prim = $boucle->primary;
392
-	$table = $boucle->id_table;
393
-	$arg = kwote(calculer_argument_precedent($idb, 'id_trad', $boucles));
394
-	$dprim = kwote(calculer_argument_precedent($idb, $prim, $boucles));
395
-	$boucle->where[] =
396
-		[
397
-			"'OR'",
398
-			[
399
-				"'AND'",
400
-				["'='", "'$table.id_trad'", 0],
401
-				["'='", "'$table.$prim'", $dprim]
402
-			],
403
-			[
404
-				"'AND'",
405
-				["'>'", "'$table.id_trad'", 0],
406
-				["'='", "'$table.id_trad'", $arg]
407
-			]
408
-		];
390
+    $boucle = &$boucles[$idb];
391
+    $prim = $boucle->primary;
392
+    $table = $boucle->id_table;
393
+    $arg = kwote(calculer_argument_precedent($idb, 'id_trad', $boucles));
394
+    $dprim = kwote(calculer_argument_precedent($idb, $prim, $boucles));
395
+    $boucle->where[] =
396
+        [
397
+            "'OR'",
398
+            [
399
+                "'AND'",
400
+                ["'='", "'$table.id_trad'", 0],
401
+                ["'='", "'$table.$prim'", $dprim]
402
+            ],
403
+            [
404
+                "'AND'",
405
+                ["'>'", "'$table.id_trad'", 0],
406
+                ["'='", "'$table.id_trad'", $arg]
407
+            ]
408
+        ];
409 409
 }
410 410
 
411 411
 
@@ -423,17 +423,17 @@  discard block
 block discarded – undo
423 423
  * @return void
424 424
  **/
425 425
 function critere_origine_traduction_dist($idb, &$boucles, $crit) {
426
-	$boucle = &$boucles[$idb];
427
-	$prim = $boucle->primary;
428
-	$table = $boucle->id_table;
429
-
430
-	$c =
431
-		[
432
-			"'OR'",
433
-			["'='", "'$table." . "id_trad'", "'$table.$prim'"],
434
-			["'='", "'$table.id_trad'", "'0'"]
435
-		];
436
-	$boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
426
+    $boucle = &$boucles[$idb];
427
+    $prim = $boucle->primary;
428
+    $table = $boucle->id_table;
429
+
430
+    $c =
431
+        [
432
+            "'OR'",
433
+            ["'='", "'$table." . "id_trad'", "'$table.$prim'"],
434
+            ["'='", "'$table.id_trad'", "'0'"]
435
+        ];
436
+    $boucle->where[] = ($crit->not ? ["'NOT'", $c] : $c);
437 437
 }
438 438
 
439 439
 
@@ -450,17 +450,17 @@  discard block
 block discarded – undo
450 450
  **/
451 451
 function critere_meme_parent_dist($idb, &$boucles, $crit) {
452 452
 
453
-	$boucle = &$boucles[$idb];
454
-	$arg = kwote(calculer_argument_precedent($idb, 'id_parent', $boucles));
455
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
456
-	$mparent = $boucle->id_table . '.' . $id_parent;
457
-
458
-	if ($boucle->type_requete == 'rubriques' || isset($GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'])) {
459
-		$boucle->where[] = ["'='", "'$mparent'", $arg];
460
-	} // le cas FORUMS est gere dans le plugin forum, dans la fonction critere_FORUMS_meme_parent_dist()
461
-	else {
462
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $boucle->type_requete]];
463
-	}
453
+    $boucle = &$boucles[$idb];
454
+    $arg = kwote(calculer_argument_precedent($idb, 'id_parent', $boucles));
455
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
456
+    $mparent = $boucle->id_table . '.' . $id_parent;
457
+
458
+    if ($boucle->type_requete == 'rubriques' || isset($GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'])) {
459
+        $boucle->where[] = ["'='", "'$mparent'", $arg];
460
+    } // le cas FORUMS est gere dans le plugin forum, dans la fonction critere_FORUMS_meme_parent_dist()
461
+    else {
462
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $boucle->type_requete]];
463
+    }
464 464
 }
465 465
 
466 466
 
@@ -491,38 +491,38 @@  discard block
 block discarded – undo
491 491
  **/
492 492
 function critere_branche_dist($idb, &$boucles, $crit) {
493 493
 
494
-	$not = $crit->not;
495
-	$boucle = &$boucles[$idb];
496
-	// prendre en priorite un identifiant en parametre {branche XX}
497
-	if (isset($crit->param[0])) {
498
-		$arg = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
499
-		// sinon on le prend chez une boucle parente
500
-	} else {
501
-		$arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles), $boucle->sql_serveur, 'int NOT NULL');
502
-	}
503
-
504
-	//Trouver une jointure
505
-	$champ = 'id_rubrique';
506
-	$desc = $boucle->show;
507
-	//Seulement si necessaire
508
-	if (!array_key_exists($champ, $desc['field'])) {
509
-		$cle = trouver_jointure_champ($champ, $boucle);
510
-		$trouver_table = charger_fonction('trouver_table', 'base');
511
-		$desc = $trouver_table($boucle->from[$cle]);
512
-		if (count(trouver_champs_decomposes($champ, $desc)) > 1) {
513
-			$decompose = decompose_champ_id_objet($champ);
514
-			$champ = array_shift($decompose);
515
-			$boucle->where[] = ["'='", _q($cle . '.' . reset($decompose)), '"' . sql_quote(end($decompose)) . '"'];
516
-		}
517
-	} else {
518
-		$cle = $boucle->id_table;
519
-	}
520
-
521
-	$c = "sql_in('$cle" . ".$champ', calcul_branche_in($arg)"
522
-		. ($not ? ", 'NOT'" : '') . ')';
523
-	$boucle->where[] = $crit->cond
524
-		? "($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')'
525
-		: $c;
494
+    $not = $crit->not;
495
+    $boucle = &$boucles[$idb];
496
+    // prendre en priorite un identifiant en parametre {branche XX}
497
+    if (isset($crit->param[0])) {
498
+        $arg = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
499
+        // sinon on le prend chez une boucle parente
500
+    } else {
501
+        $arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles), $boucle->sql_serveur, 'int NOT NULL');
502
+    }
503
+
504
+    //Trouver une jointure
505
+    $champ = 'id_rubrique';
506
+    $desc = $boucle->show;
507
+    //Seulement si necessaire
508
+    if (!array_key_exists($champ, $desc['field'])) {
509
+        $cle = trouver_jointure_champ($champ, $boucle);
510
+        $trouver_table = charger_fonction('trouver_table', 'base');
511
+        $desc = $trouver_table($boucle->from[$cle]);
512
+        if (count(trouver_champs_decomposes($champ, $desc)) > 1) {
513
+            $decompose = decompose_champ_id_objet($champ);
514
+            $champ = array_shift($decompose);
515
+            $boucle->where[] = ["'='", _q($cle . '.' . reset($decompose)), '"' . sql_quote(end($decompose)) . '"'];
516
+        }
517
+    } else {
518
+        $cle = $boucle->id_table;
519
+    }
520
+
521
+    $c = "sql_in('$cle" . ".$champ', calcul_branche_in($arg)"
522
+        . ($not ? ", 'NOT'" : '') . ')';
523
+    $boucle->where[] = $crit->cond
524
+        ? "($arg ? $c : " . ($not ? "'0=1'" : "'1=1'") . ')'
525
+        : $c;
526 526
 }
527 527
 
528 528
 /**
@@ -538,15 +538,15 @@  discard block
 block discarded – undo
538 538
  **/
539 539
 function critere_logo_dist($idb, &$boucles, $crit) {
540 540
 
541
-	$boucle = &$boucles[$idb];
542
-	$not = ($crit->not ? 'NOT' : '');
543
-	$serveur = $boucle->sql_serveur;
541
+    $boucle = &$boucles[$idb];
542
+    $not = ($crit->not ? 'NOT' : '');
543
+    $serveur = $boucle->sql_serveur;
544 544
 
545
-	$c = "sql_in('" .
546
-		$boucle->id_table . '.' . $boucle->primary
547
-		. "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')";
545
+    $c = "sql_in('" .
546
+        $boucle->id_table . '.' . $boucle->primary
547
+        . "', lister_objets_avec_logos('" . $boucle->primary . "'), '$not', '$serveur')";
548 548
 
549
-	$boucle->where[] = $c;
549
+    $boucle->where[] = $c;
550 550
 }
551 551
 
552 552
 
@@ -568,31 +568,31 @@  discard block
 block discarded – undo
568 568
  * @return void|array
569 569
  **/
570 570
 function critere_fusion_dist($idb, &$boucles, $crit) {
571
-	if ($t = isset($crit->param[0])) {
572
-		$t = $crit->param[0];
573
-		if ($t[0]->type == 'texte') {
574
-			$t = $t[0]->texte;
575
-			if (preg_match('/^(.*)\.(.*)$/', $t, $r)) {
576
-				$t = table_objet_sql($r[1]);
577
-				$t = array_search($t, $boucles[$idb]->from);
578
-				if ($t) {
579
-					$t .= '.' . $r[2];
580
-				}
581
-			}
582
-		} else {
583
-			$t = '".'
584
-				. calculer_critere_arg_dynamique($idb, $boucles, $t)
585
-				. '."';
586
-		}
587
-	}
588
-	if ($t) {
589
-		$boucles[$idb]->group[] = $t;
590
-		if (!in_array($t, $boucles[$idb]->select)) {
591
-			$boucles[$idb]->select[] = $t;
592
-		}
593
-	} else {
594
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
595
-	}
571
+    if ($t = isset($crit->param[0])) {
572
+        $t = $crit->param[0];
573
+        if ($t[0]->type == 'texte') {
574
+            $t = $t[0]->texte;
575
+            if (preg_match('/^(.*)\.(.*)$/', $t, $r)) {
576
+                $t = table_objet_sql($r[1]);
577
+                $t = array_search($t, $boucles[$idb]->from);
578
+                if ($t) {
579
+                    $t .= '.' . $r[2];
580
+                }
581
+            }
582
+        } else {
583
+            $t = '".'
584
+                . calculer_critere_arg_dynamique($idb, $boucles, $t)
585
+                . '."';
586
+        }
587
+    }
588
+    if ($t) {
589
+        $boucles[$idb]->group[] = $t;
590
+        if (!in_array($t, $boucles[$idb]->select)) {
591
+            $boucles[$idb]->select[] = $t;
592
+        }
593
+    } else {
594
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
595
+    }
596 596
 }
597 597
 
598 598
 /**
@@ -612,7 +612,7 @@  discard block
 block discarded – undo
612 612
  * @return void
613 613
  **/
614 614
 function critere_fusion_supprimer_dist($idb, &$boucles, $crit) {
615
-	$boucles[$idb]->group = [];
615
+    $boucles[$idb]->group = [];
616 616
 }
617 617
 
618 618
 /**
@@ -649,44 +649,44 @@  discard block
 block discarded – undo
649 649
  * @param Critere $crit Paramètres du critère dans cette boucle
650 650
  */
651 651
 function critere_collecte_dist($idb, &$boucles, $crit) {
652
-	if (isset($crit->param[0])) {
653
-		$_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
654
-		$boucle = $boucles[$idb];
655
-		$boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')";
656
-		$n = is_countable($boucle->order) ? count($boucle->order) : 0;
657
-		if ($n && (!str_contains($boucle->order[$n - 1], 'COLLATE'))) {
658
-			// l'instruction COLLATE doit être placée avant ASC ou DESC
659
-			// notamment lors de l'utilisation `{!par xxx}{collate yyy}`
660
-			if (
661
-				(false !== $i = strpos($boucle->order[$n - 1], 'ASC'))
662
-				|| (false !== $i = strpos($boucle->order[$n - 1], 'DESC'))
663
-			) {
664
-				$boucle->order[$n - 1] = substr_replace($boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0);
665
-			} else {
666
-				$boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate'];
667
-			}
668
-		}
669
-	} else {
670
-		return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]);
671
-	}
652
+    if (isset($crit->param[0])) {
653
+        $_coll = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
654
+        $boucle = $boucles[$idb];
655
+        $boucle->modificateur['collate'] = "($_coll ?' COLLATE '.$_coll:'')";
656
+        $n = is_countable($boucle->order) ? count($boucle->order) : 0;
657
+        if ($n && (!str_contains($boucle->order[$n - 1], 'COLLATE'))) {
658
+            // l'instruction COLLATE doit être placée avant ASC ou DESC
659
+            // notamment lors de l'utilisation `{!par xxx}{collate yyy}`
660
+            if (
661
+                (false !== $i = strpos($boucle->order[$n - 1], 'ASC'))
662
+                || (false !== $i = strpos($boucle->order[$n - 1], 'DESC'))
663
+            ) {
664
+                $boucle->order[$n - 1] = substr_replace($boucle->order[$n - 1], "' . " . $boucle->modificateur['collate'] . " . ' ", $i, 0);
665
+            } else {
666
+                $boucle->order[$n - 1] .= ' . ' . $boucle->modificateur['collate'];
667
+            }
668
+        }
669
+    } else {
670
+        return (['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . (is_countable($boucles[$idb]->order) ? count($boucles[$idb]->order) : 0)]]);
671
+    }
672 672
 }
673 673
 
674 674
 function calculer_critere_arg_dynamique($idb, &$boucles, $crit, $suffix = '') {
675
-	$boucle = $boucles[$idb];
676
-	$alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')';
677
-	$var = '$champs_' . $idb;
678
-	$desc = (str_contains($boucle->in, (string) "static $var ="));
679
-	if (!$desc) {
680
-		$desc = $boucle->show['field'];
681
-		$desc = implode(',', array_map('_q', array_keys($desc)));
682
-		$boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');';
683
-	}
684
-	if ($desc) {
685
-		$alt = "(in_array(\$x, $var)  ? $alt :(\$x$suffix))";
686
-	}
687
-	$arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent);
688
-
689
-	return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')";
675
+    $boucle = $boucles[$idb];
676
+    $alt = "('" . $boucle->id_table . '.\' . $x' . $suffix . ')';
677
+    $var = '$champs_' . $idb;
678
+    $desc = (str_contains($boucle->in, (string) "static $var ="));
679
+    if (!$desc) {
680
+        $desc = $boucle->show['field'];
681
+        $desc = implode(',', array_map('_q', array_keys($desc)));
682
+        $boucles[$idb]->in .= "\n\tstatic $var = array(" . $desc . ');';
683
+    }
684
+    if ($desc) {
685
+        $alt = "(in_array(\$x, $var)  ? $alt :(\$x$suffix))";
686
+    }
687
+    $arg = calculer_liste($crit, $idb, $boucles, $boucle->id_parent);
688
+
689
+    return "((\$x = preg_replace(\"/\\W/\",'', $arg)) ? $alt : '')";
690 690
 }
691 691
 
692 692
 /**
@@ -725,7 +725,7 @@  discard block
 block discarded – undo
725 725
  * @param Critere $crit Paramètres du critère dans cette boucle
726 726
  */
727 727
 function critere_par_dist($idb, &$boucles, $crit) {
728
-	return critere_parinverse($idb, $boucles, $crit);
728
+    return critere_parinverse($idb, $boucles, $crit);
729 729
 }
730 730
 
731 731
 /**
@@ -747,91 +747,91 @@  discard block
 block discarded – undo
747 747
  * @param Critere $crit Paramètres du critère dans cette boucle
748 748
  */
749 749
 function critere_parinverse($idb, &$boucles, $crit) {
750
-	$boucle = &$boucles[$idb];
751
-
752
-	$sens = $collecte = '';
753
-	if ($crit->not) {
754
-		$sens = " . ' DESC'";
755
-	}
756
-	if (isset($boucle->modificateur['collate'])) {
757
-		$collecte = ' . ' . $boucle->modificateur['collate'];
758
-	}
759
-
760
-	// Pour chaque paramètre du critère
761
-	foreach ($crit->param as $tri) {
762
-		$order = $fct = '';
763
-		// tris specifiés dynamiquement {par #ENV{tri}}
764
-		if ($tri[0]->type != 'texte') {
765
-			// calculer le order dynamique qui verifie les champs
766
-			$order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens);
767
-			// ajouter 'hasard' comme possibilité de tri dynamique
768
-			calculer_critere_par_hasard($idb, $boucles, $crit);
769
-		}
770
-		// tris textuels {par titre}
771
-		else {
772
-			$par = array_shift($tri);
773
-			$par = $par->texte;
774
-
775
-			// tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre}
776
-			if (preg_match(',^(\w+)[\s]+(.*)$,', $par, $m)) {
777
-				$expression = trim($m[1]);
778
-				$champ = trim($m[2]);
779
-				if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) {
780
-					$order = $f($idb, $boucles, $crit, $tri, $champ);
781
-				} else {
782
-					return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
783
-				}
784
-
785
-			// tris de la forme {par champ} ou {par FONCTION(champ)}
786
-			} elseif ($boucle->type_requete == 'DATA' || preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', $par, $match)) {
787
-				// {par FONCTION(champ)}
788
-				if (isset($match) && count($match) > 2) {
789
-					$par = substr($match[2], 1, -1);
790
-					$fct = $match[1];
791
-				}
792
-				// quelques cas spécifiques {par hasard}, {par date}
793
-				if ($par == 'hasard') {
794
-					$order = calculer_critere_par_hasard($idb, $boucles, $crit);
795
-				} elseif ($par == 'date' && !empty($boucle->show['date'])) {
796
-					$order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'";
797
-				} else {
798
-					// cas général {par champ}, {par table.champ}, ...
799
-					$order = calculer_critere_par_champ($idb, $boucles, $crit, $par);
800
-				}
801
-			}
802
-
803
-			// on ne sait pas traiter…
804
-			else {
805
-				return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
806
-			}
807
-
808
-			// En cas d'erreur de squelette retournée par une fonction
809
-			if (is_array($order)) {
810
-				return $order;
811
-			}
812
-		}
813
-
814
-		if (preg_match('/^\'([^"]*)\'$/', $order, $m)) {
815
-			$t = $m[1];
816
-			if (strpos($t, '.') && !in_array($t, $boucle->select)) {
817
-				$boucle->select[] = $t;
818
-			}
819
-		} else {
820
-			$sens = '';
821
-		}
822
-
823
-		if ($fct) {
824
-			$order = preg_match("/^\s*'(.*)'\s*$/", $order, $r)
825
-				? "'$fct(" . $r[1] . ")'"
826
-				: "'$fct(' . $order . ')'";
827
-		}
828
-		$t = $order . $collecte . $sens;
829
-		if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
830
-			$t = $r[1] . $r[2];
831
-		}
832
-
833
-		$boucle->order[] = $t;
834
-	}
750
+    $boucle = &$boucles[$idb];
751
+
752
+    $sens = $collecte = '';
753
+    if ($crit->not) {
754
+        $sens = " . ' DESC'";
755
+    }
756
+    if (isset($boucle->modificateur['collate'])) {
757
+        $collecte = ' . ' . $boucle->modificateur['collate'];
758
+    }
759
+
760
+    // Pour chaque paramètre du critère
761
+    foreach ($crit->param as $tri) {
762
+        $order = $fct = '';
763
+        // tris specifiés dynamiquement {par #ENV{tri}}
764
+        if ($tri[0]->type != 'texte') {
765
+            // calculer le order dynamique qui verifie les champs
766
+            $order = calculer_critere_arg_dynamique($idb, $boucles, $tri, $sens);
767
+            // ajouter 'hasard' comme possibilité de tri dynamique
768
+            calculer_critere_par_hasard($idb, $boucles, $crit);
769
+        }
770
+        // tris textuels {par titre}
771
+        else {
772
+            $par = array_shift($tri);
773
+            $par = $par->texte;
774
+
775
+            // tris de la forme {par expression champ} tel que {par num titre} ou {par multi titre}
776
+            if (preg_match(',^(\w+)[\s]+(.*)$,', $par, $m)) {
777
+                $expression = trim($m[1]);
778
+                $champ = trim($m[2]);
779
+                if (function_exists($f = 'calculer_critere_par_expression_' . $expression)) {
780
+                    $order = $f($idb, $boucles, $crit, $tri, $champ);
781
+                } else {
782
+                    return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
783
+                }
784
+
785
+            // tris de la forme {par champ} ou {par FONCTION(champ)}
786
+            } elseif ($boucle->type_requete == 'DATA' || preg_match(',^' . CHAMP_SQL_PLUS_FONC . '$,is', $par, $match)) {
787
+                // {par FONCTION(champ)}
788
+                if (isset($match) && count($match) > 2) {
789
+                    $par = substr($match[2], 1, -1);
790
+                    $fct = $match[1];
791
+                }
792
+                // quelques cas spécifiques {par hasard}, {par date}
793
+                if ($par == 'hasard') {
794
+                    $order = calculer_critere_par_hasard($idb, $boucles, $crit);
795
+                } elseif ($par == 'date' && !empty($boucle->show['date'])) {
796
+                    $order = "'" . $boucle->id_table . '.' . $boucle->show['date'] . "'";
797
+                } else {
798
+                    // cas général {par champ}, {par table.champ}, ...
799
+                    $order = calculer_critere_par_champ($idb, $boucles, $crit, $par);
800
+                }
801
+            }
802
+
803
+            // on ne sait pas traiter…
804
+            else {
805
+                return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
806
+            }
807
+
808
+            // En cas d'erreur de squelette retournée par une fonction
809
+            if (is_array($order)) {
810
+                return $order;
811
+            }
812
+        }
813
+
814
+        if (preg_match('/^\'([^"]*)\'$/', $order, $m)) {
815
+            $t = $m[1];
816
+            if (strpos($t, '.') && !in_array($t, $boucle->select)) {
817
+                $boucle->select[] = $t;
818
+            }
819
+        } else {
820
+            $sens = '';
821
+        }
822
+
823
+        if ($fct) {
824
+            $order = preg_match("/^\s*'(.*)'\s*$/", $order, $r)
825
+                ? "'$fct(" . $r[1] . ")'"
826
+                : "'$fct(' . $order . ')'";
827
+        }
828
+        $t = $order . $collecte . $sens;
829
+        if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
830
+            $t = $r[1] . $r[2];
831
+        }
832
+
833
+        $boucle->order[] = $t;
834
+    }
835 835
 }
836 836
 
837 837
 /**
@@ -845,13 +845,13 @@  discard block
 block discarded – undo
845 845
  * @return string Clause pour le Order by
846 846
  */
847 847
 function calculer_critere_par_hasard($idb, &$boucles, $crit) {
848
-	$boucle = &$boucles[$idb];
849
-	// Si ce n'est fait, ajouter un champ 'hasard' dans le select
850
-	$parha = 'rand() AS hasard';
851
-	if (!in_array($parha, $boucle->select)) {
852
-		$boucle->select[] = $parha;
853
-	}
854
-	return "'hasard'";
848
+    $boucle = &$boucles[$idb];
849
+    // Si ce n'est fait, ajouter un champ 'hasard' dans le select
850
+    $parha = 'rand() AS hasard';
851
+    if (!in_array($parha, $boucle->select)) {
852
+        $boucle->select[] = $parha;
853
+    }
854
+    return "'hasard'";
855 855
 }
856 856
 
857 857
 /**
@@ -875,22 +875,22 @@  discard block
 block discarded – undo
875 875
  * @return string|array Clause pour le Order by (array si erreur)
876 876
  */
877 877
 function calculer_critere_par_expression_num($idb, &$boucles, $crit, $tri, $champ) {
878
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
879
-	if (is_array($_champ)) {
880
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]];
881
-	}
882
-	$boucle = &$boucles[$idb];
883
-	$texte = '0+' . $_champ;
884
-	$suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
885
-	if ($suite !== "''") {
886
-		$texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
887
-	}
888
-	$asnum = 'num' . ($boucle->order ? count($boucle->order) : '');
889
-	$boucle->select[] = $texte . " AS $asnum";
890
-
891
-	$orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ);
892
-	$orderassinum = trim($orderassinum, "'");
893
-	return "'$orderassinum, $asnum'";
878
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
879
+    if (is_array($_champ)) {
880
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " num $champ"]];
881
+    }
882
+    $boucle = &$boucles[$idb];
883
+    $texte = '0+' . $_champ;
884
+    $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
885
+    if ($suite !== "''") {
886
+        $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
887
+    }
888
+    $asnum = 'num' . ($boucle->order ? count($boucle->order) : '');
889
+    $boucle->select[] = $texte . " AS $asnum";
890
+
891
+    $orderassinum = calculer_critere_par_expression_sinum($idb, $boucles, $crit, $tri, $champ);
892
+    $orderassinum = trim($orderassinum, "'");
893
+    return "'$orderassinum, $asnum'";
894 894
 }
895 895
 
896 896
 /**
@@ -911,34 +911,34 @@  discard block
 block discarded – undo
911 911
  * @return string|array Clause pour le Order by (array si erreur)
912 912
  */
913 913
 function calculer_critere_par_expression_sinum($idb, &$boucles, $crit, $tri, $champ) {
914
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
915
-	if (is_array($_champ)) {
916
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]];
917
-	}
918
-	$boucle = &$boucles[$idb];
919
-	$texte = '0+' . $_champ;
920
-	$suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
921
-	if ($suite !== "''") {
922
-		$texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
923
-	}
924
-
925
-	$as = false;
926
-	$select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS ";
927
-	foreach ($boucle->select as $s) {
928
-		if (str_starts_with($s, $select)) {
929
-			$as = trim(substr($s, strlen($select)));
930
-			if (!preg_match(',\W,', $as)) {
931
-				break;
932
-			}
933
-			$as = false;
934
-		}
935
-	}
936
-
937
-	if (!$as) {
938
-		$as = 'sinum' . ($boucle->order ? count($boucle->order) : '');
939
-		$boucle->select[] = $select . $as;
940
-	}
941
-	return "'$as'";
914
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
915
+    if (is_array($_champ)) {
916
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " sinum $champ"]];
917
+    }
918
+    $boucle = &$boucles[$idb];
919
+    $texte = '0+' . $_champ;
920
+    $suite = calculer_liste($tri, $idb, $boucles, $boucle->id_parent);
921
+    if ($suite !== "''") {
922
+        $texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . ' . "';
923
+    }
924
+
925
+    $as = false;
926
+    $select = "CASE ( $texte ) WHEN 0 THEN 1 ELSE 0 END AS ";
927
+    foreach ($boucle->select as $s) {
928
+        if (str_starts_with($s, $select)) {
929
+            $as = trim(substr($s, strlen($select)));
930
+            if (!preg_match(',\W,', $as)) {
931
+                break;
932
+            }
933
+            $as = false;
934
+        }
935
+    }
936
+
937
+    if (!$as) {
938
+        $as = 'sinum' . ($boucle->order ? count($boucle->order) : '');
939
+        $boucle->select[] = $select . $as;
940
+    }
941
+    return "'$as'";
942 942
 }
943 943
 
944 944
 
@@ -958,13 +958,13 @@  discard block
 block discarded – undo
958 958
  * @return string|array Clause pour le Order by (array si erreur)
959 959
  */
960 960
 function calculer_critere_par_expression_multi($idb, &$boucles, $crit, $tri, $champ) {
961
-	$_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
962
-	if (is_array($_champ)) {
963
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]];
964
-	}
965
-	$boucle = &$boucles[$idb];
966
-	$boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\"";
967
-	return "'multi'";
961
+    $_champ = calculer_critere_par_champ($idb, $boucles, $crit, $champ, true);
962
+    if (is_array($_champ)) {
963
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . " multi $champ"]];
964
+    }
965
+    $boucle = &$boucles[$idb];
966
+    $boucle->select[] = "\".sql_multi('" . $_champ . "', \$GLOBALS['spip_lang']).\"";
967
+    return "'multi'";
968 968
 }
969 969
 
970 970
 /**
@@ -983,56 +983,56 @@  discard block
 block discarded – undo
983 983
  * @return array|string
984 984
  */
985 985
 function calculer_critere_par_champ($idb, &$boucles, $crit, $par, $raw = false) {
986
-	$boucle = &$boucles[$idb];
987
-	$desc = $boucle->show;
988
-
989
-	// le champ existe dans la table, pas de souci (le plus commun)
990
-	if (isset($desc['field'][$par])) {
991
-		$par = $boucle->id_table . '.' . $par;
992
-	}
993
-	// le champ est peut être une jointure
994
-	else {
995
-		$table = $table_alias = false; // toutes les tables de jointure possibles
996
-		$champ = $par;
997
-
998
-		// le champ demandé est une exception de jointure {par titre_mot}
999
-		if (isset($GLOBALS['exceptions_des_jointures'][$par])) {
1000
-			[$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par];
1001
-		} // la table de jointure est explicitement indiquée {par truc.muche}
1002
-		elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) {
1003
-			[, $table, $champ] = $r;
1004
-			$table_alias = $table; // c'est peut-être un alias de table {par L1.titre}
1005
-			$table = table_objet_sql($table);
1006
-		}
1007
-
1008
-		// Si on connait la table d'arrivée, on la demande donc explicitement
1009
-		// Sinon on cherche le champ dans les tables possibles de jointures
1010
-		// Si la table est déjà dans le from, on la réutilise.
1011
-		if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) {
1012
-			$par = $infos['alias'] . '.' . $champ;
1013
-		} elseif (
1014
-			$boucle->jointures_explicites
1015
-			&& ($alias = trouver_jointure_champ($champ, $boucle, explode(' ', $boucle->jointures_explicites), false, $table))
1016
-		) {
1017
-			$par = $alias . '.' . $champ;
1018
-		} elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) {
1019
-			$par = $alias . '.' . $champ;
1020
-		// en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même)
1021
-		} elseif (
1022
-			$table_alias
1023
-			&& isset($boucle->from[$table_alias])
1024
-			&& ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias]))
1025
-		) {
1026
-			$par = $infos['alias'] . '.' . $champ;
1027
-		} elseif ($table) {
1028
-			// On avait table + champ, mais on ne les a pas trouvés
1029
-			return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
1030
-		} else {
1031
-			// Sinon tant pis, ca doit etre un champ synthetise (cf points)
1032
-		}
1033
-	}
1034
-
1035
-	return $raw ? $par : "'$par'";
986
+    $boucle = &$boucles[$idb];
987
+    $desc = $boucle->show;
988
+
989
+    // le champ existe dans la table, pas de souci (le plus commun)
990
+    if (isset($desc['field'][$par])) {
991
+        $par = $boucle->id_table . '.' . $par;
992
+    }
993
+    // le champ est peut être une jointure
994
+    else {
995
+        $table = $table_alias = false; // toutes les tables de jointure possibles
996
+        $champ = $par;
997
+
998
+        // le champ demandé est une exception de jointure {par titre_mot}
999
+        if (isset($GLOBALS['exceptions_des_jointures'][$par])) {
1000
+            [$table, $champ] = $GLOBALS['exceptions_des_jointures'][$par];
1001
+        } // la table de jointure est explicitement indiquée {par truc.muche}
1002
+        elseif (preg_match('/^([^,]*)\.(.*)$/', $par, $r)) {
1003
+            [, $table, $champ] = $r;
1004
+            $table_alias = $table; // c'est peut-être un alias de table {par L1.titre}
1005
+            $table = table_objet_sql($table);
1006
+        }
1007
+
1008
+        // Si on connait la table d'arrivée, on la demande donc explicitement
1009
+        // Sinon on cherche le champ dans les tables possibles de jointures
1010
+        // Si la table est déjà dans le from, on la réutilise.
1011
+        if ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $table)) {
1012
+            $par = $infos['alias'] . '.' . $champ;
1013
+        } elseif (
1014
+            $boucle->jointures_explicites
1015
+            && ($alias = trouver_jointure_champ($champ, $boucle, explode(' ', $boucle->jointures_explicites), false, $table))
1016
+        ) {
1017
+            $par = $alias . '.' . $champ;
1018
+        } elseif ($alias = trouver_jointure_champ($champ, $boucle, $boucle->jointures, false, $table)) {
1019
+            $par = $alias . '.' . $champ;
1020
+        // en spécifiant directement l'alias {par L2.titre} (situation hasardeuse tout de même)
1021
+        } elseif (
1022
+            $table_alias
1023
+            && isset($boucle->from[$table_alias])
1024
+            && ($infos = chercher_champ_dans_tables($champ, $boucle->from, $boucle->sql_serveur, $boucle->from[$table_alias]))
1025
+        ) {
1026
+            $par = $infos['alias'] . '.' . $champ;
1027
+        } elseif ($table) {
1028
+            // On avait table + champ, mais on ne les a pas trouvés
1029
+            return ['zbug_critere_inconnu', ['critere' => $crit->op . " $par"]];
1030
+        } else {
1031
+            // Sinon tant pis, ca doit etre un champ synthetise (cf points)
1032
+        }
1033
+    }
1034
+
1035
+    return $raw ? $par : "'$par'";
1036 1036
 }
1037 1037
 
1038 1038
 /**
@@ -1046,11 +1046,11 @@  discard block
 block discarded – undo
1046 1046
  * @return string Champ pour le compilateur si trouvé, tel que "'alias.champ'", sinon vide.
1047 1047
  */
1048 1048
 function critere_par_joint($table, $champ, &$boucle) {
1049
-	$t = array_search($table, $boucle->from);
1050
-	if (!$t) {
1051
-		$t = trouver_jointure_champ($champ, $boucle);
1052
-	}
1053
-	return $t ? "'" . $t . '.' . $champ . "'" : '';
1049
+    $t = array_search($table, $boucle->from);
1050
+    if (!$t) {
1051
+        $t = trouver_jointure_champ($champ, $boucle);
1052
+    }
1053
+    return $t ? "'" . $t . '.' . $champ . "'" : '';
1054 1054
 }
1055 1055
 
1056 1056
 /**
@@ -1075,33 +1075,33 @@  discard block
 block discarded – undo
1075 1075
  */
1076 1076
 function critere_inverse_dist($idb, &$boucles, $crit) {
1077 1077
 
1078
-	$boucle = &$boucles[$idb];
1079
-	// Classement par ordre inverse
1080
-	if ($crit->not) {
1081
-		critere_parinverse($idb, $boucles, $crit);
1082
-	} else {
1083
-		$order = "' DESC'";
1084
-		// Classement par ordre inverse fonction eventuelle de #ENV{...}
1085
-		if (isset($crit->param[0])) {
1086
-			$critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
1087
-			$order = "(($critere)?' DESC':'')";
1088
-		}
1089
-
1090
-		$n = is_countable($boucle->order) ? count($boucle->order) : 0;
1091
-		if (!$n) {
1092
-			if (isset($boucle->default_order[0])) {
1093
-				$boucle->default_order[0] .= ' . " DESC"';
1094
-			} else {
1095
-				$boucle->default_order[] = ' DESC';
1096
-			}
1097
-		} else {
1098
-			$t = $boucle->order[$n - 1] . " . $order";
1099
-			if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
1100
-				$t = $r[1] . $r[2];
1101
-			}
1102
-			$boucle->order[$n - 1] = $t;
1103
-		}
1104
-	}
1078
+    $boucle = &$boucles[$idb];
1079
+    // Classement par ordre inverse
1080
+    if ($crit->not) {
1081
+        critere_parinverse($idb, $boucles, $crit);
1082
+    } else {
1083
+        $order = "' DESC'";
1084
+        // Classement par ordre inverse fonction eventuelle de #ENV{...}
1085
+        if (isset($crit->param[0])) {
1086
+            $critere = calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent);
1087
+            $order = "(($critere)?' DESC':'')";
1088
+        }
1089
+
1090
+        $n = is_countable($boucle->order) ? count($boucle->order) : 0;
1091
+        if (!$n) {
1092
+            if (isset($boucle->default_order[0])) {
1093
+                $boucle->default_order[0] .= ' . " DESC"';
1094
+            } else {
1095
+                $boucle->default_order[] = ' DESC';
1096
+            }
1097
+        } else {
1098
+            $t = $boucle->order[$n - 1] . " . $order";
1099
+            if (preg_match("/^(.*)'\s*\.\s*'([^']*')$/", $t, $r)) {
1100
+                $t = $r[1] . $r[2];
1101
+            }
1102
+            $boucle->order[$n - 1] = $t;
1103
+        }
1104
+    }
1105 1105
 }
1106 1106
 
1107 1107
 /**
@@ -1113,139 +1113,139 @@  discard block
 block discarded – undo
1113 1113
  * @return void|array
1114 1114
  */
1115 1115
 function critere_par_ordre_liste_dist($idb, &$boucles, $crit) {
1116
-	$boucle = &$boucles[$idb];
1116
+    $boucle = &$boucles[$idb];
1117 1117
 
1118
-	$sens = $collecte = '';
1119
-	if ($crit->not) {
1120
-		$sens = " . ' DESC'";
1121
-	}
1118
+    $sens = $collecte = '';
1119
+    if ($crit->not) {
1120
+        $sens = " . ' DESC'";
1121
+    }
1122 1122
 
1123
-	$crit2 = clone $crit;
1124
-	$crit2->not = false;
1125
-	$crit2->param = [reset($crit->param)];
1126
-	$res = critere_parinverse($idb, $boucles, $crit2);
1123
+    $crit2 = clone $crit;
1124
+    $crit2->not = false;
1125
+    $crit2->param = [reset($crit->param)];
1126
+    $res = critere_parinverse($idb, $boucles, $crit2);
1127 1127
 
1128
-	// erreur ?
1129
-	if (is_array($res)) {
1130
-		return $res;
1131
-	}
1128
+    // erreur ?
1129
+    if (is_array($res)) {
1130
+        return $res;
1131
+    }
1132 1132
 
1133
-	$_order = array_pop($boucle->order);
1133
+    $_order = array_pop($boucle->order);
1134 1134
 
1135
-	$_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent);
1135
+    $_liste = calculer_liste($crit->param[1], [], $boucles, $boucles[$idb]->id_parent);
1136 1136
 
1137
-	$order = "'-FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste(array_reverse($_liste),'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens";
1138
-	$boucle->order[] = $order;
1137
+    $order = "'-FIELD(' . $_order . ',' . ((\$zl=formate_liste_critere_par_ordre_liste(array_reverse($_liste),'" . $boucle->sql_serveur . "')) ? \$zl : '0').')'$sens";
1138
+    $boucle->order[] = $order;
1139 1139
 }
1140 1140
 
1141 1141
 
1142 1142
 function critere_agenda_dist($idb, &$boucles, $crit) {
1143
-	$params = $crit->param;
1144
-
1145
-	if ((is_countable($params) ? count($params) : 0) < 1) {
1146
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1147
-	}
1148
-
1149
-	$boucle = &$boucles[$idb];
1150
-	$parent = $boucle->id_parent;
1151
-	$fields = $boucle->show['field'];
1152
-
1153
-	$date = array_shift($params);
1154
-	$type = array_shift($params);
1155
-
1156
-	// la valeur $type doit etre connue a la compilation
1157
-	// donc etre forcement reduite a un litteral unique dans le source
1158
-	$type = is_object($type[0]) ? $type[0]->texte : null;
1159
-
1160
-	// La valeur date doit designer un champ de la table SQL.
1161
-	// Si c'est un litteral unique dans le source, verifier a la compil,
1162
-	// sinon synthetiser le test de verif pour execution ulterieure
1163
-	// On prendra arbitrairement le premier champ si test negatif.
1164
-	if ((is_countable($date) ? count($date) : 0) == 1 && $date[0]->type == 'texte') {
1165
-		$date = $date[0]->texte;
1166
-		if (!isset($fields[$date])) {
1167
-			return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]];
1168
-		}
1169
-	} else {
1170
-		$a = calculer_liste($date, $idb, $boucles, $parent);
1171
-		$noms = array_keys($fields);
1172
-		$defaut = $noms[0];
1173
-		$noms = implode(' ', $noms);
1174
-		# bien laisser 2 espaces avant $nom pour que strpos<>0
1175
-		$cond = "(\$a=strval($a))AND\nstrpos(\"  $noms \",\" \$a \")";
1176
-		$date = "'.(($cond)\n?\$a:\"$defaut\").'";
1177
-	}
1178
-	$annee = $params ? array_shift($params) : '';
1179
-	$annee = "\n" . 'sprintf("%04d", ($x = ' .
1180
-		calculer_liste($annee, $idb, $boucles, $parent) .
1181
-		') ? $x : date("Y"))';
1182
-
1183
-	$mois = $params ? array_shift($params) : '';
1184
-	$mois = "\n" . 'sprintf("%02d", ($x = ' .
1185
-		calculer_liste($mois, $idb, $boucles, $parent) .
1186
-		') ? $x : date("m"))';
1187
-
1188
-	$jour = $params ? array_shift($params) : '';
1189
-	$jour = "\n" . 'sprintf("%02d", ($x = ' .
1190
-		calculer_liste($jour, $idb, $boucles, $parent) .
1191
-		') ? $x : date("d"))';
1192
-
1193
-	$annee2 = $params ? array_shift($params) : '';
1194
-	$annee2 = "\n" . 'sprintf("%04d", ($x = ' .
1195
-		calculer_liste($annee2, $idb, $boucles, $parent) .
1196
-		') ? $x : date("Y"))';
1197
-
1198
-	$mois2 = $params ? array_shift($params) : '';
1199
-	$mois2 = "\n" . 'sprintf("%02d", ($x = ' .
1200
-		calculer_liste($mois2, $idb, $boucles, $parent) .
1201
-		') ? $x : date("m"))';
1202
-
1203
-	$jour2 = $params ? array_shift($params) : '';
1204
-	$jour2 = "\n" . 'sprintf("%02d", ($x = ' .
1205
-		calculer_liste($jour2, $idb, $boucles, $parent) .
1206
-		') ? $x : date("d"))';
1207
-
1208
-	$date = $boucle->id_table . ".$date";
1209
-
1210
-	$quote_end = ",'" . $boucle->sql_serveur . "','text'";
1211
-	if ($type == 'jour') {
1212
-		$boucle->where[] = [
1213
-			"'='",
1214
-			"'DATE_FORMAT($date, \'%Y%m%d\')'",
1215
-			("sql_quote($annee . $mois . $jour$quote_end)")
1216
-		];
1217
-	} elseif ($type == 'mois') {
1218
-		$boucle->where[] = [
1219
-			"'='",
1220
-			"'DATE_FORMAT($date, \'%Y%m\')'",
1221
-			("sql_quote($annee . $mois$quote_end)")
1222
-		];
1223
-	} elseif ($type == 'semaine') {
1224
-		$boucle->where[] = [
1225
-			"'AND'",
1226
-			[
1227
-				"'>='",
1228
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1229
-				("date_debut_semaine($annee, $mois, $jour)")
1230
-			],
1231
-			[
1232
-				"'<='",
1233
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1234
-				("date_fin_semaine($annee, $mois, $jour)")
1235
-			]
1236
-		];
1237
-	} elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) {
1238
-		$boucle->where[] = [
1239
-			"'AND'",
1240
-			[
1241
-				"'>='",
1242
-				"'DATE_FORMAT($date, \'%Y%m%d\')'",
1243
-				("sql_quote($annee . $mois . $jour$quote_end)")
1244
-			],
1245
-			["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")]
1246
-		];
1247
-	}
1248
-	// sinon on prend tout
1143
+    $params = $crit->param;
1144
+
1145
+    if ((is_countable($params) ? count($params) : 0) < 1) {
1146
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1147
+    }
1148
+
1149
+    $boucle = &$boucles[$idb];
1150
+    $parent = $boucle->id_parent;
1151
+    $fields = $boucle->show['field'];
1152
+
1153
+    $date = array_shift($params);
1154
+    $type = array_shift($params);
1155
+
1156
+    // la valeur $type doit etre connue a la compilation
1157
+    // donc etre forcement reduite a un litteral unique dans le source
1158
+    $type = is_object($type[0]) ? $type[0]->texte : null;
1159
+
1160
+    // La valeur date doit designer un champ de la table SQL.
1161
+    // Si c'est un litteral unique dans le source, verifier a la compil,
1162
+    // sinon synthetiser le test de verif pour execution ulterieure
1163
+    // On prendra arbitrairement le premier champ si test negatif.
1164
+    if ((is_countable($date) ? count($date) : 0) == 1 && $date[0]->type == 'texte') {
1165
+        $date = $date[0]->texte;
1166
+        if (!isset($fields[$date])) {
1167
+            return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ' . $date]];
1168
+        }
1169
+    } else {
1170
+        $a = calculer_liste($date, $idb, $boucles, $parent);
1171
+        $noms = array_keys($fields);
1172
+        $defaut = $noms[0];
1173
+        $noms = implode(' ', $noms);
1174
+        # bien laisser 2 espaces avant $nom pour que strpos<>0
1175
+        $cond = "(\$a=strval($a))AND\nstrpos(\"  $noms \",\" \$a \")";
1176
+        $date = "'.(($cond)\n?\$a:\"$defaut\").'";
1177
+    }
1178
+    $annee = $params ? array_shift($params) : '';
1179
+    $annee = "\n" . 'sprintf("%04d", ($x = ' .
1180
+        calculer_liste($annee, $idb, $boucles, $parent) .
1181
+        ') ? $x : date("Y"))';
1182
+
1183
+    $mois = $params ? array_shift($params) : '';
1184
+    $mois = "\n" . 'sprintf("%02d", ($x = ' .
1185
+        calculer_liste($mois, $idb, $boucles, $parent) .
1186
+        ') ? $x : date("m"))';
1187
+
1188
+    $jour = $params ? array_shift($params) : '';
1189
+    $jour = "\n" . 'sprintf("%02d", ($x = ' .
1190
+        calculer_liste($jour, $idb, $boucles, $parent) .
1191
+        ') ? $x : date("d"))';
1192
+
1193
+    $annee2 = $params ? array_shift($params) : '';
1194
+    $annee2 = "\n" . 'sprintf("%04d", ($x = ' .
1195
+        calculer_liste($annee2, $idb, $boucles, $parent) .
1196
+        ') ? $x : date("Y"))';
1197
+
1198
+    $mois2 = $params ? array_shift($params) : '';
1199
+    $mois2 = "\n" . 'sprintf("%02d", ($x = ' .
1200
+        calculer_liste($mois2, $idb, $boucles, $parent) .
1201
+        ') ? $x : date("m"))';
1202
+
1203
+    $jour2 = $params ? array_shift($params) : '';
1204
+    $jour2 = "\n" . 'sprintf("%02d", ($x = ' .
1205
+        calculer_liste($jour2, $idb, $boucles, $parent) .
1206
+        ') ? $x : date("d"))';
1207
+
1208
+    $date = $boucle->id_table . ".$date";
1209
+
1210
+    $quote_end = ",'" . $boucle->sql_serveur . "','text'";
1211
+    if ($type == 'jour') {
1212
+        $boucle->where[] = [
1213
+            "'='",
1214
+            "'DATE_FORMAT($date, \'%Y%m%d\')'",
1215
+            ("sql_quote($annee . $mois . $jour$quote_end)")
1216
+        ];
1217
+    } elseif ($type == 'mois') {
1218
+        $boucle->where[] = [
1219
+            "'='",
1220
+            "'DATE_FORMAT($date, \'%Y%m\')'",
1221
+            ("sql_quote($annee . $mois$quote_end)")
1222
+        ];
1223
+    } elseif ($type == 'semaine') {
1224
+        $boucle->where[] = [
1225
+            "'AND'",
1226
+            [
1227
+                "'>='",
1228
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1229
+                ("date_debut_semaine($annee, $mois, $jour)")
1230
+            ],
1231
+            [
1232
+                "'<='",
1233
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1234
+                ("date_fin_semaine($annee, $mois, $jour)")
1235
+            ]
1236
+        ];
1237
+    } elseif ((is_countable($crit->param) ? count($crit->param) : 0) > 2) {
1238
+        $boucle->where[] = [
1239
+            "'AND'",
1240
+            [
1241
+                "'>='",
1242
+                "'DATE_FORMAT($date, \'%Y%m%d\')'",
1243
+                ("sql_quote($annee . $mois . $jour$quote_end)")
1244
+            ],
1245
+            ["'<='", "'DATE_FORMAT($date, \'%Y%m%d\')'", ("sql_quote($annee2 . $mois2 . $jour2$quote_end)")]
1246
+        ];
1247
+    }
1248
+    // sinon on prend tout
1249 1249
 }
1250 1250
 
1251 1251
 
@@ -1270,33 +1270,33 @@  discard block
 block discarded – undo
1270 1270
  * @return void
1271 1271
  **/
1272 1272
 function calculer_critere_parties($idb, &$boucles, $crit) {
1273
-	$boucle = &$boucles[$idb];
1274
-	$a1 = $crit->param[0];
1275
-	$a2 = $crit->param[1];
1276
-	$op = $crit->op;
1277
-
1278
-	[$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1);
1279
-	[$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2);
1280
-
1281
-	if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) {
1282
-		$boucle->limit = $a11 . ',' . $a21;
1283
-	} else {
1284
-		// 3 dans {1/3}, {2,3} ou {1,n-3}
1285
-		$boucle->total_parties = ($a21 != 'n') ? $a21 : $a22;
1286
-		// 2 dans {2/3}, {2,5}, {n-2,1}
1287
-		$partie = ($a11 != 'n') ? $a11 : $a12;
1288
-		$mode = (($op == '/') ? '/' :
1289
-			(($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+'));
1290
-		// cas simple {0,#ENV{truc}} compilons le en LIMIT :
1291
-		if ($a11 !== 'n' && $a21 !== 'n' && $mode == '++' && $op == ',') {
1292
-			$boucle->limit =
1293
-				(is_numeric($a11) ? "'$a11'" : $a11)
1294
-				. ".','."
1295
-				. (is_numeric($a21) ? "'$a21'" : $a21);
1296
-		} else {
1297
-			calculer_parties($boucles, $idb, $partie, $mode);
1298
-		}
1299
-	}
1273
+    $boucle = &$boucles[$idb];
1274
+    $a1 = $crit->param[0];
1275
+    $a2 = $crit->param[1];
1276
+    $op = $crit->op;
1277
+
1278
+    [$a11, $a12] = calculer_critere_parties_aux($idb, $boucles, $a1);
1279
+    [$a21, $a22] = calculer_critere_parties_aux($idb, $boucles, $a2);
1280
+
1281
+    if (($op == ',') && (is_numeric($a11) && (is_numeric($a21)))) {
1282
+        $boucle->limit = $a11 . ',' . $a21;
1283
+    } else {
1284
+        // 3 dans {1/3}, {2,3} ou {1,n-3}
1285
+        $boucle->total_parties = ($a21 != 'n') ? $a21 : $a22;
1286
+        // 2 dans {2/3}, {2,5}, {n-2,1}
1287
+        $partie = ($a11 != 'n') ? $a11 : $a12;
1288
+        $mode = (($op == '/') ? '/' :
1289
+            (($a11 == 'n') ? '-' : '+') . (($a21 == 'n') ? '-' : '+'));
1290
+        // cas simple {0,#ENV{truc}} compilons le en LIMIT :
1291
+        if ($a11 !== 'n' && $a21 !== 'n' && $mode == '++' && $op == ',') {
1292
+            $boucle->limit =
1293
+                (is_numeric($a11) ? "'$a11'" : $a11)
1294
+                . ".','."
1295
+                . (is_numeric($a21) ? "'$a21'" : $a21);
1296
+        } else {
1297
+            calculer_parties($boucles, $idb, $partie, $mode);
1298
+        }
1299
+    }
1300 1300
 }
1301 1301
 
1302 1302
 /**
@@ -1324,63 +1324,63 @@  discard block
 block discarded – undo
1324 1324
  * @return void
1325 1325
  **/
1326 1326
 function calculer_parties(&$boucles, $id_boucle, $debut, $mode) {
1327
-	$total_parties = $boucles[$id_boucle]->total_parties;
1328
-
1329
-	preg_match(',([+-/p])([+-/])?,', $mode, $regs);
1330
-	[, $op1, $op2] = array_pad($regs, 3, null);
1331
-	$nombre_boucle = "\$Numrows['$id_boucle']['total']";
1332
-	// {1/3}
1333
-	if ($op1 == '/') {
1334
-		$pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)";
1335
-		$totpos = is_numeric($total_parties) ? ($total_parties) :
1336
-			"($total_parties ? $total_parties : 1)";
1337
-		$fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1";
1338
-		$debut = $pmoins1 ? "ceil(($nombre_boucle * $pmoins1)/$totpos);" : 0;
1339
-	} else {
1340
-		// cas {n-1,x}
1341
-		if ($op1 == '-') {
1342
-			$debut = "$nombre_boucle - $debut;";
1343
-		}
1344
-
1345
-		// cas {x,n-1}
1346
-		if ($op2 == '-') {
1347
-			$fin = '$debut_boucle + ' . $nombre_boucle . ' - '
1348
-				. (is_numeric($total_parties) ? ($total_parties + 1) :
1349
-					($total_parties . ' - 1'));
1350
-		} else {
1351
-			// {x,1} ou {pagination}
1352
-			$fin = '$debut_boucle'
1353
-				. (is_numeric($total_parties) ?
1354
-					(($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) :
1355
-					('+' . $total_parties . ' - 1'));
1356
-		}
1357
-
1358
-		// {pagination}, gerer le debut_xx=-1 pour tout voir
1359
-		if ($op1 == 'p') {
1360
-			$debut .= ";\n	\$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))";
1361
-			$debut .= ";\n	\$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))";
1362
-			$fin = "(\$tout ? $nombre_boucle : $fin)";
1363
-		}
1364
-	}
1365
-
1366
-	// Notes :
1367
-	// $debut_boucle et $fin_boucle sont les indices SQL du premier
1368
-	// et du dernier demandes dans la boucle : 0 pour le premier,
1369
-	// n-1 pour le dernier ; donc total_boucle = 1 + debut - fin
1370
-	// Utiliser min pour rabattre $fin_boucle sur total_boucle.
1371
-
1372
-	$boucles[$id_boucle]->mode_partie = "\n\t"
1373
-		. '$debut_boucle = ' . $debut . ";\n	"
1374
-		. "\$debut_boucle = intval(\$debut_boucle);\n	"
1375
-		. '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n	"
1376
-		. '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n	"
1377
-		. '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);'
1378
-		. "\n\tif (\$debut_boucle>0"
1379
-		. " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']"
1380
-		. " AND \$iter->seek(\$debut_boucle,'continue'))"
1381
-		. "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t";
1382
-
1383
-	$boucles[$id_boucle]->partie = "
1327
+    $total_parties = $boucles[$id_boucle]->total_parties;
1328
+
1329
+    preg_match(',([+-/p])([+-/])?,', $mode, $regs);
1330
+    [, $op1, $op2] = array_pad($regs, 3, null);
1331
+    $nombre_boucle = "\$Numrows['$id_boucle']['total']";
1332
+    // {1/3}
1333
+    if ($op1 == '/') {
1334
+        $pmoins1 = is_numeric($debut) ? ($debut - 1) : "($debut-1)";
1335
+        $totpos = is_numeric($total_parties) ? ($total_parties) :
1336
+            "($total_parties ? $total_parties : 1)";
1337
+        $fin = "ceil(($nombre_boucle * $debut )/$totpos) - 1";
1338
+        $debut = $pmoins1 ? "ceil(($nombre_boucle * $pmoins1)/$totpos);" : 0;
1339
+    } else {
1340
+        // cas {n-1,x}
1341
+        if ($op1 == '-') {
1342
+            $debut = "$nombre_boucle - $debut;";
1343
+        }
1344
+
1345
+        // cas {x,n-1}
1346
+        if ($op2 == '-') {
1347
+            $fin = '$debut_boucle + ' . $nombre_boucle . ' - '
1348
+                . (is_numeric($total_parties) ? ($total_parties + 1) :
1349
+                    ($total_parties . ' - 1'));
1350
+        } else {
1351
+            // {x,1} ou {pagination}
1352
+            $fin = '$debut_boucle'
1353
+                . (is_numeric($total_parties) ?
1354
+                    (($total_parties == 1) ? '' : (' + ' . ($total_parties - 1))) :
1355
+                    ('+' . $total_parties . ' - 1'));
1356
+        }
1357
+
1358
+        // {pagination}, gerer le debut_xx=-1 pour tout voir
1359
+        if ($op1 == 'p') {
1360
+            $debut .= ";\n	\$debut_boucle = ((\$tout=(\$debut_boucle == -1))?0:(\$debut_boucle))";
1361
+            $debut .= ";\n	\$debut_boucle = max(0,min(\$debut_boucle,floor(($nombre_boucle-1)/($total_parties))*($total_parties)))";
1362
+            $fin = "(\$tout ? $nombre_boucle : $fin)";
1363
+        }
1364
+    }
1365
+
1366
+    // Notes :
1367
+    // $debut_boucle et $fin_boucle sont les indices SQL du premier
1368
+    // et du dernier demandes dans la boucle : 0 pour le premier,
1369
+    // n-1 pour le dernier ; donc total_boucle = 1 + debut - fin
1370
+    // Utiliser min pour rabattre $fin_boucle sur total_boucle.
1371
+
1372
+    $boucles[$id_boucle]->mode_partie = "\n\t"
1373
+        . '$debut_boucle = ' . $debut . ";\n	"
1374
+        . "\$debut_boucle = intval(\$debut_boucle);\n	"
1375
+        . '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n	"
1376
+        . '$Numrows[\'' . $id_boucle . "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n	"
1377
+        . '$Numrows[\'' . $id_boucle . '\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);'
1378
+        . "\n\tif (\$debut_boucle>0"
1379
+        . " AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total']"
1380
+        . " AND \$iter->seek(\$debut_boucle,'continue'))"
1381
+        . "\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t";
1382
+
1383
+    $boucles[$id_boucle]->partie = "
1384 1384
 		if (\$Numrows['$id_boucle']['compteur_boucle'] <= \$debut_boucle) continue;
1385 1385
 		if (\$Numrows['$id_boucle']['compteur_boucle']-1 > \$fin_boucle) break;";
1386 1386
 }
@@ -1397,26 +1397,26 @@  discard block
 block discarded – undo
1397 1397
  * @return array          Valeur de l'élément (peut être une expression PHP), Nombre soustrait
1398 1398
  **/
1399 1399
 function calculer_critere_parties_aux($idb, &$boucles, $param) {
1400
-	if ($param[0]->type != 'texte') {
1401
-		$a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent);
1402
-		if (isset($param[1]->texte)) {
1403
-			preg_match(',^\s*(-(\d+))?\s*$,', $param[1]->texte, $m);
1404
-
1405
-			return ["intval($a1)", ((isset($m[2]) && $m[2]) ? $m[2] : 0)];
1406
-		} else {
1407
-			return ["intval($a1)", 0];
1408
-		}
1409
-	} else {
1410
-		preg_match(',^\s*((\d+)|n)\s*(-\s*(\d+)?\s*)?$,', $param[0]->texte, $m);
1411
-		$a1 = $m[1];
1412
-		if (empty($m[3])) {
1413
-			return [$a1, 0];
1414
-		} elseif (!empty($m[4])) {
1415
-			return [$a1, $m[4]];
1416
-		} else {
1417
-			return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)];
1418
-		}
1419
-	}
1400
+    if ($param[0]->type != 'texte') {
1401
+        $a1 = calculer_liste([$param[0]], $idb, $boucles, $boucles[$idb]->id_parent);
1402
+        if (isset($param[1]->texte)) {
1403
+            preg_match(',^\s*(-(\d+))?\s*$,', $param[1]->texte, $m);
1404
+
1405
+            return ["intval($a1)", ((isset($m[2]) && $m[2]) ? $m[2] : 0)];
1406
+        } else {
1407
+            return ["intval($a1)", 0];
1408
+        }
1409
+    } else {
1410
+        preg_match(',^\s*((\d+)|n)\s*(-\s*(\d+)?\s*)?$,', $param[0]->texte, $m);
1411
+        $a1 = $m[1];
1412
+        if (empty($m[3])) {
1413
+            return [$a1, 0];
1414
+        } elseif (!empty($m[4])) {
1415
+            return [$a1, $m[4]];
1416
+        } else {
1417
+            return [$a1, calculer_liste([$param[1]], $idb, $boucles, $boucles[$idb]->id_parent)];
1418
+        }
1419
+    }
1420 1420
 }
1421 1421
 
1422 1422
 
@@ -1443,46 +1443,46 @@  discard block
 block discarded – undo
1443 1443
  *     array : Erreur sur un des critères
1444 1444
  **/
1445 1445
 function calculer_criteres($idb, &$boucles) {
1446
-	$msg = '';
1447
-	$boucle = $boucles[$idb];
1448
-	$table = strtoupper($boucle->type_requete);
1449
-	$serveur = strtolower($boucle->sql_serveur);
1450
-
1451
-	$defaut = charger_fonction('DEFAUT', 'calculer_critere');
1452
-	// s'il y avait une erreur de syntaxe, propager cette info
1453
-	if (!is_array($boucle->criteres)) {
1454
-		return [];
1455
-	}
1456
-
1457
-	foreach ($boucle->criteres as $crit) {
1458
-		$critere = $crit->op;
1459
-		// critere personnalise ?
1460
-		if (
1461
-			(!$serveur
1462
-				|| !function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere)
1463
-				&& !function_exists($f .= '_dist')
1464
-				&& !function_exists($f = 'critere_' . $serveur . '_' . $critere)
1465
-				&& !function_exists($f .= '_dist')
1466
-			)
1467
-			&& !function_exists($f = 'critere_' . $table . '_' . $critere)
1468
-			&& !function_exists($f .= '_dist')
1469
-			&& !function_exists($f = 'critere_' . $critere)
1470
-			&& !function_exists($f .= '_dist')
1471
-		) {
1472
-			// fonction critere standard
1473
-			$f = $defaut;
1474
-		}
1475
-		// compile le critere
1476
-		$res = $f($idb, $boucles, $crit);
1477
-
1478
-		// Gestion centralisee des erreurs pour pouvoir propager
1479
-		if (is_array($res)) {
1480
-			$msg = $res;
1481
-			erreur_squelette($msg, $boucle);
1482
-		}
1483
-	}
1484
-
1485
-	return $msg;
1446
+    $msg = '';
1447
+    $boucle = $boucles[$idb];
1448
+    $table = strtoupper($boucle->type_requete);
1449
+    $serveur = strtolower($boucle->sql_serveur);
1450
+
1451
+    $defaut = charger_fonction('DEFAUT', 'calculer_critere');
1452
+    // s'il y avait une erreur de syntaxe, propager cette info
1453
+    if (!is_array($boucle->criteres)) {
1454
+        return [];
1455
+    }
1456
+
1457
+    foreach ($boucle->criteres as $crit) {
1458
+        $critere = $crit->op;
1459
+        // critere personnalise ?
1460
+        if (
1461
+            (!$serveur
1462
+                || !function_exists($f = 'critere_' . $serveur . '_' . $table . '_' . $critere)
1463
+                && !function_exists($f .= '_dist')
1464
+                && !function_exists($f = 'critere_' . $serveur . '_' . $critere)
1465
+                && !function_exists($f .= '_dist')
1466
+            )
1467
+            && !function_exists($f = 'critere_' . $table . '_' . $critere)
1468
+            && !function_exists($f .= '_dist')
1469
+            && !function_exists($f = 'critere_' . $critere)
1470
+            && !function_exists($f .= '_dist')
1471
+        ) {
1472
+            // fonction critere standard
1473
+            $f = $defaut;
1474
+        }
1475
+        // compile le critere
1476
+        $res = $f($idb, $boucles, $crit);
1477
+
1478
+        // Gestion centralisee des erreurs pour pouvoir propager
1479
+        if (is_array($res)) {
1480
+            $msg = $res;
1481
+            erreur_squelette($msg, $boucle);
1482
+        }
1483
+    }
1484
+
1485
+    return $msg;
1486 1486
 }
1487 1487
 
1488 1488
 /**
@@ -1497,11 +1497,11 @@  discard block
 block discarded – undo
1497 1497
  * @return string         Code compilé rééchappé
1498 1498
  */
1499 1499
 function kwote($lisp, $serveur = '', $type = '') {
1500
-	if (preg_match(_CODE_QUOTE, $lisp, $r)) {
1501
-		return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"';
1502
-	} else {
1503
-		return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')";
1504
-	}
1500
+    if (preg_match(_CODE_QUOTE, $lisp, $r)) {
1501
+        return $r[1] . '"' . sql_quote(str_replace(["\\'", '\\\\'], ["'", '\\'], $r[2]), $serveur, $type) . '"';
1502
+    } else {
1503
+        return "sql_quote($lisp, '$serveur', '" . str_replace("'", "\\'", $type) . "')";
1504
+    }
1505 1505
 }
1506 1506
 
1507 1507
 
@@ -1520,81 +1520,81 @@  discard block
 block discarded – undo
1520 1520
  * @return void|array
1521 1521
  **/
1522 1522
 function critere_IN_dist($idb, &$boucles, $crit) {
1523
-	$r = calculer_critere_infixe($idb, $boucles, $crit);
1524
-	if (!$r) {
1525
-		return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1526
-	}
1527
-	[$arg, $op, $val, $col, $where_complement] = $r;
1528
-
1529
-	$in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col);
1530
-
1531
-	//	inserer la condition; exemple: {id_mot ?IN (66, 62, 64)}
1532
-	$where = $in;
1533
-	if ($crit->cond) {
1534
-		$pred = calculer_argument_precedent($idb, $col, $boucles);
1535
-		$where = ["'?'", $pred, $where, "''"];
1536
-		if ($where_complement) { // condition annexe du type "AND (objet='article')"
1537
-		$where_complement = ["'?'", $pred, $where_complement, "''"];
1538
-		}
1539
-	}
1540
-	if ($crit->exclus) {
1541
-		if (!preg_match(',^L\d+[.],', $arg)) {
1542
-			$where = ["'NOT'", $where];
1543
-		} else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1544
-			// c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1545
-		{
1546
-			$where = [
1547
-				"'NOT'",
1548
-				[
1549
-					"'IN'",
1550
-					"'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1551
-					["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1552
-				]
1553
-			];
1554
-		}
1555
-	}
1556
-
1557
-	$boucles[$idb]->where[] = $where;
1558
-	if ($where_complement) { // condition annexe du type "AND (objet='article')"
1559
-	$boucles[$idb]->where[] = $where_complement;
1560
-	}
1523
+    $r = calculer_critere_infixe($idb, $boucles, $crit);
1524
+    if (!$r) {
1525
+        return ['zbug_critere_inconnu', ['critere' => $crit->op . ' ?']];
1526
+    }
1527
+    [$arg, $op, $val, $col, $where_complement] = $r;
1528
+
1529
+    $in = critere_IN_cas($idb, $boucles, $crit->not ? 'NOT' : ($crit->exclus ? 'exclus' : ''), $arg, $op, $val, $col);
1530
+
1531
+    //	inserer la condition; exemple: {id_mot ?IN (66, 62, 64)}
1532
+    $where = $in;
1533
+    if ($crit->cond) {
1534
+        $pred = calculer_argument_precedent($idb, $col, $boucles);
1535
+        $where = ["'?'", $pred, $where, "''"];
1536
+        if ($where_complement) { // condition annexe du type "AND (objet='article')"
1537
+        $where_complement = ["'?'", $pred, $where_complement, "''"];
1538
+        }
1539
+    }
1540
+    if ($crit->exclus) {
1541
+        if (!preg_match(',^L\d+[.],', $arg)) {
1542
+            $where = ["'NOT'", $where];
1543
+        } else // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1544
+            // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1545
+        {
1546
+            $where = [
1547
+                "'NOT'",
1548
+                [
1549
+                    "'IN'",
1550
+                    "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1551
+                    ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1552
+                ]
1553
+            ];
1554
+        }
1555
+    }
1556
+
1557
+    $boucles[$idb]->where[] = $where;
1558
+    if ($where_complement) { // condition annexe du type "AND (objet='article')"
1559
+    $boucles[$idb]->where[] = $where_complement;
1560
+    }
1561 1561
 }
1562 1562
 
1563 1563
 function critere_IN_cas($idb, &$boucles, $crit2, $arg, $op, $val, $col) {
1564
-	static $num = [];
1565
-	$descr = $boucles[$idb]->descr;
1566
-	$cpt = &$num[$descr['nom']][$descr['gram']][$idb];
1567
-
1568
-	$var = '$in' . $cpt++;
1569
-	$x = "\n\t$var = array();";
1570
-	foreach ($val as $k => $v) {
1571
-		if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) {
1572
-			// optimiser le traitement des constantes
1573
-			if (is_numeric($r[2])) {
1574
-				$x .= "\n\t$var" . "[]= $r[2];";
1575
-			} else {
1576
-				$x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';';
1577
-			}
1578
-		} else {
1579
-			// Pour permettre de passer des tableaux de valeurs
1580
-			// on repere l'utilisation brute de #ENV**{X},
1581
-			// c'est-a-dire sa  traduction en ($PILE[0][X]).
1582
-			// et on deballe mais en rajoutant l'anti XSS
1583
-			$x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);";
1584
-		}
1585
-	}
1586
-
1587
-	$boucles[$idb]->in .= $x;
1588
-
1589
-	// inserer le tri par defaut selon les ordres du IN ...
1590
-	// avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp)
1591
-	// et que l'on limite donc strictement aux cas necessaires :
1592
-	// si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle
1593
-	if (!$crit2) {
1594
-		$boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))";
1595
-	}
1596
-
1597
-	return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')';
1564
+    static $num = [];
1565
+    $descr = $boucles[$idb]->descr;
1566
+    $cpt = &$num[$descr['nom']][$descr['gram']][$idb];
1567
+
1568
+    $var = '$in' . $cpt++;
1569
+    $x = "\n\t$var = array();";
1570
+    foreach ($val as $k => $v) {
1571
+        if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) {
1572
+            // optimiser le traitement des constantes
1573
+            if (is_numeric($r[2])) {
1574
+                $x .= "\n\t$var" . "[]= $r[2];";
1575
+            } else {
1576
+                $x .= "\n\t$var" . '[]= ' . sql_quote($r[2]) . ';';
1577
+            }
1578
+        } else {
1579
+            // Pour permettre de passer des tableaux de valeurs
1580
+            // on repere l'utilisation brute de #ENV**{X},
1581
+            // c'est-a-dire sa  traduction en ($PILE[0][X]).
1582
+            // et on deballe mais en rajoutant l'anti XSS
1583
+            $x .= "\n\tif (!(is_array(\$a = ($v))))\n\t\t$var" . "[]= \$a;\n\telse $var = array_merge($var, \$a);";
1584
+        }
1585
+    }
1586
+
1587
+    $boucles[$idb]->in .= $x;
1588
+
1589
+    // inserer le tri par defaut selon les ordres du IN ...
1590
+    // avec une ecriture de type FIELD qui degrade les performances (du meme ordre qu'un regexp)
1591
+    // et que l'on limite donc strictement aux cas necessaires :
1592
+    // si ce n'est pas un !IN, et si il n'y a pas d'autre order dans la boucle
1593
+    if (!$crit2) {
1594
+        $boucles[$idb]->default_order[] = "((!\$zqv=sql_quote($var) OR \$zqv===\"''\") ? 0 : ('FIELD($arg,' . \$zqv . ')'))";
1595
+    }
1596
+
1597
+    return "sql_in('$arg', $var" . ($crit2 == 'NOT' ? ",'NOT'" : '') . ')';
1598 1598
 }
1599 1599
 
1600 1600
 /**
@@ -1610,22 +1610,22 @@  discard block
 block discarded – undo
1610 1610
  * @return void
1611 1611
  */
1612 1612
 function critere_where_dist($idb, &$boucles, $crit) {
1613
-	$boucle = &$boucles[$idb];
1614
-	if (isset($crit->param[0])) {
1615
-		$_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1616
-	} else {
1617
-		$_where = 'spip_sanitize_from_request(@$Pile[0]["where"],"where","vide")';
1618
-	}
1619
-
1620
-	if ($crit->cond) {
1621
-		$_where = "((\$zzw = $_where) ? \$zzw : '')";
1622
-	}
1623
-
1624
-	if ($crit->not) {
1625
-		$_where = "array('NOT',$_where)";
1626
-	}
1627
-
1628
-	$boucle->where[] = $_where;
1613
+    $boucle = &$boucles[$idb];
1614
+    if (isset($crit->param[0])) {
1615
+        $_where = calculer_liste($crit->param[0], $idb, $boucles, $boucle->id_parent);
1616
+    } else {
1617
+        $_where = 'spip_sanitize_from_request(@$Pile[0]["where"],"where","vide")';
1618
+    }
1619
+
1620
+    if ($crit->cond) {
1621
+        $_where = "((\$zzw = $_where) ? \$zzw : '')";
1622
+    }
1623
+
1624
+    if ($crit->not) {
1625
+        $_where = "array('NOT',$_where)";
1626
+    }
1627
+
1628
+    $boucle->where[] = $_where;
1629 1629
 }
1630 1630
 
1631 1631
 /**
@@ -1653,31 +1653,31 @@  discard block
 block discarded – undo
1653 1653
  * @return void
1654 1654
  */
1655 1655
 function critere_id__dist($idb, &$boucles, $crit) {
1656
-	/** @var Boucle $boucle */
1657
-	$boucle = $boucles[$idb];
1658
-
1659
-	$champs = lister_champs_id_conditionnel(
1660
-		$boucle->show['table'],
1661
-		$boucle->show,
1662
-		$boucle->sql_serveur
1663
-	);
1664
-
1665
-	// ne pas tenir compte des critères identiques déjà présents.
1666
-	if (!empty($boucle->modificateur['criteres'])) {
1667
-		$champs = array_diff($champs, array_keys($boucle->modificateur['criteres']));
1668
-	}
1669
-	// nous aider en mode debug.
1670
-	$boucle->debug[] = 'id_ : ' . implode(', ', $champs);
1671
-	$boucle->modificateur['id_'] = $champs;
1672
-
1673
-	// créer un critère {id_xxx?} de chaque champ retenu
1674
-	foreach ($champs as $champ) {
1675
-		$critere_id_table = new Critere();
1676
-		$critere_id_table->op = $champ;
1677
-		$critere_id_table->cond = true;
1678
-		$critere_id_table->ligne = $crit->ligne;
1679
-		calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table);
1680
-	}
1656
+    /** @var Boucle $boucle */
1657
+    $boucle = $boucles[$idb];
1658
+
1659
+    $champs = lister_champs_id_conditionnel(
1660
+        $boucle->show['table'],
1661
+        $boucle->show,
1662
+        $boucle->sql_serveur
1663
+    );
1664
+
1665
+    // ne pas tenir compte des critères identiques déjà présents.
1666
+    if (!empty($boucle->modificateur['criteres'])) {
1667
+        $champs = array_diff($champs, array_keys($boucle->modificateur['criteres']));
1668
+    }
1669
+    // nous aider en mode debug.
1670
+    $boucle->debug[] = 'id_ : ' . implode(', ', $champs);
1671
+    $boucle->modificateur['id_'] = $champs;
1672
+
1673
+    // créer un critère {id_xxx?} de chaque champ retenu
1674
+    foreach ($champs as $champ) {
1675
+        $critere_id_table = new Critere();
1676
+        $critere_id_table->op = $champ;
1677
+        $critere_id_table->cond = true;
1678
+        $critere_id_table->ligne = $crit->ligne;
1679
+        calculer_critere_DEFAUT_dist($idb, $boucles, $critere_id_table);
1680
+    }
1681 1681
 }
1682 1682
 
1683 1683
 /**
@@ -1697,74 +1697,74 @@  discard block
 block discarded – undo
1697 1697
  * @return array Liste de nom de champs (tel que id_article, id_mot, id_parent ...)
1698 1698
  */
1699 1699
 function lister_champs_id_conditionnel($table, $desc = null, $serveur = '') {
1700
-	// calculer la description de la table
1701
-	if (!is_array($desc)) {
1702
-		$desc = description_table($table, $serveur);
1703
-	}
1704
-	if (!$desc) {
1705
-		return [];
1706
-	}
1707
-
1708
-	// Les champs id_xx de la table demandée
1709
-	$champs = array_filter(
1710
-		array_keys($desc['field']),
1711
-		fn($champ) => str_starts_with($champ, 'id_') || $champ == 'objet'
1712
-	);
1713
-
1714
-	// Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute.
1715
-	if (
1716
-		in_array('id_rubrique', $champs)
1717
-		&& !in_array('id_secteur', $champs)
1718
-	) {
1719
-		$champs[] = 'id_secteur';
1720
-	}
1721
-
1722
-	// On ne fera pas mieux pour les tables d’un autre serveur
1723
-	if ($serveur) {
1724
-		return $champs;
1725
-	}
1726
-
1727
-	$primary = false;
1728
-	$associable = false;
1729
-	include_spip('action/editer_liens');
1730
-
1731
-	if (isset($desc['type'])) {
1732
-		$primary = id_table_objet($desc['type']);
1733
-		$associable = objet_associable($desc['type']);
1734
-	}
1735
-	if (isset($desc['field']['id_objet']) && isset($desc['field']['objet'])) {
1736
-		$associable = true;
1737
-	}
1738
-
1739
-	// liste de toutes les tables principales, sauf la notre
1740
-	$tables = lister_tables_objets_sql();
1741
-	unset($tables[$table]);
1742
-
1743
-	foreach ($tables as $_table => $_desc) {
1744
-		if (
1745
-			$associable
1746
-			|| $primary && array_key_exists($primary, $_desc['field'])
1747
-			|| objet_associable($_desc['type'])
1748
-		) {
1749
-			$champs[] = id_table_objet($_table);
1750
-		}
1751
-	}
1752
-	$champs = array_values(array_unique($champs));
1753
-
1754
-	// Exclusions de certains id
1755
-	$exclusions = pipeline(
1756
-		'exclure_id_conditionnel',
1757
-		[
1758
-			'args' => [
1759
-				'table' => $table,
1760
-				'id_table_objet' => $primary,
1761
-				'associable' => $associable,
1762
-			],
1763
-			'data' => [],
1764
-		]
1765
-	);
1766
-
1767
-	return array_diff($champs, $exclusions);
1700
+    // calculer la description de la table
1701
+    if (!is_array($desc)) {
1702
+        $desc = description_table($table, $serveur);
1703
+    }
1704
+    if (!$desc) {
1705
+        return [];
1706
+    }
1707
+
1708
+    // Les champs id_xx de la table demandée
1709
+    $champs = array_filter(
1710
+        array_keys($desc['field']),
1711
+        fn($champ) => str_starts_with($champ, 'id_') || $champ == 'objet'
1712
+    );
1713
+
1714
+    // Si le champ id_rubrique appartient à la liste et si id_secteur n'est pas inclus on le rajoute.
1715
+    if (
1716
+        in_array('id_rubrique', $champs)
1717
+        && !in_array('id_secteur', $champs)
1718
+    ) {
1719
+        $champs[] = 'id_secteur';
1720
+    }
1721
+
1722
+    // On ne fera pas mieux pour les tables d’un autre serveur
1723
+    if ($serveur) {
1724
+        return $champs;
1725
+    }
1726
+
1727
+    $primary = false;
1728
+    $associable = false;
1729
+    include_spip('action/editer_liens');
1730
+
1731
+    if (isset($desc['type'])) {
1732
+        $primary = id_table_objet($desc['type']);
1733
+        $associable = objet_associable($desc['type']);
1734
+    }
1735
+    if (isset($desc['field']['id_objet']) && isset($desc['field']['objet'])) {
1736
+        $associable = true;
1737
+    }
1738
+
1739
+    // liste de toutes les tables principales, sauf la notre
1740
+    $tables = lister_tables_objets_sql();
1741
+    unset($tables[$table]);
1742
+
1743
+    foreach ($tables as $_table => $_desc) {
1744
+        if (
1745
+            $associable
1746
+            || $primary && array_key_exists($primary, $_desc['field'])
1747
+            || objet_associable($_desc['type'])
1748
+        ) {
1749
+            $champs[] = id_table_objet($_table);
1750
+        }
1751
+    }
1752
+    $champs = array_values(array_unique($champs));
1753
+
1754
+    // Exclusions de certains id
1755
+    $exclusions = pipeline(
1756
+        'exclure_id_conditionnel',
1757
+        [
1758
+            'args' => [
1759
+                'table' => $table,
1760
+                'id_table_objet' => $primary,
1761
+                'associable' => $associable,
1762
+            ],
1763
+            'data' => [],
1764
+        ]
1765
+    );
1766
+
1767
+    return array_diff($champs, $exclusions);
1768 1768
 }
1769 1769
 
1770 1770
 /**
@@ -1819,31 +1819,31 @@  discard block
 block discarded – undo
1819 1819
  * @return void
1820 1820
  */
1821 1821
 function critere_tri_dist($idb, &$boucles, $crit) {
1822
-	$boucle = &$boucles[$idb];
1823
-
1824
-	// definition du champ par defaut
1825
-	$_champ_defaut = isset($crit->param[0][0])
1826
-		? calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent)
1827
-		: "''";
1828
-	$_liste_sens_defaut = isset($crit->param[1][0])
1829
-		? calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent)
1830
-		: '1';
1831
-	$_variable = isset($crit->param[2][0])
1832
-		? calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent)
1833
-		: "'$idb'";
1834
-
1835
-	$_tri = "((\$t=(isset(\$Pile[0]['tri'.$_variable]))?\$Pile[0]['tri'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('tri'.$_variable))?session_get('tri'.$_variable):$_champ_defaut))?tri_protege_champ(\$t):'')";
1836
-
1837
-	$_sens_defaut = "(is_array(\$s=$_liste_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)";
1838
-	$_sens = "((intval(\$t=(isset(\$Pile[0]['sens'.$_variable]))?\$Pile[0]['sens'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('sens'.$_variable))?session_get('sens'.$_variable):$_sens_defaut))==-1 OR \$t=='inverse')?-1:1)";
1839
-
1840
-	$boucle->modificateur['tri_champ'] = $_tri;
1841
-	$boucle->modificateur['tri_sens'] = $_sens;
1842
-	$boucle->modificateur['tri_liste_sens_defaut'] = $_liste_sens_defaut;
1843
-	$boucle->modificateur['tri_nom'] = $_variable;
1844
-	// faut il inserer un test sur l'existence de $tri parmi les champs de la table ?
1845
-	// evite des erreurs sql, mais peut empecher des tri sur jointure ...
1846
-	$boucle->hash .= "
1822
+    $boucle = &$boucles[$idb];
1823
+
1824
+    // definition du champ par defaut
1825
+    $_champ_defaut = isset($crit->param[0][0])
1826
+        ? calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent)
1827
+        : "''";
1828
+    $_liste_sens_defaut = isset($crit->param[1][0])
1829
+        ? calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent)
1830
+        : '1';
1831
+    $_variable = isset($crit->param[2][0])
1832
+        ? calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent)
1833
+        : "'$idb'";
1834
+
1835
+    $_tri = "((\$t=(isset(\$Pile[0]['tri'.$_variable]))?\$Pile[0]['tri'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('tri'.$_variable))?session_get('tri'.$_variable):$_champ_defaut))?tri_protege_champ(\$t):'')";
1836
+
1837
+    $_sens_defaut = "(is_array(\$s=$_liste_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)";
1838
+    $_sens = "((intval(\$t=(isset(\$Pile[0]['sens'.$_variable]))?\$Pile[0]['sens'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('sens'.$_variable))?session_get('sens'.$_variable):$_sens_defaut))==-1 OR \$t=='inverse')?-1:1)";
1839
+
1840
+    $boucle->modificateur['tri_champ'] = $_tri;
1841
+    $boucle->modificateur['tri_sens'] = $_sens;
1842
+    $boucle->modificateur['tri_liste_sens_defaut'] = $_liste_sens_defaut;
1843
+    $boucle->modificateur['tri_nom'] = $_variable;
1844
+    // faut il inserer un test sur l'existence de $tri parmi les champs de la table ?
1845
+    // evite des erreurs sql, mais peut empecher des tri sur jointure ...
1846
+    $boucle->hash .= "
1847 1847
 	\$senstri = '';
1848 1848
 	\$tri = $_tri;
1849 1849
 	if (\$tri){
@@ -1851,8 +1851,8 @@  discard block
 block discarded – undo
1851 1851
 		\$senstri = (\$senstri<0)?' DESC':'';
1852 1852
 	};
1853 1853
 	";
1854
-	$boucle->select[] = '".tri_champ_select($tri)."';
1855
-	$boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)";
1854
+    $boucle->select[] = '".tri_champ_select($tri)."';
1855
+    $boucle->order[] = "tri_champ_order(\$tri,\$command['from'],\$senstri)";
1856 1856
 }
1857 1857
 
1858 1858
 # criteres de comparaison
@@ -1869,21 +1869,21 @@  discard block
 block discarded – undo
1869 1869
  * @return void|array
1870 1870
  **/
1871 1871
 function calculer_critere_DEFAUT_dist($idb, &$boucles, $crit) {
1872
-	// double cas particulier {0,1} et {1/2} repere a l'analyse lexicale
1873
-	if ($crit->op == ',' || $crit->op == '/') {
1874
-		calculer_critere_parties($idb, $boucles, $crit);
1875
-		return;
1876
-	}
1877
-
1878
-	$r = calculer_critere_infixe($idb, $boucles, $crit);
1879
-	if (!$r) {
1880
-		#	// on produit une erreur seulement si le critere n'a pas de '?'
1881
-		#	if (!$crit->cond) {
1882
-		return ['zbug_critere_inconnu', ['critere' => $crit->op]];
1883
-		#	}
1884
-	} else {
1885
-		calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r);
1886
-	}
1872
+    // double cas particulier {0,1} et {1/2} repere a l'analyse lexicale
1873
+    if ($crit->op == ',' || $crit->op == '/') {
1874
+        calculer_critere_parties($idb, $boucles, $crit);
1875
+        return;
1876
+    }
1877
+
1878
+    $r = calculer_critere_infixe($idb, $boucles, $crit);
1879
+    if (!$r) {
1880
+        #	// on produit une erreur seulement si le critere n'a pas de '?'
1881
+        #	if (!$crit->cond) {
1882
+        return ['zbug_critere_inconnu', ['critere' => $crit->op]];
1883
+        #	}
1884
+    } else {
1885
+        calculer_critere_DEFAUT_args($idb, $boucles, $crit, $r);
1886
+    }
1887 1887
 }
1888 1888
 
1889 1889
 
@@ -1903,60 +1903,60 @@  discard block
 block discarded – undo
1903 1903
  * @return void
1904 1904
  **/
1905 1905
 function calculer_critere_DEFAUT_args($idb, &$boucles, $crit, $args) {
1906
-	[$arg, $op, $val, $col, $where_complement] = $args;
1907
-
1908
-	$where = ["'$op'", "'$arg'", $val[0]];
1909
-
1910
-	// inserer la negation (cf !...)
1911
-
1912
-	if ($crit->not) {
1913
-		$where = ["'NOT'", $where];
1914
-	}
1915
-	if ($crit->exclus) {
1916
-		if (!preg_match(',^L\d+[.],', $arg)) {
1917
-			$where = ["'NOT'", $where];
1918
-		} else {
1919
-			// un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1920
-			// c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1921
-			$where = [
1922
-				"'NOT'",
1923
-				[
1924
-					"'IN'",
1925
-					"'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1926
-					["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1927
-				]
1928
-			];
1929
-		}
1930
-	}
1931
-
1932
-	// inserer la condition (cf {lang?})
1933
-	// traiter a part la date, elle est mise d'office par SPIP,
1934
-	if ($crit->cond) {
1935
-		$pred = calculer_argument_precedent($idb, $col, $boucles);
1936
-		if (($col === 'date' || $col === 'date_redac') && $pred === "\$Pile[0]['" . $col . "']") {
1937
-			$pred = "(\$Pile[0]['{$col}_default']?'':$pred)";
1938
-		}
1939
-
1940
-		if ($op === '=' && !$crit->not) {
1941
-			$where = [
1942
-				"'?'",
1943
-				"(is_array($pred))",
1944
-				critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col),
1945
-				$where
1946
-			];
1947
-		}
1948
-		$where = ["'?'", "!is_whereable($pred)", "''", $where];
1949
-		if ($where_complement) {
1950
-			// condition annexe du type "AND (objet='article')"
1951
-			$where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement];
1952
-		}
1953
-	}
1954
-
1955
-	$boucles[$idb]->where[] = $where;
1956
-	if ($where_complement) {
1957
-		// condition annexe du type "AND (objet='article')"
1958
-		$boucles[$idb]->where[] = $where_complement;
1959
-	}
1906
+    [$arg, $op, $val, $col, $where_complement] = $args;
1907
+
1908
+    $where = ["'$op'", "'$arg'", $val[0]];
1909
+
1910
+    // inserer la negation (cf !...)
1911
+
1912
+    if ($crit->not) {
1913
+        $where = ["'NOT'", $where];
1914
+    }
1915
+    if ($crit->exclus) {
1916
+        if (!preg_match(',^L\d+[.],', $arg)) {
1917
+            $where = ["'NOT'", $where];
1918
+        } else {
1919
+            // un not sur un critere de jointure se traduit comme un NOT IN avec une sous requete
1920
+            // c'est une sous requete identique a la requete principale sous la forme (SELF,$select,$where) avec $select et $where qui surchargent
1921
+            $where = [
1922
+                "'NOT'",
1923
+                [
1924
+                    "'IN'",
1925
+                    "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'",
1926
+                    ["'SELF'", "'" . $boucles[$idb]->id_table . '.' . $boucles[$idb]->primary . "'", $where]
1927
+                ]
1928
+            ];
1929
+        }
1930
+    }
1931
+
1932
+    // inserer la condition (cf {lang?})
1933
+    // traiter a part la date, elle est mise d'office par SPIP,
1934
+    if ($crit->cond) {
1935
+        $pred = calculer_argument_precedent($idb, $col, $boucles);
1936
+        if (($col === 'date' || $col === 'date_redac') && $pred === "\$Pile[0]['" . $col . "']") {
1937
+            $pred = "(\$Pile[0]['{$col}_default']?'':$pred)";
1938
+        }
1939
+
1940
+        if ($op === '=' && !$crit->not) {
1941
+            $where = [
1942
+                "'?'",
1943
+                "(is_array($pred))",
1944
+                critere_IN_cas($idb, $boucles, 'COND', $arg, $op, [$pred], $col),
1945
+                $where
1946
+            ];
1947
+        }
1948
+        $where = ["'?'", "!is_whereable($pred)", "''", $where];
1949
+        if ($where_complement) {
1950
+            // condition annexe du type "AND (objet='article')"
1951
+            $where_complement = ["'?'", "!is_whereable($pred)", "''", $where_complement];
1952
+        }
1953
+    }
1954
+
1955
+    $boucles[$idb]->where[] = $where;
1956
+    if ($where_complement) {
1957
+        // condition annexe du type "AND (objet='article')"
1958
+        $boucles[$idb]->where[] = $where_complement;
1959
+    }
1960 1960
 }
1961 1961
 
1962 1962
 
@@ -1997,160 +1997,160 @@  discard block
 block discarded – undo
1997 1997
  **/
1998 1998
 function calculer_critere_infixe($idb, &$boucles, $crit) {
1999 1999
 
2000
-	$boucle = &$boucles[$idb];
2001
-	$type = $boucle->type_requete;
2002
-	$table = $boucle->id_table;
2003
-	$desc = $boucle->show;
2004
-	$col_vraie = null;
2005
-
2006
-	[$fct, $col, $op, $val, $args_sql] =
2007
-		calculer_critere_infixe_ops($idb, $boucles, $crit);
2008
-
2009
-	$col_alias = $col;
2010
-	$where_complement = false;
2011
-
2012
-	// Cas particulier : id_enfant => utiliser la colonne id_objet
2013
-	if ($col == 'id_enfant') {
2014
-		$col = $boucle->primary;
2015
-	}
2016
-
2017
-	// Cas particulier : id_parent => verifier les exceptions de tables
2018
-	if (
2019
-		in_array($col, ['id_parent', 'id_secteur'])
2020
-		&& isset($GLOBALS['exceptions_des_tables'][$table][$col]) || isset($GLOBALS['exceptions_des_tables'][$table][$col]) && is_string($GLOBALS['exceptions_des_tables'][$table][$col])
2021
-	) {
2022
-		$col = $GLOBALS['exceptions_des_tables'][$table][$col];
2023
-	} // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums)
2024
-	else {
2025
-		if ($col == 'id_secteur' && ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) {
2026
-			$table = $critere_secteur($idb, $boucles, $val, $crit);
2027
-		}
2028
-
2029
-		// cas id_article=xx qui se mappe en id_objet=xx AND objet=article
2030
-		// sauf si exception declaree : sauter cette etape
2031
-		else {
2032
-			if (
2033
-				!isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col])
2034
-				&& !isset($GLOBALS['exceptions_des_jointures'][$col])
2035
-				&& count(trouver_champs_decomposes($col, $desc)) > 1
2036
-			) {
2037
-				$e = decompose_champ_id_objet($col);
2038
-				$col = array_shift($e);
2039
-				$where_complement = primary_doublee($e, $table);
2040
-			} // Cas particulier : expressions de date
2041
-			else {
2042
-				if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) {
2043
-					[$col, $col_vraie] = $c;
2044
-					$table = '';
2045
-				} // table explicitée {mots.titre}
2046
-				else {
2047
-					if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2048
-						[, $table, $col] = $r;
2049
-						$col_alias = $col;
2050
-
2051
-						$trouver_table = charger_fonction('trouver_table', 'base');
2052
-						if (
2053
-							($desc = $trouver_table($table, $boucle->sql_serveur))
2054
-							&& isset($desc['field'][$col])
2055
-							&& ($cle = array_search($desc['table'], $boucle->from))
2056
-						) {
2057
-							$table = $cle;
2058
-						} else {
2059
-							$table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond || $op != '='));
2060
-						}
2061
-						#$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true);
2062
-						if (!$table) {
2063
-							return '';
2064
-						}
2065
-					}
2066
-					// si le champ n'est pas trouvé dans la table,
2067
-					// on cherche si une jointure peut l'obtenir
2068
-					elseif (@!array_key_exists($col, $desc['field'])) {
2069
-						// Champ joker * des iterateurs DATA qui accepte tout
2070
-						if (@array_key_exists('*', $desc['field'])) {
2071
-							$desc['field'][$col_vraie ?: $col] = ''; // on veut pas de cast INT par defaut car le type peut etre n'importe quoi dans les boucles DATA
2072
-						}
2073
-						else {
2074
-							$r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table);
2075
-							if (!$r) {
2076
-								return '';
2077
-							}
2078
-							[$col, $col_alias, $table, $where_complement, $desc] = $r;
2079
-						}
2080
-					}
2081
-				}
2082
-			}
2083
-		}
2084
-	}
2085
-
2086
-	$col_vraie = ($col_vraie ?: $col);
2087
-	// Dans tous les cas,
2088
-	// virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL)
2089
-	// et passer dans sql_quote avec le type si connu
2090
-	// et int sinon si la valeur est numerique
2091
-	// sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon)
2092
-	// Ne pas utiliser intval, PHP tronquant les Bigint de SQL
2093
-	if ($op == '=' || in_array($op, $GLOBALS['table_criteres_infixes'])) {
2094
-		$type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL');
2095
-		// defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon
2096
-		// prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut
2097
-		if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", $val[0], $r)) {
2098
-			$val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"';
2099
-		}
2100
-		// sinon expliciter les
2101
-		// sql_quote(truc) en sql_quote(truc,'',type)
2102
-		// sql_quote(truc,serveur) en sql_quote(truc,serveur,type)
2103
-		// sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type)
2104
-		// sans toucher aux
2105
-		// sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE')
2106
-		// sql_quote(truc,'','varchar')
2107
-		elseif (
2108
-			preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', $val[0], $r)
2109
-			&& (!isset($r[3]) || !$r[3] || !trim($r[3], ", '"))
2110
-		) {
2111
-			$r = $r[1]
2112
-				. ((isset($r[2]) && $r[2]) ? $r[2] : ",''")
2113
-				. ",'" . addslashes($type_cast_quote) . "'";
2114
-			$val[0] = "sql_quote($r)";
2115
-		}
2116
-		elseif (
2117
-			str_contains($val[0], '@@defaultcast@@')
2118
-			&& preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2119
-		) {
2120
-			$val[0] = substr($val[0], 0, -strlen($r[0])) . "'" . addslashes($type_cast_quote) . "')";
2121
-		}
2122
-	}
2123
-
2124
-	if (
2125
-		str_contains($val[0], '@@defaultcast@@')
2126
-		&& preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2127
-	) {
2128
-		$val[0] = substr($val[0], 0, -strlen($r[0])) . "'char')";
2129
-	}
2130
-
2131
-	// Indicateur pour permettre aux fonctionx boucle_X de modifier
2132
-	// leurs requetes par defaut, notamment le champ statut
2133
-	// Ne pas confondre champs de la table principale et des jointures
2134
-	if ($table === $boucle->id_table) {
2135
-		$boucles[$idb]->modificateur['criteres'][$col_vraie] = true;
2136
-		if ($col_alias != $col_vraie) {
2137
-			$boucles[$idb]->modificateur['criteres'][$col_alias] = true;
2138
-		}
2139
-	}
2140
-
2141
-	// inserer le nom de la table SQL devant le nom du champ
2142
-	if ($table) {
2143
-		$arg = $col[0] == '`' ? "$table." . substr($col, 1, -1) : "$table.$col";
2144
-	} else {
2145
-		$arg = $col;
2146
-	}
2147
-
2148
-	// inserer la fonction SQL
2149
-	if ($fct) {
2150
-		$arg = "$fct($arg$args_sql)";
2151
-	}
2152
-
2153
-	return [$arg, $op, $val, $col_alias, $where_complement];
2000
+    $boucle = &$boucles[$idb];
2001
+    $type = $boucle->type_requete;
2002
+    $table = $boucle->id_table;
2003
+    $desc = $boucle->show;
2004
+    $col_vraie = null;
2005
+
2006
+    [$fct, $col, $op, $val, $args_sql] =
2007
+        calculer_critere_infixe_ops($idb, $boucles, $crit);
2008
+
2009
+    $col_alias = $col;
2010
+    $where_complement = false;
2011
+
2012
+    // Cas particulier : id_enfant => utiliser la colonne id_objet
2013
+    if ($col == 'id_enfant') {
2014
+        $col = $boucle->primary;
2015
+    }
2016
+
2017
+    // Cas particulier : id_parent => verifier les exceptions de tables
2018
+    if (
2019
+        in_array($col, ['id_parent', 'id_secteur'])
2020
+        && isset($GLOBALS['exceptions_des_tables'][$table][$col]) || isset($GLOBALS['exceptions_des_tables'][$table][$col]) && is_string($GLOBALS['exceptions_des_tables'][$table][$col])
2021
+    ) {
2022
+        $col = $GLOBALS['exceptions_des_tables'][$table][$col];
2023
+    } // et possibilite de gerer un critere secteur sur des tables de plugins (ie forums)
2024
+    else {
2025
+        if ($col == 'id_secteur' && ($critere_secteur = charger_fonction("critere_secteur_$type", 'public', true))) {
2026
+            $table = $critere_secteur($idb, $boucles, $val, $crit);
2027
+        }
2028
+
2029
+        // cas id_article=xx qui se mappe en id_objet=xx AND objet=article
2030
+        // sauf si exception declaree : sauter cette etape
2031
+        else {
2032
+            if (
2033
+                !isset($GLOBALS['exceptions_des_jointures'][table_objet_sql($table)][$col])
2034
+                && !isset($GLOBALS['exceptions_des_jointures'][$col])
2035
+                && count(trouver_champs_decomposes($col, $desc)) > 1
2036
+            ) {
2037
+                $e = decompose_champ_id_objet($col);
2038
+                $col = array_shift($e);
2039
+                $where_complement = primary_doublee($e, $table);
2040
+            } // Cas particulier : expressions de date
2041
+            else {
2042
+                if ($c = calculer_critere_infixe_date($idb, $boucles, $col)) {
2043
+                    [$col, $col_vraie] = $c;
2044
+                    $table = '';
2045
+                } // table explicitée {mots.titre}
2046
+                else {
2047
+                    if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2048
+                        [, $table, $col] = $r;
2049
+                        $col_alias = $col;
2050
+
2051
+                        $trouver_table = charger_fonction('trouver_table', 'base');
2052
+                        if (
2053
+                            ($desc = $trouver_table($table, $boucle->sql_serveur))
2054
+                            && isset($desc['field'][$col])
2055
+                            && ($cle = array_search($desc['table'], $boucle->from))
2056
+                        ) {
2057
+                            $table = $cle;
2058
+                        } else {
2059
+                            $table = trouver_jointure_champ($col, $boucle, [$table], ($crit->cond || $op != '='));
2060
+                        }
2061
+                        #$table = calculer_critere_externe_init($boucle, array($table), $col, $desc, ($crit->cond OR $op!='='), true);
2062
+                        if (!$table) {
2063
+                            return '';
2064
+                        }
2065
+                    }
2066
+                    // si le champ n'est pas trouvé dans la table,
2067
+                    // on cherche si une jointure peut l'obtenir
2068
+                    elseif (@!array_key_exists($col, $desc['field'])) {
2069
+                        // Champ joker * des iterateurs DATA qui accepte tout
2070
+                        if (@array_key_exists('*', $desc['field'])) {
2071
+                            $desc['field'][$col_vraie ?: $col] = ''; // on veut pas de cast INT par defaut car le type peut etre n'importe quoi dans les boucles DATA
2072
+                        }
2073
+                        else {
2074
+                            $r = calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table);
2075
+                            if (!$r) {
2076
+                                return '';
2077
+                            }
2078
+                            [$col, $col_alias, $table, $where_complement, $desc] = $r;
2079
+                        }
2080
+                    }
2081
+                }
2082
+            }
2083
+        }
2084
+    }
2085
+
2086
+    $col_vraie = ($col_vraie ?: $col);
2087
+    // Dans tous les cas,
2088
+    // virer les guillemets eventuels autour d'un int (qui sont refuses par certains SQL)
2089
+    // et passer dans sql_quote avec le type si connu
2090
+    // et int sinon si la valeur est numerique
2091
+    // sinon introduire le vrai type du champ si connu dans le sql_quote (ou int NOT NULL sinon)
2092
+    // Ne pas utiliser intval, PHP tronquant les Bigint de SQL
2093
+    if ($op == '=' || in_array($op, $GLOBALS['table_criteres_infixes'])) {
2094
+        $type_cast_quote = ($desc['field'][$col_vraie] ?? 'int NOT NULL');
2095
+        // defaire le quote des int et les passer dans sql_quote avec le bon type de champ si on le connait, int sinon
2096
+        // prendre en compte le debug ou la valeur arrive avec un commentaire PHP en debut
2097
+        if (preg_match(",^\\A(\s*//.*?$\s*)?\"'(-?\d+)'\"\\z,ms", $val[0], $r)) {
2098
+            $val[0] = $r[1] . '"' . sql_quote($r[2], $boucle->sql_serveur, $type_cast_quote) . '"';
2099
+        }
2100
+        // sinon expliciter les
2101
+        // sql_quote(truc) en sql_quote(truc,'',type)
2102
+        // sql_quote(truc,serveur) en sql_quote(truc,serveur,type)
2103
+        // sql_quote(truc,serveur,'') en sql_quote(truc,serveur,type)
2104
+        // sans toucher aux
2105
+        // sql_quote(truc,'','varchar(10) DEFAULT \'oui\' COLLATE NOCASE')
2106
+        // sql_quote(truc,'','varchar')
2107
+        elseif (
2108
+            preg_match('/\Asql_quote[(](.*?)(,[^)]*?)?(,[^)]*(?:\(\d+\)[^)]*)?)?[)]\s*\z/ms', $val[0], $r)
2109
+            && (!isset($r[3]) || !$r[3] || !trim($r[3], ", '"))
2110
+        ) {
2111
+            $r = $r[1]
2112
+                . ((isset($r[2]) && $r[2]) ? $r[2] : ",''")
2113
+                . ",'" . addslashes($type_cast_quote) . "'";
2114
+            $val[0] = "sql_quote($r)";
2115
+        }
2116
+        elseif (
2117
+            str_contains($val[0], '@@defaultcast@@')
2118
+            && preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2119
+        ) {
2120
+            $val[0] = substr($val[0], 0, -strlen($r[0])) . "'" . addslashes($type_cast_quote) . "')";
2121
+        }
2122
+    }
2123
+
2124
+    if (
2125
+        str_contains($val[0], '@@defaultcast@@')
2126
+        && preg_match("/'@@defaultcast@@'\s*\)\s*\z/ms", $val[0], $r)
2127
+    ) {
2128
+        $val[0] = substr($val[0], 0, -strlen($r[0])) . "'char')";
2129
+    }
2130
+
2131
+    // Indicateur pour permettre aux fonctionx boucle_X de modifier
2132
+    // leurs requetes par defaut, notamment le champ statut
2133
+    // Ne pas confondre champs de la table principale et des jointures
2134
+    if ($table === $boucle->id_table) {
2135
+        $boucles[$idb]->modificateur['criteres'][$col_vraie] = true;
2136
+        if ($col_alias != $col_vraie) {
2137
+            $boucles[$idb]->modificateur['criteres'][$col_alias] = true;
2138
+        }
2139
+    }
2140
+
2141
+    // inserer le nom de la table SQL devant le nom du champ
2142
+    if ($table) {
2143
+        $arg = $col[0] == '`' ? "$table." . substr($col, 1, -1) : "$table.$col";
2144
+    } else {
2145
+        $arg = $col;
2146
+    }
2147
+
2148
+    // inserer la fonction SQL
2149
+    if ($fct) {
2150
+        $arg = "$fct($arg$args_sql)";
2151
+    }
2152
+
2153
+    return [$arg, $op, $val, $col_alias, $where_complement];
2154 2154
 }
2155 2155
 
2156 2156
 
@@ -2179,75 +2179,75 @@  discard block
 block discarded – undo
2179 2179
  **/
2180 2180
 function calculer_critere_infixe_externe($boucle, $crit, $op, $desc, $col, $col_alias, $table) {
2181 2181
 
2182
-	$where = '';
2183
-
2184
-	$calculer_critere_externe = 'calculer_critere_externe_init';
2185
-	// gestion par les plugins des jointures tordues
2186
-	// pas automatiques mais necessaires
2187
-	$table_sql = table_objet_sql($table);
2188
-	if (
2189
-		isset($GLOBALS['exceptions_des_jointures'][$table_sql])
2190
-		&& is_array($GLOBALS['exceptions_des_jointures'][$table_sql])
2191
-		&& (
2192
-			isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col])
2193
-			|| isset($GLOBALS['exceptions_des_jointures'][$table_sql][''])
2194
-		)
2195
-	) {
2196
-		$t = $GLOBALS['exceptions_des_jointures'][$table_sql];
2197
-		$index = $t[$col] ?? $t[''] ?? [];
2198
-
2199
-		if ((is_countable($index) ? count($index) : 0) == 3) {
2200
-			[$t, $col, $calculer_critere_externe] = $index;
2201
-		} elseif ((is_countable($index) ? count($index) : 0) == 2) {
2202
-			[$t, $col] = $t[$col];
2203
-		} elseif ((is_countable($index) ? count($index) : 0) == 1) {
2204
-			[$calculer_critere_externe] = $index;
2205
-			$t = $table;
2206
-		} else {
2207
-			$t = '';
2208
-		} // jointure non declaree. La trouver.
2209
-	} elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) {
2210
-		[$t, $col] = $GLOBALS['exceptions_des_jointures'][$col];
2211
-	} else {
2212
-		$t = '';
2213
-	} // jointure non declaree. La trouver.
2214
-
2215
-	// ici on construit le from pour fournir $col en piochant dans les jointures
2216
-
2217
-	// si des jointures explicites sont fournies, on cherche d'abord dans celles ci
2218
-	// permet de forcer une table de lien quand il y a ambiguite
2219
-	// <BOUCLE_(DOCUMENTS documents_liens){id_mot}>
2220
-	// alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}>
2221
-	$table = '';
2222
-	if ($boucle->jointures_explicites) {
2223
-		$jointures_explicites = explode(' ', $boucle->jointures_explicites);
2224
-		$table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond || $op != '='), $t);
2225
-	}
2226
-
2227
-	// et sinon on cherche parmi toutes les jointures declarees
2228
-	if (!$table) {
2229
-		$table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond || $op != '='), $t);
2230
-	}
2231
-
2232
-	if (!$table) {
2233
-		return '';
2234
-	}
2235
-
2236
-	// il ne reste plus qu'a trouver le champ dans les from
2237
-	[$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle);
2238
-
2239
-	if ((is_countable($cle) ? count($cle) : 0) > 1 || reset($cle) !== $col) {
2240
-		$col_alias = $col; // id_article devient juste le nom d'origine
2241
-		if ((is_countable($cle) ? count($cle) : 0) > 1 && reset($cle) == 'id_objet') {
2242
-			$e = decompose_champ_id_objet($col);
2243
-			$col = array_shift($e);
2244
-			$where = primary_doublee($e, $table);
2245
-		} else {
2246
-			$col = reset($cle);
2247
-		}
2248
-	}
2249
-
2250
-	return [$col, $col_alias, $table, $where, $desc];
2182
+    $where = '';
2183
+
2184
+    $calculer_critere_externe = 'calculer_critere_externe_init';
2185
+    // gestion par les plugins des jointures tordues
2186
+    // pas automatiques mais necessaires
2187
+    $table_sql = table_objet_sql($table);
2188
+    if (
2189
+        isset($GLOBALS['exceptions_des_jointures'][$table_sql])
2190
+        && is_array($GLOBALS['exceptions_des_jointures'][$table_sql])
2191
+        && (
2192
+            isset($GLOBALS['exceptions_des_jointures'][$table_sql][$col])
2193
+            || isset($GLOBALS['exceptions_des_jointures'][$table_sql][''])
2194
+        )
2195
+    ) {
2196
+        $t = $GLOBALS['exceptions_des_jointures'][$table_sql];
2197
+        $index = $t[$col] ?? $t[''] ?? [];
2198
+
2199
+        if ((is_countable($index) ? count($index) : 0) == 3) {
2200
+            [$t, $col, $calculer_critere_externe] = $index;
2201
+        } elseif ((is_countable($index) ? count($index) : 0) == 2) {
2202
+            [$t, $col] = $t[$col];
2203
+        } elseif ((is_countable($index) ? count($index) : 0) == 1) {
2204
+            [$calculer_critere_externe] = $index;
2205
+            $t = $table;
2206
+        } else {
2207
+            $t = '';
2208
+        } // jointure non declaree. La trouver.
2209
+    } elseif (isset($GLOBALS['exceptions_des_jointures'][$col])) {
2210
+        [$t, $col] = $GLOBALS['exceptions_des_jointures'][$col];
2211
+    } else {
2212
+        $t = '';
2213
+    } // jointure non declaree. La trouver.
2214
+
2215
+    // ici on construit le from pour fournir $col en piochant dans les jointures
2216
+
2217
+    // si des jointures explicites sont fournies, on cherche d'abord dans celles ci
2218
+    // permet de forcer une table de lien quand il y a ambiguite
2219
+    // <BOUCLE_(DOCUMENTS documents_liens){id_mot}>
2220
+    // alors que <BOUCLE_(DOCUMENTS){id_mot}> produit la meme chose que <BOUCLE_(DOCUMENTS mots_liens){id_mot}>
2221
+    $table = '';
2222
+    if ($boucle->jointures_explicites) {
2223
+        $jointures_explicites = explode(' ', $boucle->jointures_explicites);
2224
+        $table = $calculer_critere_externe($boucle, $jointures_explicites, $col, $desc, ($crit->cond || $op != '='), $t);
2225
+    }
2226
+
2227
+    // et sinon on cherche parmi toutes les jointures declarees
2228
+    if (!$table) {
2229
+        $table = $calculer_critere_externe($boucle, $boucle->jointures, $col, $desc, ($crit->cond || $op != '='), $t);
2230
+    }
2231
+
2232
+    if (!$table) {
2233
+        return '';
2234
+    }
2235
+
2236
+    // il ne reste plus qu'a trouver le champ dans les from
2237
+    [$nom, $desc, $cle] = trouver_champ_exterieur($col, $boucle->from, $boucle);
2238
+
2239
+    if ((is_countable($cle) ? count($cle) : 0) > 1 || reset($cle) !== $col) {
2240
+        $col_alias = $col; // id_article devient juste le nom d'origine
2241
+        if ((is_countable($cle) ? count($cle) : 0) > 1 && reset($cle) == 'id_objet') {
2242
+            $e = decompose_champ_id_objet($col);
2243
+            $col = array_shift($e);
2244
+            $where = primary_doublee($e, $table);
2245
+        } else {
2246
+            $col = reset($cle);
2247
+        }
2248
+    }
2249
+
2250
+    return [$col, $col_alias, $table, $where, $desc];
2251 2251
 }
2252 2252
 
2253 2253
 
@@ -2268,10 +2268,10 @@  discard block
 block discarded – undo
2268 2268
  *     - valeur
2269 2269
  **/
2270 2270
 function primary_doublee($decompose, $table) {
2271
-	$e1 = reset($decompose);
2272
-	$e2 = "sql_quote('" . end($decompose) . "')";
2271
+    $e1 = reset($decompose);
2272
+    $e2 = "sql_quote('" . end($decompose) . "')";
2273 2273
 
2274
-	return ["'='", "'$table." . $e1 . "'", $e2];
2274
+    return ["'='", "'$table." . $e1 . "'", $e2];
2275 2275
 }
2276 2276
 
2277 2277
 /**
@@ -2302,56 +2302,56 @@  discard block
 block discarded – undo
2302 2302
  *     Vide sinon.
2303 2303
  */
2304 2304
 function calculer_critere_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) {
2305
-	// si on demande un truc du genre spip_mots
2306
-	// avec aussi spip_mots_liens dans les jointures dispo
2307
-	// et qu'on est la
2308
-	// il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots
2309
-	if (
2310
-		$checkarrivee
2311
-		&& is_string($checkarrivee)
2312
-		&& ($a = table_objet($checkarrivee))
2313
-		&& in_array($a . '_liens', $joints)
2314
-		&& ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee))
2315
-	) {
2316
-		return $res;
2317
-	}
2318
-	foreach ($joints as $joint) {
2319
-		if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) {
2320
-			// alias de table dans le from
2321
-			$t = array_search($arrivee[0], $boucle->from);
2322
-			// recuperer la cle id_xx eventuellement decomposee en (id_objet,objet)
2323
-			$cols = $arrivee[2];
2324
-			// mais on ignore la 3eme cle si presente qui correspond alors au point de depart
2325
-			if ((is_countable($cols) ? count($cols) : 0) > 2) {
2326
-				array_pop($cols);
2327
-			}
2328
-			if ($t) {
2329
-				// la table est déjà dans le FROM, on vérifie si le champ est utilisé.
2330
-				$joindre = false;
2331
-				foreach ($cols as $col) {
2332
-					$c = '/\b' . $t . ".$col" . '\b/';
2333
-					if (trouver_champ($c, $boucle->where)) {
2334
-						$joindre = true;
2335
-					} else {
2336
-						// mais ca peut etre dans le FIELD pour le Having
2337
-						$c = "/FIELD.$t" . ".$col,/";
2338
-						if (trouver_champ($c, $boucle->select)) {
2339
-							$joindre = true;
2340
-						}
2341
-					}
2342
-				}
2343
-				if (!$joindre) {
2344
-					return $t;
2345
-				}
2346
-			}
2347
-			array_pop($arrivee);
2348
-			if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) {
2349
-				return $res;
2350
-			}
2351
-		}
2352
-	}
2353
-
2354
-	return '';
2305
+    // si on demande un truc du genre spip_mots
2306
+    // avec aussi spip_mots_liens dans les jointures dispo
2307
+    // et qu'on est la
2308
+    // il faut privilegier la jointure directe en 2 etapes spip_mots_liens, spip_mots
2309
+    if (
2310
+        $checkarrivee
2311
+        && is_string($checkarrivee)
2312
+        && ($a = table_objet($checkarrivee))
2313
+        && in_array($a . '_liens', $joints)
2314
+        && ($res = calculer_lien_externe_init($boucle, $joints, $col, $desc, $cond, $checkarrivee))
2315
+    ) {
2316
+        return $res;
2317
+    }
2318
+    foreach ($joints as $joint) {
2319
+        if ($arrivee = trouver_champ_exterieur($col, [$joint], $boucle, $checkarrivee)) {
2320
+            // alias de table dans le from
2321
+            $t = array_search($arrivee[0], $boucle->from);
2322
+            // recuperer la cle id_xx eventuellement decomposee en (id_objet,objet)
2323
+            $cols = $arrivee[2];
2324
+            // mais on ignore la 3eme cle si presente qui correspond alors au point de depart
2325
+            if ((is_countable($cols) ? count($cols) : 0) > 2) {
2326
+                array_pop($cols);
2327
+            }
2328
+            if ($t) {
2329
+                // la table est déjà dans le FROM, on vérifie si le champ est utilisé.
2330
+                $joindre = false;
2331
+                foreach ($cols as $col) {
2332
+                    $c = '/\b' . $t . ".$col" . '\b/';
2333
+                    if (trouver_champ($c, $boucle->where)) {
2334
+                        $joindre = true;
2335
+                    } else {
2336
+                        // mais ca peut etre dans le FIELD pour le Having
2337
+                        $c = "/FIELD.$t" . ".$col,/";
2338
+                        if (trouver_champ($c, $boucle->select)) {
2339
+                            $joindre = true;
2340
+                        }
2341
+                    }
2342
+                }
2343
+                if (!$joindre) {
2344
+                    return $t;
2345
+                }
2346
+            }
2347
+            array_pop($arrivee);
2348
+            if ($res = calculer_jointure($boucle, [$boucle->id_table, $desc], $arrivee, $cols, $cond, 1)) {
2349
+                return $res;
2350
+            }
2351
+        }
2352
+    }
2353
+
2354
+    return '';
2355 2355
 }
2356 2356
 
2357 2357
 /**
@@ -2377,35 +2377,35 @@  discard block
 block discarded – undo
2377 2377
  *     Alias de la table de jointure (Lx)
2378 2378
  */
2379 2379
 function calculer_lien_externe_init(&$boucle, $joints, $col, $desc, $cond, $checkarrivee = false) {
2380
-	$primary_arrivee = id_table_objet($checkarrivee);
2381
-
2382
-	// [FIXME] $checkarrivee peut-il arriver avec false ????
2383
-	$intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens');
2384
-	$arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee);
2385
-
2386
-	if (!$intermediaire || !$arrivee) {
2387
-		return '';
2388
-	}
2389
-	array_pop($intermediaire); // enlever la cle en 3eme argument
2390
-	array_pop($arrivee); // enlever la cle en 3eme argument
2391
-
2392
-	$res = fabrique_jointures(
2393
-		$boucle,
2394
-		[
2395
-			[
2396
-				$boucle->id_table,
2397
-				$intermediaire,
2398
-				[id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']]
2399
-			],
2400
-			[reset($intermediaire), $arrivee, $primary_arrivee]
2401
-		],
2402
-		$cond,
2403
-		$desc,
2404
-		$boucle->id_table,
2405
-		[$col]
2406
-	);
2407
-
2408
-	return $res;
2380
+    $primary_arrivee = id_table_objet($checkarrivee);
2381
+
2382
+    // [FIXME] $checkarrivee peut-il arriver avec false ????
2383
+    $intermediaire = trouver_champ_exterieur($primary_arrivee, $joints, $boucle, $checkarrivee . '_liens');
2384
+    $arrivee = trouver_champ_exterieur($col, $joints, $boucle, $checkarrivee);
2385
+
2386
+    if (!$intermediaire || !$arrivee) {
2387
+        return '';
2388
+    }
2389
+    array_pop($intermediaire); // enlever la cle en 3eme argument
2390
+    array_pop($arrivee); // enlever la cle en 3eme argument
2391
+
2392
+    $res = fabrique_jointures(
2393
+        $boucle,
2394
+        [
2395
+            [
2396
+                $boucle->id_table,
2397
+                $intermediaire,
2398
+                [id_table_objet($desc['table_objet']), 'id_objet', 'objet', $desc['type']]
2399
+            ],
2400
+            [reset($intermediaire), $arrivee, $primary_arrivee]
2401
+        ],
2402
+        $cond,
2403
+        $desc,
2404
+        $boucle->id_table,
2405
+        [$col]
2406
+    );
2407
+
2408
+    return $res;
2409 2409
 }
2410 2410
 
2411 2411
 
@@ -2422,17 +2422,17 @@  discard block
 block discarded – undo
2422 2422
  *     false sinon.
2423 2423
  **/
2424 2424
 function trouver_champ($champ, $where) {
2425
-	if (!is_array($where)) {
2426
-		return preg_match($champ, $where);
2427
-	} else {
2428
-		foreach ($where as $clause) {
2429
-			if (trouver_champ($champ, $clause)) {
2430
-				return true;
2431
-			}
2432
-		}
2433
-
2434
-		return false;
2435
-	}
2425
+    if (!is_array($where)) {
2426
+        return preg_match($champ, $where);
2427
+    } else {
2428
+        foreach ($where as $clause) {
2429
+            if (trouver_champ($champ, $clause)) {
2430
+                return true;
2431
+            }
2432
+        }
2433
+
2434
+        return false;
2435
+    }
2436 2436
 }
2437 2437
 
2438 2438
 
@@ -2458,128 +2458,128 @@  discard block
 block discarded – undo
2458 2458
  *     - string $args_sql  Suite des arguments du critère. ?
2459 2459
  **/
2460 2460
 function calculer_critere_infixe_ops($idb, &$boucles, $crit) {
2461
-	// cas d'une valeur comparee a elle-meme ou son referent
2462
-	if ((is_countable($crit->param) ? count($crit->param) : 0) == 0) {
2463
-		$op = '=';
2464
-		$col = $val = $crit->op;
2465
-		if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2466
-			$val = $r[2];
2467
-		}
2468
-		// Cas special {lang} : aller chercher $GLOBALS['spip_lang']
2469
-		if ($val == 'lang') {
2470
-			$val = [kwote('$GLOBALS[\'spip_lang\']')];
2471
-		} else {
2472
-			$defaut = null;
2473
-			if ($val == 'id_parent') {
2474
-				// Si id_parent, comparer l'id_parent avec l'id_objet
2475
-				// de la boucle superieure.... faudrait verifier qu'il existe
2476
-				// pour eviter l'erreur SQL
2477
-				$val = $boucles[$idb]->primary;
2478
-				// mais si pas de boucle superieure, prendre id_parent dans l'env
2479
-				$defaut = "(\$Pile[0]['id_parent'] ?? null)";
2480
-			} elseif ($val == 'id_enfant') {
2481
-				// Si id_enfant, comparer l'id_objet avec l'id_parent
2482
-				// de la boucle superieure
2483
-				$val = 'id_parent';
2484
-			} elseif ($crit->cond && ($col == 'date' || $col == 'date_redac')) {
2485
-				// un critere conditionnel sur date est traite a part
2486
-				// car la date est mise d'office par SPIP,
2487
-				$defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])";
2488
-			}
2489
-
2490
-			$val = calculer_argument_precedent($idb, $val, $boucles, $defaut);
2491
-			$val = [kwote($val)];
2492
-		}
2493
-	} else {
2494
-		// comparaison explicite
2495
-		// le phraseur impose que le premier param soit du texte
2496
-		$params = $crit->param;
2497
-		$op = $crit->op;
2498
-		if ($op == '==') {
2499
-			$op = 'REGEXP';
2500
-		}
2501
-		$col = array_shift($params);
2502
-		$col = $col[0]->texte;
2503
-
2504
-		$val = [];
2505
-		$parent = $boucles[$idb]->id_parent;
2506
-
2507
-		// Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
2508
-		// celui ne sachant pas ce qu'est un critere infixe
2509
-		// et a fortiori son 2e operande qu'entoure " ou '
2510
-		if (
2511
-			(is_countable($params) ? count($params) : 0) == 1
2512
-			&& (is_countable($params[0]) ? count($params[0]) : 0) == 3
2513
-			&& $params[0][0]->type == 'texte'
2514
-			&& $params[0][2]->type == 'texte'
2515
-			&& ($p = $params[0][0]->texte) == $params[0][2]->texte
2516
-			&& ($p == "'" || $p == '"')
2517
-			&& $params[0][1]->type == 'champ'
2518
-		) {
2519
-			$val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p";
2520
-		} else {
2521
-			foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
2522
-				$a = calculer_liste($p, $idb, $boucles, $parent);
2523
-				$val[] = strcasecmp($op, 'IN') == 0
2524
-					? $a
2525
-					// toujours quoter en char ici
2526
-					: kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@');
2527
-			}
2528
-		}
2529
-	}
2530
-
2531
-	$fct = $args_sql = '';
2532
-	// fonction SQL ?
2533
-	// chercher FONCTION(champ) tel que CONCAT(titre,descriptif)
2534
-	if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) {
2535
-		$fct = $m[1];
2536
-		preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a);
2537
-		$col = $a[1];
2538
-		if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) {
2539
-			$col = $m[1];
2540
-			$args_sql = $m[2];
2541
-		}
2542
-		$args_sql .= $a[2];
2543
-	}
2544
-
2545
-	return [$fct, $col, $op, $val, $args_sql];
2461
+    // cas d'une valeur comparee a elle-meme ou son referent
2462
+    if ((is_countable($crit->param) ? count($crit->param) : 0) == 0) {
2463
+        $op = '=';
2464
+        $col = $val = $crit->op;
2465
+        if (preg_match('/^(.*)\.(.*)$/', $col, $r)) {
2466
+            $val = $r[2];
2467
+        }
2468
+        // Cas special {lang} : aller chercher $GLOBALS['spip_lang']
2469
+        if ($val == 'lang') {
2470
+            $val = [kwote('$GLOBALS[\'spip_lang\']')];
2471
+        } else {
2472
+            $defaut = null;
2473
+            if ($val == 'id_parent') {
2474
+                // Si id_parent, comparer l'id_parent avec l'id_objet
2475
+                // de la boucle superieure.... faudrait verifier qu'il existe
2476
+                // pour eviter l'erreur SQL
2477
+                $val = $boucles[$idb]->primary;
2478
+                // mais si pas de boucle superieure, prendre id_parent dans l'env
2479
+                $defaut = "(\$Pile[0]['id_parent'] ?? null)";
2480
+            } elseif ($val == 'id_enfant') {
2481
+                // Si id_enfant, comparer l'id_objet avec l'id_parent
2482
+                // de la boucle superieure
2483
+                $val = 'id_parent';
2484
+            } elseif ($crit->cond && ($col == 'date' || $col == 'date_redac')) {
2485
+                // un critere conditionnel sur date est traite a part
2486
+                // car la date est mise d'office par SPIP,
2487
+                $defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])";
2488
+            }
2489
+
2490
+            $val = calculer_argument_precedent($idb, $val, $boucles, $defaut);
2491
+            $val = [kwote($val)];
2492
+        }
2493
+    } else {
2494
+        // comparaison explicite
2495
+        // le phraseur impose que le premier param soit du texte
2496
+        $params = $crit->param;
2497
+        $op = $crit->op;
2498
+        if ($op == '==') {
2499
+            $op = 'REGEXP';
2500
+        }
2501
+        $col = array_shift($params);
2502
+        $col = $col[0]->texte;
2503
+
2504
+        $val = [];
2505
+        $parent = $boucles[$idb]->id_parent;
2506
+
2507
+        // Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
2508
+        // celui ne sachant pas ce qu'est un critere infixe
2509
+        // et a fortiori son 2e operande qu'entoure " ou '
2510
+        if (
2511
+            (is_countable($params) ? count($params) : 0) == 1
2512
+            && (is_countable($params[0]) ? count($params[0]) : 0) == 3
2513
+            && $params[0][0]->type == 'texte'
2514
+            && $params[0][2]->type == 'texte'
2515
+            && ($p = $params[0][0]->texte) == $params[0][2]->texte
2516
+            && ($p == "'" || $p == '"')
2517
+            && $params[0][1]->type == 'champ'
2518
+        ) {
2519
+            $val[] = "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p";
2520
+        } else {
2521
+            foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
2522
+                $a = calculer_liste($p, $idb, $boucles, $parent);
2523
+                $val[] = strcasecmp($op, 'IN') == 0
2524
+                    ? $a
2525
+                    // toujours quoter en char ici
2526
+                    : kwote($a, $boucles[$idb]->sql_serveur, '@@defaultcast@@');
2527
+            }
2528
+        }
2529
+    }
2530
+
2531
+    $fct = $args_sql = '';
2532
+    // fonction SQL ?
2533
+    // chercher FONCTION(champ) tel que CONCAT(titre,descriptif)
2534
+    if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) {
2535
+        $fct = $m[1];
2536
+        preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a);
2537
+        $col = $a[1];
2538
+        if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) {
2539
+            $col = $m[1];
2540
+            $args_sql = $m[2];
2541
+        }
2542
+        $args_sql .= $a[2];
2543
+    }
2544
+
2545
+    return [$fct, $col, $op, $val, $args_sql];
2546 2546
 }
2547 2547
 
2548 2548
 // compatibilite ancienne version
2549 2549
 
2550 2550
 function calculer_vieux_in($params) {
2551
-	$deb = $params[0][0];
2552
-	$k = (is_countable($params) ? count($params) : 0) - 1;
2553
-	$last = $params[$k];
2554
-	$j = (is_countable($last) ? count($last) : 0) - 1;
2555
-	$last = $last[$j];
2556
-	$n = isset($last->texte) ? strlen($last->texte) : 0;
2557
-
2558
-	if (
2559
-		!((isset($deb->texte[0]) && $deb->texte[0] == '(')
2560
-		&& (isset($last->texte[$n - 1]) && $last->texte[$n - 1] == ')'))
2561
-	) {
2562
-		return $params;
2563
-	}
2564
-	$params[0][0]->texte = substr($deb->texte, 1);
2565
-	// attention, on peut avoir k=0,j=0 ==> recalculer
2566
-	$last = $params[$k][$j];
2567
-	$n = strlen($last->texte);
2568
-	$params[$k][$j]->texte = substr($last->texte, 0, $n - 1);
2569
-	$newp = [];
2570
-	foreach ($params as $v) {
2571
-		if ($v[0]->type != 'texte') {
2572
-			$newp[] = $v;
2573
-		} else {
2574
-			foreach (explode(',', $v[0]->texte) as $x) {
2575
-				$t = new Texte();
2576
-				$t->texte = $x;
2577
-				$newp[] = [$t];
2578
-			}
2579
-		}
2580
-	}
2581
-
2582
-	return $newp;
2551
+    $deb = $params[0][0];
2552
+    $k = (is_countable($params) ? count($params) : 0) - 1;
2553
+    $last = $params[$k];
2554
+    $j = (is_countable($last) ? count($last) : 0) - 1;
2555
+    $last = $last[$j];
2556
+    $n = isset($last->texte) ? strlen($last->texte) : 0;
2557
+
2558
+    if (
2559
+        !((isset($deb->texte[0]) && $deb->texte[0] == '(')
2560
+        && (isset($last->texte[$n - 1]) && $last->texte[$n - 1] == ')'))
2561
+    ) {
2562
+        return $params;
2563
+    }
2564
+    $params[0][0]->texte = substr($deb->texte, 1);
2565
+    // attention, on peut avoir k=0,j=0 ==> recalculer
2566
+    $last = $params[$k][$j];
2567
+    $n = strlen($last->texte);
2568
+    $params[$k][$j]->texte = substr($last->texte, 0, $n - 1);
2569
+    $newp = [];
2570
+    foreach ($params as $v) {
2571
+        if ($v[0]->type != 'texte') {
2572
+            $newp[] = $v;
2573
+        } else {
2574
+            foreach (explode(',', $v[0]->texte) as $x) {
2575
+                $t = new Texte();
2576
+                $t->texte = $x;
2577
+                $newp[] = [$t];
2578
+            }
2579
+        }
2580
+    }
2581
+
2582
+    return $newp;
2583 2583
 }
2584 2584
 
2585 2585
 /**
@@ -2598,91 +2598,91 @@  discard block
 block discarded – undo
2598 2598
  *     - nom de la colonne de date (si le calcul n'est pas relatif)
2599 2599
  **/
2600 2600
 function calculer_critere_infixe_date($idb, &$boucles, $col) {
2601
-	if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) {
2602
-		return '';
2603
-	}
2604
-
2605
-	$boucle = $boucles[$idb];
2606
-	$table = $boucle->show;
2607
-
2608
-	// si c'est une colonne de la table, ne rien faire
2609
-	if (isset($table['field'][$col])) {
2610
-		return '';
2611
-	}
2612
-
2613
-	// Le type de critère à prendre en compte
2614
-	$col = $regs[1];
2615
-
2616
-	// Si on trouve un nom de champ date précis, on l'utilise, pas besoin de déclaration dans l'API objet
2617
-	if (isset($regs[3]) && ($suite = $regs[3])) {
2618
-		# Recherche de l'existence du champ date_xxxx,
2619
-		# si oui choisir ce champ, sinon choisir xxxx
2620
-		$date_orig = isset($table['field']["date$suite"]) ? 'date' . $suite : substr($suite, 1);
2621
-
2622
-		$pred = $date_orig;
2623
-	} else { // Sinon il FAUT avoir déclaré le champ date officiel dans l'API objet
2624
-		// Si aucune déclaration trouvée, on quitte
2625
-		if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) {
2626
-			return '';
2627
-		}
2628
-		// Par défaut, on prend le champ date déclaré dans l'API
2629
-		$pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date'];
2630
-
2631
-		// Si c'est pour du relatif
2632
-		if (isset($regs[2]) && ($rel = $regs[2])) {
2633
-			$pred = 'date';
2634
-		}
2635
-	}
2636
-
2637
-	$date_compare = "\"' . normaliser_date(" .
2638
-		calculer_argument_precedent($idb, $pred, $boucles) .
2639
-		") . '\"";
2640
-
2641
-	$col_vraie = $date_orig;
2642
-	$date_orig = $boucle->id_table . '.' . $date_orig;
2643
-
2644
-	switch ($col) {
2645
-		case 'date':
2646
-			$col = $date_orig;
2647
-			break;
2648
-		case 'jour':
2649
-			$col = "DAYOFMONTH($date_orig)";
2650
-			break;
2651
-		case 'mois':
2652
-			$col = "MONTH($date_orig)";
2653
-			break;
2654
-		case 'annee':
2655
-			$col = "YEAR($date_orig)";
2656
-			break;
2657
-		case 'heure':
2658
-			$col = "DATE_FORMAT($date_orig, \\'%H:%i\\')";
2659
-			break;
2660
-		case 'age':
2661
-			$col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig);
2662
-			$col_vraie = '';// comparer a un int (par defaut)
2663
-			break;
2664
-		case 'age_relatif':
2665
-			$col = calculer_param_date($date_compare, $date_orig);
2666
-			$col_vraie = '';// comparer a un int (par defaut)
2667
-			break;
2668
-		case 'jour_relatif':
2669
-			$col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))';
2670
-			$col_vraie = '';// comparer a un int (par defaut)
2671
-			break;
2672
-		case 'mois_relatif':
2673
-			$col = 'MONTH(' . $date_compare . ')-MONTH(' .
2674
-				$date_orig . ')+12*(YEAR(' . $date_compare .
2675
-				')-YEAR(' . $date_orig . '))';
2676
-			$col_vraie = '';// comparer a un int (par defaut)
2677
-			break;
2678
-		case 'annee_relatif':
2679
-			$col = 'YEAR(' . $date_compare . ')-YEAR(' .
2680
-				$date_orig . ')';
2681
-			$col_vraie = '';// comparer a un int (par defaut)
2682
-			break;
2683
-	}
2684
-
2685
-	return [$col, $col_vraie];
2601
+    if (!preg_match(',^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z_]+)?$,', $col, $regs)) {
2602
+        return '';
2603
+    }
2604
+
2605
+    $boucle = $boucles[$idb];
2606
+    $table = $boucle->show;
2607
+
2608
+    // si c'est une colonne de la table, ne rien faire
2609
+    if (isset($table['field'][$col])) {
2610
+        return '';
2611
+    }
2612
+
2613
+    // Le type de critère à prendre en compte
2614
+    $col = $regs[1];
2615
+
2616
+    // Si on trouve un nom de champ date précis, on l'utilise, pas besoin de déclaration dans l'API objet
2617
+    if (isset($regs[3]) && ($suite = $regs[3])) {
2618
+        # Recherche de l'existence du champ date_xxxx,
2619
+        # si oui choisir ce champ, sinon choisir xxxx
2620
+        $date_orig = isset($table['field']["date$suite"]) ? 'date' . $suite : substr($suite, 1);
2621
+
2622
+        $pred = $date_orig;
2623
+    } else { // Sinon il FAUT avoir déclaré le champ date officiel dans l'API objet
2624
+        // Si aucune déclaration trouvée, on quitte
2625
+        if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) {
2626
+            return '';
2627
+        }
2628
+        // Par défaut, on prend le champ date déclaré dans l'API
2629
+        $pred = $date_orig = $GLOBALS['table_date'][$table['id_table']] ?? $table['date'];
2630
+
2631
+        // Si c'est pour du relatif
2632
+        if (isset($regs[2]) && ($rel = $regs[2])) {
2633
+            $pred = 'date';
2634
+        }
2635
+    }
2636
+
2637
+    $date_compare = "\"' . normaliser_date(" .
2638
+        calculer_argument_precedent($idb, $pred, $boucles) .
2639
+        ") . '\"";
2640
+
2641
+    $col_vraie = $date_orig;
2642
+    $date_orig = $boucle->id_table . '.' . $date_orig;
2643
+
2644
+    switch ($col) {
2645
+        case 'date':
2646
+            $col = $date_orig;
2647
+            break;
2648
+        case 'jour':
2649
+            $col = "DAYOFMONTH($date_orig)";
2650
+            break;
2651
+        case 'mois':
2652
+            $col = "MONTH($date_orig)";
2653
+            break;
2654
+        case 'annee':
2655
+            $col = "YEAR($date_orig)";
2656
+            break;
2657
+        case 'heure':
2658
+            $col = "DATE_FORMAT($date_orig, \\'%H:%i\\')";
2659
+            break;
2660
+        case 'age':
2661
+            $col = calculer_param_date("\'' . date('Y-m-d H:i:00') . '\'", $date_orig);
2662
+            $col_vraie = '';// comparer a un int (par defaut)
2663
+            break;
2664
+        case 'age_relatif':
2665
+            $col = calculer_param_date($date_compare, $date_orig);
2666
+            $col_vraie = '';// comparer a un int (par defaut)
2667
+            break;
2668
+        case 'jour_relatif':
2669
+            $col = '(TO_DAYS(' . $date_compare . ')-TO_DAYS(' . $date_orig . '))';
2670
+            $col_vraie = '';// comparer a un int (par defaut)
2671
+            break;
2672
+        case 'mois_relatif':
2673
+            $col = 'MONTH(' . $date_compare . ')-MONTH(' .
2674
+                $date_orig . ')+12*(YEAR(' . $date_compare .
2675
+                ')-YEAR(' . $date_orig . '))';
2676
+            $col_vraie = '';// comparer a un int (par defaut)
2677
+            break;
2678
+        case 'annee_relatif':
2679
+            $col = 'YEAR(' . $date_compare . ')-YEAR(' .
2680
+                $date_orig . ')';
2681
+            $col_vraie = '';// comparer a un int (par defaut)
2682
+            break;
2683
+    }
2684
+
2685
+    return [$col, $col_vraie];
2686 2686
 }
2687 2687
 
2688 2688
 /**
@@ -2701,16 +2701,16 @@  discard block
 block discarded – undo
2701 2701
  *     de colonne SQL et une date.
2702 2702
  **/
2703 2703
 function calculer_param_date($date_compare, $date_orig) {
2704
-	if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) {
2705
-		$init = "'\" . (\$x = $r[1]) . \"'";
2706
-		$date_compare = '\'$x\'';
2707
-	} else {
2708
-		$init = $date_compare;
2709
-	}
2710
-
2711
-	return
2712
-		// optimisation : mais prevoir le support SQLite avant
2713
-		"TIMESTAMPDIFF(HOUR,$date_orig,$init)/24";
2704
+    if (preg_match(",'\" *\.(.*)\. *\"',", $date_compare, $r)) {
2705
+        $init = "'\" . (\$x = $r[1]) . \"'";
2706
+        $date_compare = '\'$x\'';
2707
+    } else {
2708
+        $init = $date_compare;
2709
+    }
2710
+
2711
+    return
2712
+        // optimisation : mais prevoir le support SQLite avant
2713
+        "TIMESTAMPDIFF(HOUR,$date_orig,$init)/24";
2714 2714
 }
2715 2715
 
2716 2716
 /**
@@ -2728,17 +2728,17 @@  discard block
 block discarded – undo
2728 2728
  * @param Critere $crit Paramètres du critère dans cette boucle
2729 2729
  */
2730 2730
 function critere_DATA_source_dist($idb, &$boucles, $crit) {
2731
-	$boucle = &$boucles[$idb];
2731
+    $boucle = &$boucles[$idb];
2732 2732
 
2733
-	$args = [];
2734
-	foreach ($crit->param as &$param) {
2735
-		$args[] = calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent);
2736
-	}
2733
+    $args = [];
2734
+    foreach ($crit->param as &$param) {
2735
+        $args[] = calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent);
2736
+    }
2737 2737
 
2738
-	$boucle->hash .= '
2738
+    $boucle->hash .= '
2739 2739
 	$command[\'sourcemode\'] = ' . array_shift($args) . ";\n";
2740 2740
 
2741
-	$boucle->hash .= '
2741
+    $boucle->hash .= '
2742 2742
 	$command[\'source\'] = array(' . implode(', ', $args) . ");\n";
2743 2743
 }
2744 2744
 
@@ -2756,8 +2756,8 @@  discard block
 block discarded – undo
2756 2756
  * @param Critere $crit Paramètres du critère dans cette boucle
2757 2757
  */
2758 2758
 function critere_DATA_datacache_dist($idb, &$boucles, $crit) {
2759
-	$boucle = &$boucles[$idb];
2760
-	$boucle->hash .= '
2759
+    $boucle = &$boucles[$idb];
2760
+    $boucle->hash .= '
2761 2761
 	$command[\'datacache\'] = ' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2762 2762
 }
2763 2763
 
@@ -2773,12 +2773,12 @@  discard block
 block discarded – undo
2773 2773
  * @param Critere $crit Paramètres du critère dans cette boucle
2774 2774
  */
2775 2775
 function critere_php_args_dist($idb, &$boucles, $crit) {
2776
-	$boucle = &$boucles[$idb];
2777
-	$boucle->hash .= '$command[\'args\']=array();';
2778
-	foreach ($crit->param as $param) {
2779
-		$boucle->hash .= '
2776
+    $boucle = &$boucles[$idb];
2777
+    $boucle->hash .= '$command[\'args\']=array();';
2778
+    foreach ($crit->param as $param) {
2779
+        $boucle->hash .= '
2780 2780
 			$command[\'args\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2781
-	}
2781
+    }
2782 2782
 }
2783 2783
 
2784 2784
 /**
@@ -2795,16 +2795,16 @@  discard block
 block discarded – undo
2795 2795
  * @param Critere $crit Paramètres du critère dans cette boucle
2796 2796
  */
2797 2797
 function critere_DATA_liste_dist($idb, &$boucles, $crit) {
2798
-	$boucle = &$boucles[$idb];
2799
-	$boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n";
2800
-	foreach ($crit->param as $param) {
2801
-		$boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste(
2802
-			$param,
2803
-			$idb,
2804
-			$boucles,
2805
-			$boucles[$idb]->id_parent
2806
-		) . ";\n";
2807
-	}
2798
+    $boucle = &$boucles[$idb];
2799
+    $boucle->hash .= "\n\t" . '$command[\'liste\'] = array();' . "\n";
2800
+    foreach ($crit->param as $param) {
2801
+        $boucle->hash .= "\t" . '$command[\'liste\'][] = ' . calculer_liste(
2802
+            $param,
2803
+            $idb,
2804
+            $boucles,
2805
+            $boucles[$idb]->id_parent
2806
+        ) . ";\n";
2807
+    }
2808 2808
 }
2809 2809
 
2810 2810
 /**
@@ -2829,16 +2829,16 @@  discard block
 block discarded – undo
2829 2829
  * @param Critere $crit Paramètres du critère dans cette boucle
2830 2830
  */
2831 2831
 function critere_DATA_enum_dist($idb, &$boucles, $crit) {
2832
-	$boucle = &$boucles[$idb];
2833
-	$boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n";
2834
-	foreach ($crit->param as $param) {
2835
-		$boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste(
2836
-			$param,
2837
-			$idb,
2838
-			$boucles,
2839
-			$boucles[$idb]->id_parent
2840
-		) . ";\n";
2841
-	}
2832
+    $boucle = &$boucles[$idb];
2833
+    $boucle->hash .= "\n\t" . '$command[\'enum\'] = array();' . "\n";
2834
+    foreach ($crit->param as $param) {
2835
+        $boucle->hash .= "\t" . '$command[\'enum\'][] = ' . calculer_liste(
2836
+            $param,
2837
+            $idb,
2838
+            $boucles,
2839
+            $boucles[$idb]->id_parent
2840
+        ) . ";\n";
2841
+    }
2842 2842
 }
2843 2843
 
2844 2844
 /**
@@ -2853,11 +2853,11 @@  discard block
 block discarded – undo
2853 2853
  * @param Critere $crit Paramètres du critère dans cette boucle
2854 2854
  */
2855 2855
 function critere_DATA_datapath_dist($idb, &$boucles, $crit) {
2856
-	$boucle = &$boucles[$idb];
2857
-	foreach ($crit->param as $param) {
2858
-		$boucle->hash .= '
2856
+    $boucle = &$boucles[$idb];
2857
+    foreach ($crit->param as $param) {
2858
+        $boucle->hash .= '
2859 2859
 			$command[\'datapath\'][] = ' . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ';';
2860
-	}
2860
+    }
2861 2861
 }
2862 2862
 
2863 2863
 
@@ -2889,20 +2889,20 @@  discard block
 block discarded – undo
2889 2889
  * @param Critere $crit Paramètres du critère dans cette boucle
2890 2890
  */
2891 2891
 function critere_si_dist($idb, &$boucles, $crit) {
2892
-	$boucle = &$boucles[$idb];
2893
-	// il faut initialiser 1 fois le tableau a chaque appel de la boucle
2894
-	// (par exemple lorsque notre boucle est appelee dans une autre boucle)
2895
-	// mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle !
2896
-	$boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
2897
-	if ($crit->param) {
2898
-		foreach ($crit->param as $param) {
2899
-			$boucle->hash .= "\t\$command['si'][] = "
2900
-				. calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n";
2901
-		}
2902
-		// interdire {si 0} aussi !
2903
-	} else {
2904
-		$boucle->hash .= '$command[\'si\'][] = 0;';
2905
-	}
2892
+    $boucle = &$boucles[$idb];
2893
+    // il faut initialiser 1 fois le tableau a chaque appel de la boucle
2894
+    // (par exemple lorsque notre boucle est appelee dans une autre boucle)
2895
+    // mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle !
2896
+    $boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
2897
+    if ($crit->param) {
2898
+        foreach ($crit->param as $param) {
2899
+            $boucle->hash .= "\t\$command['si'][] = "
2900
+                . calculer_liste($param, $idb, $boucles, $boucles[$idb]->id_parent) . ";\n";
2901
+        }
2902
+        // interdire {si 0} aussi !
2903
+    } else {
2904
+        $boucle->hash .= '$command[\'si\'][] = 0;';
2905
+    }
2906 2906
 }
2907 2907
 
2908 2908
 /**
@@ -2919,8 +2919,8 @@  discard block
 block discarded – undo
2919 2919
  * @param Critere $crit Paramètres du critère dans cette boucle
2920 2920
  */
2921 2921
 function critere_POUR_tableau_dist($idb, &$boucles, $crit) {
2922
-	$boucle = &$boucles[$idb];
2923
-	$boucle->hash .= '
2922
+    $boucle = &$boucles[$idb];
2923
+    $boucle->hash .= '
2924 2924
 	$command[\'source\'] = array(' . calculer_liste($crit->param[0], $idb, $boucles, $boucles[$idb]->id_parent) . ');
2925 2925
 	$command[\'sourcemode\'] = \'table\';';
2926 2926
 }
@@ -2941,27 +2941,27 @@  discard block
 block discarded – undo
2941 2941
  */
2942 2942
 function critere_noeud_dist($idb, &$boucles, $crit) {
2943 2943
 
2944
-	$not = $crit->not;
2945
-	$boucle = &$boucles[$idb];
2946
-	$primary = $boucle->primary;
2944
+    $not = $crit->not;
2945
+    $boucle = &$boucles[$idb];
2946
+    $primary = $boucle->primary;
2947 2947
 
2948
-	if (!$primary || strpos($primary, ',')) {
2949
-		erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle);
2948
+    if (!$primary || strpos($primary, ',')) {
2949
+        erreur_squelette(_T('zbug_doublon_sur_table_sans_cle_primaire'), $boucle);
2950 2950
 
2951
-		return;
2952
-	}
2953
-	$table = $boucle->type_requete;
2954
-	$table_sql = table_objet_sql(objet_type($table));
2951
+        return;
2952
+    }
2953
+    $table = $boucle->type_requete;
2954
+    $table_sql = table_objet_sql(objet_type($table));
2955 2955
 
2956
-	$id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
2956
+    $id_parent = $GLOBALS['exceptions_des_tables'][$boucle->id_table]['id_parent'] ?? 'id_parent';
2957 2957
 
2958
-	$in = 'IN';
2959
-	$where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"];
2960
-	if ($not) {
2961
-		$where = ["'NOT'", $where];
2962
-	}
2958
+    $in = 'IN';
2959
+    $where = ["'IN'", "'$boucle->id_table." . "$primary'", "'('.sql_get_select('$id_parent', '$table_sql').')'"];
2960
+    if ($not) {
2961
+        $where = ["'NOT'", $where];
2962
+    }
2963 2963
 
2964
-	$boucle->where[] = $where;
2964
+    $boucle->where[] = $where;
2965 2965
 }
2966 2966
 
2967 2967
 /**
@@ -2977,8 +2977,8 @@  discard block
 block discarded – undo
2977 2977
  * @param Critere $crit Paramètres du critère dans cette boucle
2978 2978
  */
2979 2979
 function critere_feuille_dist($idb, &$boucles, $crit) {
2980
-	$not = $crit->not;
2981
-	$crit->not = !$not;
2982
-	critere_noeud_dist($idb, $boucles, $crit);
2983
-	$crit->not = $not;
2980
+    $not = $crit->not;
2981
+    $crit->not = !$not;
2982
+    critere_noeud_dist($idb, $boucles, $crit);
2983
+    $crit->not = $not;
2984 2984
 }
Please login to merge, or discard this patch.
ecrire/public/evaluer_page.php 1 patch
Indentation   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -10,7 +10,7 @@  discard block
 block discarded – undo
10 10
 \***************************************************************************/
11 11
 
12 12
 if (!defined('_ECRIRE_INC_VERSION')) {
13
-	return;
13
+    return;
14 14
 }
15 15
 
16 16
 /**
@@ -28,50 +28,50 @@  discard block
 block discarded – undo
28 28
  * @return void
29 29
  */
30 30
 
31
- /** @var bool Évaluation réussie ? */
31
+    /** @var bool Évaluation réussie ? */
32 32
 $res = true;
33 33
 
34 34
 // Cas d'une page contenant du PHP :
35 35
 if (empty($page['process_ins']) || $page['process_ins'] != 'html') {
36
-	include_spip('inc/lang');
36
+    include_spip('inc/lang');
37 37
 
38
-	// restaurer l'etat des notes avant calcul
39
-	if (
40
-		isset($page['notes'])
41
-		&& $page['notes']
42
-		&& ($notes = charger_fonction('notes', 'inc', true))
43
-	) {
44
-		$notes($page['notes'], 'restaurer_etat');
45
-	}
46
-	ob_start();
47
-	if (str_contains($page['texte'], '?xml')) {
48
-		$page['texte'] = str_replace('<?xml', "<\1?xml", $page['texte']);
49
-	}
38
+    // restaurer l'etat des notes avant calcul
39
+    if (
40
+        isset($page['notes'])
41
+        && $page['notes']
42
+        && ($notes = charger_fonction('notes', 'inc', true))
43
+    ) {
44
+        $notes($page['notes'], 'restaurer_etat');
45
+    }
46
+    ob_start();
47
+    if (str_contains($page['texte'], '?xml')) {
48
+        $page['texte'] = str_replace('<?xml', "<\1?xml", $page['texte']);
49
+    }
50 50
 
51
-	try {
52
-		$res = eval('?' . '>' . $page['texte']);
53
-		$page['texte'] = ob_get_contents();
54
-	} catch (\Throwable $e) {
55
-		$code = $page['texte'];
56
-		$GLOBALS['numero_ligne_php'] = 1;
57
-		if (!function_exists('numerote_ligne_php')) {
58
-			function numerote_ligne_php($match) {
59
-				$GLOBALS['numero_ligne_php']++;
60
-				return "\n/*" . str_pad($GLOBALS['numero_ligne_php'], 3, '0', STR_PAD_LEFT) . '*/';
61
-			}
62
-		}
63
-		$code = '/*001*/' . preg_replace_callback(",\n,", 'numerote_ligne_php', $code);
64
-		$code = trim(highlight_string($code, true));
65
-		erreur_squelette('L' . $e->getLine() . ': ' . $e->getMessage() . '<br />' . $code, [$page['source'],'',$e->getFile(),'',$GLOBALS['spip_lang']]);
66
-		$page['texte'] = '<!-- Erreur -->';
67
-	}
68
-	ob_end_clean();
51
+    try {
52
+        $res = eval('?' . '>' . $page['texte']);
53
+        $page['texte'] = ob_get_contents();
54
+    } catch (\Throwable $e) {
55
+        $code = $page['texte'];
56
+        $GLOBALS['numero_ligne_php'] = 1;
57
+        if (!function_exists('numerote_ligne_php')) {
58
+            function numerote_ligne_php($match) {
59
+                $GLOBALS['numero_ligne_php']++;
60
+                return "\n/*" . str_pad($GLOBALS['numero_ligne_php'], 3, '0', STR_PAD_LEFT) . '*/';
61
+            }
62
+        }
63
+        $code = '/*001*/' . preg_replace_callback(",\n,", 'numerote_ligne_php', $code);
64
+        $code = trim(highlight_string($code, true));
65
+        erreur_squelette('L' . $e->getLine() . ': ' . $e->getMessage() . '<br />' . $code, [$page['source'],'',$e->getFile(),'',$GLOBALS['spip_lang']]);
66
+        $page['texte'] = '<!-- Erreur -->';
67
+    }
68
+    ob_end_clean();
69 69
 
70
-	$page['process_ins'] = 'html';
70
+    $page['process_ins'] = 'html';
71 71
 
72
-	if (str_contains($page['texte'], '?xml')) {
73
-		$page['texte'] = str_replace("<\1?xml", '<?xml', $page['texte']);
74
-	}
72
+    if (str_contains($page['texte'], '?xml')) {
73
+        $page['texte'] = str_replace("<\1?xml", '<?xml', $page['texte']);
74
+    }
75 75
 }
76 76
 
77 77
 // le résultat de calcul d'un squelette est toujours de type string
Please login to merge, or discard this patch.
ecrire/public/boucles.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -16,7 +16,7 @@  discard block
 block discarded – undo
16 16
  **/
17 17
 
18 18
 if (!defined('_ECRIRE_INC_VERSION')) {
19
-	return;
19
+    return;
20 20
 }
21 21
 
22 22
 
@@ -31,7 +31,7 @@  discard block
 block discarded – undo
31 31
  *     Code PHP compilé de la boucle
32 32
  **/
33 33
 function boucle_DEFAUT_dist($id_boucle, &$boucles) {
34
-	return calculer_boucle($id_boucle, $boucles);
34
+    return calculer_boucle($id_boucle, $boucles);
35 35
 }
36 36
 
37 37
 
@@ -50,7 +50,7 @@  discard block
 block discarded – undo
50 50
  *     Code PHP compilé de la boucle
51 51
  **/
52 52
 function boucle_BOUCLE_dist($id_boucle, &$boucles) {
53
-	return calculer_boucle($id_boucle, $boucles);
53
+    return calculer_boucle($id_boucle, $boucles);
54 54
 }
55 55
 
56 56
 
@@ -80,30 +80,30 @@  discard block
 block discarded – undo
80 80
  *     Code PHP compilé de la boucle
81 81
  **/
82 82
 function boucle_HIERARCHIE_dist($id_boucle, &$boucles) {
83
-	$boucle = &$boucles[$id_boucle];
84
-	$id_table = $boucle->id_table . '.id_rubrique';
83
+    $boucle = &$boucles[$id_boucle];
84
+    $id_table = $boucle->id_table . '.id_rubrique';
85 85
 
86
-	// Si la boucle mere est une boucle RUBRIQUES il faut ignorer la feuille
87
-	// sauf en presence du critere {tout} (vu par phraser_html)
88
-	// ou {id_article} qui positionne aussi le {tout}
86
+    // Si la boucle mere est une boucle RUBRIQUES il faut ignorer la feuille
87
+    // sauf en presence du critere {tout} (vu par phraser_html)
88
+    // ou {id_article} qui positionne aussi le {tout}
89 89
 
90
-	$boucle->hierarchie = 'if (!($id_rubrique = intval('
91
-		. calculer_argument_precedent($boucle->id_boucle, 'id_rubrique', $boucles)
92
-		. ")))\n\t\treturn '';\n\t"
93
-		. "include_spip('inc/rubriques');\n\t"
94
-		. '$hierarchie = calcul_hierarchie_in($id_rubrique,'
95
-		. (isset($boucle->modificateur['tout']) ? 'true' : 'false')
96
-		. ");\n\t"
97
-		. 'if (!$hierarchie) return "";' . "\n\t";
90
+    $boucle->hierarchie = 'if (!($id_rubrique = intval('
91
+        . calculer_argument_precedent($boucle->id_boucle, 'id_rubrique', $boucles)
92
+        . ")))\n\t\treturn '';\n\t"
93
+        . "include_spip('inc/rubriques');\n\t"
94
+        . '$hierarchie = calcul_hierarchie_in($id_rubrique,'
95
+        . (isset($boucle->modificateur['tout']) ? 'true' : 'false')
96
+        . ");\n\t"
97
+        . 'if (!$hierarchie) return "";' . "\n\t";
98 98
 
99
-	$boucle->where[] = ["'IN'", "'$id_table'", '"($hierarchie)"'];
99
+    $boucle->where[] = ["'IN'", "'$id_table'", '"($hierarchie)"'];
100 100
 
101
-	$order = "FIELD($id_table, \$hierarchie)";
102
-	if (!isset($boucle->default_order[0]) || $boucle->default_order[0] != ' DESC') {
103
-		$boucle->default_order[] = "\"$order\"";
104
-	} else {
105
-		$boucle->default_order[0] = "\"$order DESC\"";
106
-	}
101
+    $order = "FIELD($id_table, \$hierarchie)";
102
+    if (!isset($boucle->default_order[0]) || $boucle->default_order[0] != ' DESC') {
103
+        $boucle->default_order[] = "\"$order\"";
104
+    } else {
105
+        $boucle->default_order[0] = "\"$order DESC\"";
106
+    }
107 107
 
108
-	return calculer_boucle($id_boucle, $boucles);
108
+    return calculer_boucle($id_boucle, $boucles);
109 109
 }
Please login to merge, or discard this patch.
ecrire/public/quete.php 1 patch
Indentation   +421 added lines, -421 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  **/
19 19
 
20 20
 if (!defined('_ECRIRE_INC_VERSION')) {
21
-	return;
21
+    return;
22 22
 }
23 23
 
24 24
 
@@ -32,16 +32,16 @@  discard block
 block discarded – undo
32 32
  * @return array|bool|null
33 33
  */
34 34
 function quete_virtuel($id_article, $connect) {
35
-	return sql_getfetsel(
36
-		'virtuel',
37
-		'spip_articles',
38
-		['id_article=' . (int) $id_article, "statut='publie'"],
39
-		'',
40
-		'',
41
-		'',
42
-		'',
43
-		$connect
44
-	);
35
+    return sql_getfetsel(
36
+        'virtuel',
37
+        'spip_articles',
38
+        ['id_article=' . (int) $id_article, "statut='publie'"],
39
+        '',
40
+        '',
41
+        '',
42
+        '',
43
+        $connect
44
+    );
45 45
 }
46 46
 
47 47
 /**
@@ -56,39 +56,39 @@  discard block
 block discarded – undo
56 56
  * @return array
57 57
  */
58 58
 function quete_parent_lang($table, $id, string $connect = '') {
59
-	static $cache_quete = [];
60
-
61
-	if (!isset($cache_quete[$connect][$table][$id])) {
62
-		if (!isset($cache_quete[$connect][$table]['_select'])) {
63
-			$trouver_table = charger_fonction('trouver_table', 'base');
64
-			if (
65
-				!($desc = $trouver_table($table, $connect))
66
-				|| !isset($desc['field']['id_rubrique'])
67
-			) {
68
-				// pas de parent rubrique, on passe
69
-				$cache_quete[$connect][$table]['_select'] = false;
70
-			} else {
71
-				$select = ($table == 'spip_rubriques' ? 'id_parent' : 'id_rubrique');
72
-				$select .= isset($desc['field']['lang']) ? ', lang' : '';
73
-				$cache_quete[$connect][$table]['_select'] = $select;
74
-				$cache_quete[$connect][$table]['_id'] = id_table_objet(objet_type($table));
75
-			}
76
-		}
77
-		if ($cache_quete[$connect][$table]['_select']) {
78
-			$cache_quete[$connect][$table][$id] = sql_fetsel(
79
-				$cache_quete[$connect][$table]['_select'],
80
-				$table,
81
-				$cache_quete[$connect][$table]['_id'] . '=' . (int) $id,
82
-				'',
83
-				'',
84
-				'',
85
-				'',
86
-				$connect
87
-			);
88
-		}
89
-	}
90
-
91
-	return $cache_quete[$connect][$table][$id] ?? null;
59
+    static $cache_quete = [];
60
+
61
+    if (!isset($cache_quete[$connect][$table][$id])) {
62
+        if (!isset($cache_quete[$connect][$table]['_select'])) {
63
+            $trouver_table = charger_fonction('trouver_table', 'base');
64
+            if (
65
+                !($desc = $trouver_table($table, $connect))
66
+                || !isset($desc['field']['id_rubrique'])
67
+            ) {
68
+                // pas de parent rubrique, on passe
69
+                $cache_quete[$connect][$table]['_select'] = false;
70
+            } else {
71
+                $select = ($table == 'spip_rubriques' ? 'id_parent' : 'id_rubrique');
72
+                $select .= isset($desc['field']['lang']) ? ', lang' : '';
73
+                $cache_quete[$connect][$table]['_select'] = $select;
74
+                $cache_quete[$connect][$table]['_id'] = id_table_objet(objet_type($table));
75
+            }
76
+        }
77
+        if ($cache_quete[$connect][$table]['_select']) {
78
+            $cache_quete[$connect][$table][$id] = sql_fetsel(
79
+                $cache_quete[$connect][$table]['_select'],
80
+                $table,
81
+                $cache_quete[$connect][$table]['_id'] . '=' . (int) $id,
82
+                '',
83
+                '',
84
+                '',
85
+                '',
86
+                $connect
87
+            );
88
+        }
89
+    }
90
+
91
+    return $cache_quete[$connect][$table][$id] ?? null;
92 92
 }
93 93
 
94 94
 
@@ -105,11 +105,11 @@  discard block
 block discarded – undo
105 105
  * @return int
106 106
  */
107 107
 function quete_parent($id_rubrique, string $connect = '') {
108
-	if (!$id_rubrique = (int) $id_rubrique) {
109
-		return 0;
110
-	}
111
-	$id_parent = quete_parent_lang('spip_rubriques', $id_rubrique, $connect);
112
-	return $id_parent ? $id_parent['id_parent'] : 0;
108
+    if (!$id_rubrique = (int) $id_rubrique) {
109
+        return 0;
110
+    }
111
+    $id_parent = quete_parent_lang('spip_rubriques', $id_rubrique, $connect);
112
+    return $id_parent ? $id_parent['id_parent'] : 0;
113 113
 }
114 114
 
115 115
 /**
@@ -125,9 +125,9 @@  discard block
 block discarded – undo
125 125
  * @return int
126 126
  */
127 127
 function quete_rubrique($id_article, $serveur) {
128
-	$id_parent = quete_parent_lang('spip_articles', $id_article, $serveur);
128
+    $id_parent = quete_parent_lang('spip_articles', $id_article, $serveur);
129 129
 
130
-	return $id_parent['id_rubrique'] ?? 0;
130
+    return $id_parent['id_rubrique'] ?? 0;
131 131
 }
132 132
 
133 133
 
@@ -140,13 +140,13 @@  discard block
 block discarded – undo
140 140
  * @return int
141 141
  */
142 142
 function quete_profondeur($id, string $connect = '') {
143
-	$n = 0;
144
-	while ($id) {
145
-		$n++;
146
-		$id = quete_parent($id, $connect);
147
-	}
143
+    $n = 0;
144
+    while ($id) {
145
+        $n++;
146
+        $id = quete_parent($id, $connect);
147
+    }
148 148
 
149
-	return $n;
149
+    return $n;
150 150
 }
151 151
 
152 152
 
@@ -162,15 +162,15 @@  discard block
 block discarded – undo
162 162
  *     Morceau de la requête SQL testant la date
163 163
  */
164 164
 function quete_condition_postdates($champ_date, $serveur = '', $ignore_previsu = false) {
165
-	if (defined('_VAR_PREVIEW') && _VAR_PREVIEW && !$ignore_previsu) {
166
-		return '1=1';
167
-	}
168
-
169
-	return
170
-		(isset($GLOBALS['meta']['date_prochain_postdate'])
171
-			&& $GLOBALS['meta']['date_prochain_postdate'] > time())
172
-			? "$champ_date<" . sql_quote(date('Y-m-d H:i:s', $GLOBALS['meta']['date_prochain_postdate']), $serveur)
173
-			: '1=1';
165
+    if (defined('_VAR_PREVIEW') && _VAR_PREVIEW && !$ignore_previsu) {
166
+        return '1=1';
167
+    }
168
+
169
+    return
170
+        (isset($GLOBALS['meta']['date_prochain_postdate'])
171
+            && $GLOBALS['meta']['date_prochain_postdate'] > time())
172
+            ? "$champ_date<" . sql_quote(date('Y-m-d H:i:s', $GLOBALS['meta']['date_prochain_postdate']), $serveur)
173
+            : '1=1';
174 174
 }
175 175
 
176 176
 
@@ -190,101 +190,101 @@  discard block
 block discarded – undo
190 190
  * @return array|string
191 191
  */
192 192
 function quete_condition_statut($mstatut, $previsu, $publie, $serveur = '', $ignore_previsu = false) {
193
-	static $cond = [];
194
-	$key = func_get_args();
195
-	$key = implode('-', $key);
196
-	if (isset($cond[$key])) {
197
-		return $cond[$key];
198
-	}
199
-
200
-	$liste_statuts = $publie;
201
-	if (defined('_VAR_PREVIEW') && _VAR_PREVIEW && !$ignore_previsu) {
202
-		$liste_statuts = $previsu;
203
-	}
204
-	$not = false;
205
-	if (str_starts_with($liste_statuts, '!')) {
206
-		$not = true;
207
-		$liste_statuts = substr($liste_statuts, 1);
208
-	}
209
-	// '' => ne rien afficher, '!'=> ne rien filtrer
210
-	if (!strlen($liste_statuts)) {
211
-		return $cond[$key] = ($not ? '1=1' : '0=1');
212
-	}
213
-
214
-	$liste_statuts = explode(',', $liste_statuts);
215
-	$where = [];
216
-	foreach ($liste_statuts as $k => $v) {
217
-		// filtrage /auteur pour limiter les objets d'un statut (prepa en general)
218
-		// a ceux de l'auteur identifie
219
-		if (str_contains($v, '/')) {
220
-			$v = explode('/', $v);
221
-			$filtre = end($v);
222
-			$v = reset($v);
223
-			$v = preg_replace(',\W,', '', $v);
224
-			if (
225
-				$filtre == 'auteur'
226
-				&& str_contains($mstatut, '.')
227
-				&& ($objet = explode('.', $mstatut))
228
-				&& ($id_table = reset($objet))
229
-				&& ($objet = objet_type($id_table))
230
-			) {
231
-				$w = "$mstatut<>" . sql_quote($v);
232
-
233
-				// retrouver l’id_auteur qui a filé un lien de prévisu éventuellement,
234
-				// sinon l’auteur en session
235
-				include_spip('inc/securiser_action');
236
-				if ($desc = decrire_token_previsu()) {
237
-					$id_auteur = $desc['id_auteur'];
238
-				} elseif (isset($GLOBALS['visiteur_session']['id_auteur'])) {
239
-					$id_auteur = (int) $GLOBALS['visiteur_session']['id_auteur'];
240
-				} else {
241
-					$id_auteur = null;
242
-				}
243
-
244
-				// dans ce cas (admin en general), pas de filtrage sur ce statut
245
-				if (!autoriser('previsualiser' . $v, $objet, '', $id_auteur)) {
246
-					// si pas d'auteur identifie pas de sous-requete car pas d'article qui matche
247
-					if (!$id_auteur) {
248
-						$where[] = $w;
249
-					} else {
250
-						$primary = id_table_objet($objet);
251
-						$where[] = "($w OR $id_table.$primary IN (" . sql_get_select(
252
-							'ssss.id_objet',
253
-							'spip_auteurs_liens AS ssss',
254
-							'ssss.objet=' . sql_quote($objet) . ' AND ssss.id_auteur=' . (int) $id_auteur,
255
-							'',
256
-							'',
257
-							'',
258
-							'',
259
-							$serveur
260
-						) . '))';
261
-					}
262
-				}
263
-			} // ignorer ce statut si on ne sait pas comment le filtrer
264
-			else {
265
-				$v = '';
266
-			}
267
-		}
268
-		// securite
269
-		$liste_statuts[$k] = preg_replace(',\W,', '', $v);
270
-	}
271
-	$liste_statuts = array_filter($liste_statuts);
272
-	if (count($liste_statuts) == 1) {
273
-		$where[] = ['=', $mstatut, sql_quote(reset($liste_statuts), $serveur)];
274
-	} else {
275
-		$where[] = sql_in($mstatut, $liste_statuts, $not, $serveur);
276
-	}
277
-
278
-	while (count($where) > 1) {
279
-		$and = ['AND', array_pop($where), array_pop($where)];
280
-		$where[] = $and;
281
-	}
282
-	$cond[$key] = reset($where);
283
-	if ($not) {
284
-		$cond[$key] = ['NOT', $cond[$key]];
285
-	}
286
-
287
-	return $cond[$key];
193
+    static $cond = [];
194
+    $key = func_get_args();
195
+    $key = implode('-', $key);
196
+    if (isset($cond[$key])) {
197
+        return $cond[$key];
198
+    }
199
+
200
+    $liste_statuts = $publie;
201
+    if (defined('_VAR_PREVIEW') && _VAR_PREVIEW && !$ignore_previsu) {
202
+        $liste_statuts = $previsu;
203
+    }
204
+    $not = false;
205
+    if (str_starts_with($liste_statuts, '!')) {
206
+        $not = true;
207
+        $liste_statuts = substr($liste_statuts, 1);
208
+    }
209
+    // '' => ne rien afficher, '!'=> ne rien filtrer
210
+    if (!strlen($liste_statuts)) {
211
+        return $cond[$key] = ($not ? '1=1' : '0=1');
212
+    }
213
+
214
+    $liste_statuts = explode(',', $liste_statuts);
215
+    $where = [];
216
+    foreach ($liste_statuts as $k => $v) {
217
+        // filtrage /auteur pour limiter les objets d'un statut (prepa en general)
218
+        // a ceux de l'auteur identifie
219
+        if (str_contains($v, '/')) {
220
+            $v = explode('/', $v);
221
+            $filtre = end($v);
222
+            $v = reset($v);
223
+            $v = preg_replace(',\W,', '', $v);
224
+            if (
225
+                $filtre == 'auteur'
226
+                && str_contains($mstatut, '.')
227
+                && ($objet = explode('.', $mstatut))
228
+                && ($id_table = reset($objet))
229
+                && ($objet = objet_type($id_table))
230
+            ) {
231
+                $w = "$mstatut<>" . sql_quote($v);
232
+
233
+                // retrouver l’id_auteur qui a filé un lien de prévisu éventuellement,
234
+                // sinon l’auteur en session
235
+                include_spip('inc/securiser_action');
236
+                if ($desc = decrire_token_previsu()) {
237
+                    $id_auteur = $desc['id_auteur'];
238
+                } elseif (isset($GLOBALS['visiteur_session']['id_auteur'])) {
239
+                    $id_auteur = (int) $GLOBALS['visiteur_session']['id_auteur'];
240
+                } else {
241
+                    $id_auteur = null;
242
+                }
243
+
244
+                // dans ce cas (admin en general), pas de filtrage sur ce statut
245
+                if (!autoriser('previsualiser' . $v, $objet, '', $id_auteur)) {
246
+                    // si pas d'auteur identifie pas de sous-requete car pas d'article qui matche
247
+                    if (!$id_auteur) {
248
+                        $where[] = $w;
249
+                    } else {
250
+                        $primary = id_table_objet($objet);
251
+                        $where[] = "($w OR $id_table.$primary IN (" . sql_get_select(
252
+                            'ssss.id_objet',
253
+                            'spip_auteurs_liens AS ssss',
254
+                            'ssss.objet=' . sql_quote($objet) . ' AND ssss.id_auteur=' . (int) $id_auteur,
255
+                            '',
256
+                            '',
257
+                            '',
258
+                            '',
259
+                            $serveur
260
+                        ) . '))';
261
+                    }
262
+                }
263
+            } // ignorer ce statut si on ne sait pas comment le filtrer
264
+            else {
265
+                $v = '';
266
+            }
267
+        }
268
+        // securite
269
+        $liste_statuts[$k] = preg_replace(',\W,', '', $v);
270
+    }
271
+    $liste_statuts = array_filter($liste_statuts);
272
+    if (count($liste_statuts) == 1) {
273
+        $where[] = ['=', $mstatut, sql_quote(reset($liste_statuts), $serveur)];
274
+    } else {
275
+        $where[] = sql_in($mstatut, $liste_statuts, $not, $serveur);
276
+    }
277
+
278
+    while (count($where) > 1) {
279
+        $and = ['AND', array_pop($where), array_pop($where)];
280
+        $where[] = $and;
281
+    }
282
+    $cond[$key] = reset($where);
283
+    if ($not) {
284
+        $cond[$key] = ['NOT', $cond[$key]];
285
+    }
286
+
287
+    return $cond[$key];
288 288
 }
289 289
 
290 290
 /**
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
  * @return array|bool|null
296 296
  */
297 297
 function quete_fichier($id_document, $serveur = '') {
298
-	return sql_getfetsel('fichier', 'spip_documents', ('id_document=' . (int) $id_document), '', [], '', '', $serveur);
298
+    return sql_getfetsel('fichier', 'spip_documents', ('id_document=' . (int) $id_document), '', [], '', '', $serveur);
299 299
 }
300 300
 
301 301
 /**
@@ -306,7 +306,7 @@  discard block
 block discarded – undo
306 306
  * @return array|bool
307 307
  */
308 308
 function quete_document($id_document, $serveur = '') {
309
-	return sql_fetsel('*', 'spip_documents', ('id_document=' . (int) $id_document), '', [], '', '', $serveur);
309
+    return sql_fetsel('*', 'spip_documents', ('id_document=' . (int) $id_document), '', [], '', '', $serveur);
310 310
 }
311 311
 
312 312
 /**
@@ -317,7 +317,7 @@  discard block
 block discarded – undo
317 317
  * @return array|bool|null
318 318
  */
319 319
 function quete_meta($nom, $serveur) {
320
-	return sql_getfetsel('valeur', 'spip_meta', 'nom=' . sql_quote($nom), '', '', '', '', $serveur);
320
+    return sql_getfetsel('valeur', 'spip_meta', 'nom=' . sql_quote($nom), '', '', '', '', $serveur);
321 321
 }
322 322
 
323 323
 /**
@@ -343,67 +343,67 @@  discard block
 block discarded – undo
343 343
  *     Retourne soit un tableau, soit le chemin du fichier.
344 344
  */
345 345
 function quete_logo($cle_objet, $onoff, $id, $id_rubrique, $flag = false) {
346
-	include_spip('base/objets');
347
-	$nom = strtolower($onoff);
348
-
349
-	$cle_objet = id_table_objet($cle_objet);
350
-
351
-	while (1) {
352
-		$objet = objet_type($cle_objet);
353
-
354
-		$on = quete_logo_objet($id, $objet, $nom);
355
-
356
-		if ($on) {
357
-			if ($flag) {
358
-				return $on['fichier'];
359
-			} else {
360
-				$taille = @spip_getimagesize($on['chemin']);
361
-
362
-				// Si on a déjà demandé un survol directement ($onoff = off)
363
-				// ou qu'on a demandé uniquement le normal ($onoff = on)
364
-				// alors on ne cherche pas du tout le survol ici
365
-				$off = $onoff != 'ON' ? '' : quete_logo_objet($id, $objet, 'off');
366
-
367
-				// on retourne une url du type IMG/artonXX?timestamp
368
-				// qui permet de distinguer le changement de logo
369
-				// et placer un expire sur le dossier IMG/
370
-				$res = [
371
-					$on['chemin'] . ($on['timestamp'] ? "?{$on['timestamp']}" : ''),
372
-					($off ? $off['chemin'] . ($off['timestamp'] ? "?{$off['timestamp']}" : '') : ''),
373
-					($taille ? ' ' . $taille[3] : (''))
374
-				];
375
-				$res['src'] = $res[0];
376
-				$res['logo_on'] = $res[0];
377
-				$res['logo_off'] = $res[1];
378
-				$res['width'] = ($taille ? $taille[0] : '');
379
-				$res['height'] = ($taille ? $taille[1] : '');
380
-				$res['fichier'] = $on['fichier'];
381
-				$res['titre'] = ($on['titre'] ?? '');
382
-				$res['descriptif'] = ($on['descriptif'] ?? '');
383
-				$res['credits'] = ($on['credits'] ?? '');
384
-				$res['alt'] = ($on['alt'] ?? '');
385
-				$res['id'] = ($on['id_document'] ?? 0);
386
-
387
-				return $res;
388
-			}
389
-		} else {
390
-			if (defined('_LOGO_RUBRIQUE_DESACTIVER_HERITAGE')) {
391
-				return '';
392
-			} else {
393
-				if ($id_rubrique) {
394
-					$cle_objet = 'id_rubrique';
395
-					$id = $id_rubrique;
396
-					$id_rubrique = 0;
397
-				} else {
398
-					if ($id && $cle_objet == 'id_rubrique') {
399
-						$id = quete_parent($id);
400
-					} else {
401
-						return '';
402
-					}
403
-				}
404
-			}
405
-		}
406
-	}
346
+    include_spip('base/objets');
347
+    $nom = strtolower($onoff);
348
+
349
+    $cle_objet = id_table_objet($cle_objet);
350
+
351
+    while (1) {
352
+        $objet = objet_type($cle_objet);
353
+
354
+        $on = quete_logo_objet($id, $objet, $nom);
355
+
356
+        if ($on) {
357
+            if ($flag) {
358
+                return $on['fichier'];
359
+            } else {
360
+                $taille = @spip_getimagesize($on['chemin']);
361
+
362
+                // Si on a déjà demandé un survol directement ($onoff = off)
363
+                // ou qu'on a demandé uniquement le normal ($onoff = on)
364
+                // alors on ne cherche pas du tout le survol ici
365
+                $off = $onoff != 'ON' ? '' : quete_logo_objet($id, $objet, 'off');
366
+
367
+                // on retourne une url du type IMG/artonXX?timestamp
368
+                // qui permet de distinguer le changement de logo
369
+                // et placer un expire sur le dossier IMG/
370
+                $res = [
371
+                    $on['chemin'] . ($on['timestamp'] ? "?{$on['timestamp']}" : ''),
372
+                    ($off ? $off['chemin'] . ($off['timestamp'] ? "?{$off['timestamp']}" : '') : ''),
373
+                    ($taille ? ' ' . $taille[3] : (''))
374
+                ];
375
+                $res['src'] = $res[0];
376
+                $res['logo_on'] = $res[0];
377
+                $res['logo_off'] = $res[1];
378
+                $res['width'] = ($taille ? $taille[0] : '');
379
+                $res['height'] = ($taille ? $taille[1] : '');
380
+                $res['fichier'] = $on['fichier'];
381
+                $res['titre'] = ($on['titre'] ?? '');
382
+                $res['descriptif'] = ($on['descriptif'] ?? '');
383
+                $res['credits'] = ($on['credits'] ?? '');
384
+                $res['alt'] = ($on['alt'] ?? '');
385
+                $res['id'] = ($on['id_document'] ?? 0);
386
+
387
+                return $res;
388
+            }
389
+        } else {
390
+            if (defined('_LOGO_RUBRIQUE_DESACTIVER_HERITAGE')) {
391
+                return '';
392
+            } else {
393
+                if ($id_rubrique) {
394
+                    $cle_objet = 'id_rubrique';
395
+                    $id = $id_rubrique;
396
+                    $id_rubrique = 0;
397
+                } else {
398
+                    if ($id && $cle_objet == 'id_rubrique') {
399
+                        $id = quete_parent($id);
400
+                    } else {
401
+                        return '';
402
+                    }
403
+                }
404
+            }
405
+        }
406
+    }
407 407
 }
408 408
 
409 409
 /**
@@ -418,43 +418,43 @@  discard block
 block discarded – undo
418 418
  * @return bool|array
419 419
  **/
420 420
 function quete_logo_objet($id_objet, $objet, $mode) {
421
-	static $chercher_logo;
422
-	if (is_null($chercher_logo)) {
423
-		$chercher_logo = charger_fonction('chercher_logo', 'inc');
424
-	}
425
-	$cle_objet = id_table_objet($objet);
426
-
427
-	// On cherche pas la méthode classique
428
-	$infos_logo = $chercher_logo($id_objet, $cle_objet, $mode);
429
-
430
-	// Si la méthode classique a trouvé quelque chose, on utilise le nouveau format
431
-	if (!empty($infos_logo)) {
432
-		$infos = [
433
-			'chemin' => $infos_logo[0],
434
-			'timestamp' => $infos_logo[4],
435
-			'id_document' => ($infos_logo[5]['id_document'] ?? ''),
436
-		];
437
-		foreach (['fichier', 'titre', 'descriptif', 'credits', 'alt'] as $champ) {
438
-			$infos[$champ] = ($infos_logo[5][$champ] ?? '');
439
-		}
440
-		$infos_logo = $infos;
441
-	}
442
-
443
-	// On passe cette recherche de logo dans un pipeline
444
-	$infos_logo = pipeline(
445
-		'quete_logo_objet',
446
-		[
447
-			'args' => [
448
-				'id_objet' => $id_objet,
449
-				'objet' => $objet,
450
-				'cle_objet' => $cle_objet,
451
-				'mode' => $mode,
452
-			],
453
-			'data' => $infos_logo,
454
-		]
455
-	);
456
-
457
-	return $infos_logo;
421
+    static $chercher_logo;
422
+    if (is_null($chercher_logo)) {
423
+        $chercher_logo = charger_fonction('chercher_logo', 'inc');
424
+    }
425
+    $cle_objet = id_table_objet($objet);
426
+
427
+    // On cherche pas la méthode classique
428
+    $infos_logo = $chercher_logo($id_objet, $cle_objet, $mode);
429
+
430
+    // Si la méthode classique a trouvé quelque chose, on utilise le nouveau format
431
+    if (!empty($infos_logo)) {
432
+        $infos = [
433
+            'chemin' => $infos_logo[0],
434
+            'timestamp' => $infos_logo[4],
435
+            'id_document' => ($infos_logo[5]['id_document'] ?? ''),
436
+        ];
437
+        foreach (['fichier', 'titre', 'descriptif', 'credits', 'alt'] as $champ) {
438
+            $infos[$champ] = ($infos_logo[5][$champ] ?? '');
439
+        }
440
+        $infos_logo = $infos;
441
+    }
442
+
443
+    // On passe cette recherche de logo dans un pipeline
444
+    $infos_logo = pipeline(
445
+        'quete_logo_objet',
446
+        [
447
+            'args' => [
448
+                'id_objet' => $id_objet,
449
+                'objet' => $objet,
450
+                'cle_objet' => $cle_objet,
451
+                'mode' => $mode,
452
+            ],
453
+            'data' => $infos_logo,
454
+        ]
455
+    );
456
+
457
+    return $infos_logo;
458 458
 }
459 459
 
460 460
 /**
@@ -467,25 +467,25 @@  discard block
 block discarded – undo
467 467
  * @return bool|string
468 468
  */
469 469
 function quete_logo_file($row, $connect = null) {
470
-	include_spip('inc/documents');
471
-	$logo = vignette_logo_document($row, $connect);
472
-	if (!$logo) {
473
-		$logo = image_du_document($row, $connect);
474
-	}
475
-	if (!$logo) {
476
-		$f = charger_fonction('vignette', 'inc');
477
-		$logo = $f($row['extension'], false);
478
-	}
479
-	// si c'est une vignette type doc, la renvoyer direct
480
-	if (
481
-		strcmp($logo, _DIR_PLUGINS) == 0
482
-		|| strcmp($logo, _DIR_PLUGINS_DIST) == 0
483
-		|| strcmp($logo, _DIR_RACINE . 'prive/') == 0
484
-	) {
485
-		return $logo;
486
-	}
487
-
488
-	return get_spip_doc($logo);
470
+    include_spip('inc/documents');
471
+    $logo = vignette_logo_document($row, $connect);
472
+    if (!$logo) {
473
+        $logo = image_du_document($row, $connect);
474
+    }
475
+    if (!$logo) {
476
+        $f = charger_fonction('vignette', 'inc');
477
+        $logo = $f($row['extension'], false);
478
+    }
479
+    // si c'est une vignette type doc, la renvoyer direct
480
+    if (
481
+        strcmp($logo, _DIR_PLUGINS) == 0
482
+        || strcmp($logo, _DIR_PLUGINS_DIST) == 0
483
+        || strcmp($logo, _DIR_RACINE . 'prive/') == 0
484
+    ) {
485
+        return $logo;
486
+    }
487
+
488
+    return get_spip_doc($logo);
489 489
 }
490 490
 
491 491
 /**
@@ -513,20 +513,20 @@  discard block
 block discarded – undo
513 513
  */
514 514
 function quete_logo_document($row, $lien, $align, $mode_logo, $x, $y, string $connect = '') {
515 515
 
516
-	include_spip('inc/documents');
517
-	$logo = '';
518
-	if (!in_array($mode_logo, ['icone', 'apercu'])) {
519
-		$logo = vignette_logo_document($row, $connect);
520
-	}
521
-	// si on veut explicitement la vignette, ne rien renvoyer si il n'y en a pas
522
-	if ($mode_logo == 'vignette' && !$logo) {
523
-		return '';
524
-	}
525
-	if ($mode_logo == 'icone') {
526
-		$row['fichier'] = '';
527
-	}
528
-
529
-	return vignette_automatique($logo, $row, $lien, $x, $y, $align, null, $connect);
516
+    include_spip('inc/documents');
517
+    $logo = '';
518
+    if (!in_array($mode_logo, ['icone', 'apercu'])) {
519
+        $logo = vignette_logo_document($row, $connect);
520
+    }
521
+    // si on veut explicitement la vignette, ne rien renvoyer si il n'y en a pas
522
+    if ($mode_logo == 'vignette' && !$logo) {
523
+        return '';
524
+    }
525
+    if ($mode_logo == 'icone') {
526
+        $row['fichier'] = '';
527
+    }
528
+
529
+    return vignette_automatique($logo, $row, $lien, $x, $y, $align, null, $connect);
530 530
 }
531 531
 
532 532
 /**
@@ -538,26 +538,26 @@  discard block
 block discarded – undo
538 538
  */
539 539
 function quete_html_logo($logo, $align, $lien) {
540 540
 
541
-	if (!is_array($logo)) {
542
-		return '';
543
-	}
544
-
545
-	$contexte = [];
546
-	foreach ($logo as $k => $v) {
547
-		if (!is_numeric($k)) {
548
-			$contexte[$k] = $v;
549
-		}
550
-	}
551
-
552
-	foreach (['titre', 'descriptif', 'credits', 'alt'] as $champ) {
553
-		if (!empty($contexte[$champ])) {
554
-			$contexte[$champ] = appliquer_traitement_champ($contexte[$champ], $champ, 'document');
555
-		}
556
-	}
557
-
558
-	$contexte['align'] = $align;
559
-	$contexte['lien'] = $lien;
560
-	return recuperer_fond('modeles/logo', $contexte);
541
+    if (!is_array($logo)) {
542
+        return '';
543
+    }
544
+
545
+    $contexte = [];
546
+    foreach ($logo as $k => $v) {
547
+        if (!is_numeric($k)) {
548
+            $contexte[$k] = $v;
549
+        }
550
+    }
551
+
552
+    foreach (['titre', 'descriptif', 'credits', 'alt'] as $champ) {
553
+        if (!empty($contexte[$champ])) {
554
+            $contexte[$champ] = appliquer_traitement_champ($contexte[$champ], $champ, 'document');
555
+        }
556
+    }
557
+
558
+    $contexte['align'] = $align;
559
+    $contexte['lien'] = $lien;
560
+    return recuperer_fond('modeles/logo', $contexte);
561 561
 }
562 562
 
563 563
 /**
@@ -571,14 +571,14 @@  discard block
 block discarded – undo
571 571
  * @return string|false
572 572
  */
573 573
 function document_spip_externe($fichier, $connect) {
574
-	if ($connect) {
575
-		$site = quete_meta('adresse_site', $connect);
576
-		if ($site) {
577
-			$dir = quete_meta('dir_img', $connect);
578
-			return "$site/$dir$fichier";
579
-		}
580
-	}
581
-	return false;
574
+    if ($connect) {
575
+        $site = quete_meta('adresse_site', $connect);
576
+        if ($site) {
577
+            $dir = quete_meta('dir_img', $connect);
578
+            return "$site/$dir$fichier";
579
+        }
580
+    }
581
+    return false;
582 582
 }
583 583
 
584 584
 /**
@@ -591,23 +591,23 @@  discard block
 block discarded – undo
591 591
  */
592 592
 function vignette_logo_document($row, string $connect = '') {
593 593
 
594
-	if (!$row || empty($row['id_vignette'])) {
595
-		return '';
596
-	}
597
-	$fichier = quete_fichier($row['id_vignette'], $connect);
598
-	if ($url = document_spip_externe($fichier, $connect)) {
599
-		return $url;
600
-	}
601
-
602
-	$f = get_spip_doc($fichier);
603
-	if ($f && @file_exists($f)) {
604
-		return $f;
605
-	}
606
-	if ($row['mode'] !== 'vignette') {
607
-		return '';
608
-	}
609
-
610
-	return generer_objet_url($row['id_document'], 'document', '', '', null, '', $connect);
594
+    if (!$row || empty($row['id_vignette'])) {
595
+        return '';
596
+    }
597
+    $fichier = quete_fichier($row['id_vignette'], $connect);
598
+    if ($url = document_spip_externe($fichier, $connect)) {
599
+        return $url;
600
+    }
601
+
602
+    $f = get_spip_doc($fichier);
603
+    if ($f && @file_exists($f)) {
604
+        return $f;
605
+    }
606
+    if ($row['mode'] !== 'vignette') {
607
+        return '';
608
+    }
609
+
610
+    return generer_objet_url($row['id_document'], 'document', '', '', null, '', $connect);
611 611
 }
612 612
 
613 613
 /**
@@ -622,66 +622,66 @@  discard block
 block discarded – undo
622 622
  * @return bool|string
623 623
  */
624 624
 function calcul_exposer($id, $prim, $reference, $parent, $type, string $connect = '') {
625
-	static $exposer = [];
626
-
627
-	// Que faut-il exposer ? Tous les elements de $reference
628
-	// ainsi que leur hierarchie ; on ne fait donc ce calcul
629
-	// qu'une fois (par squelette) et on conserve le resultat
630
-	// en static.
631
-	if (!isset($exposer[$m = md5(serialize($reference))][$prim])) {
632
-		$principal = $reference[$type] ?? $reference["@$type"] ?? '';
633
-		// le parent fournit en argument est le parent de $id, pas celui de $principal
634
-		// il n'est donc pas utile
635
-		$parent = 0;
636
-		if (!$principal) { // regarder si un enfant est dans le contexte, auquel cas il expose peut etre le parent courant
637
-			$enfants = ['id_rubrique' => ['id_article'], 'id_groupe' => ['id_mot']];
638
-			if (isset($enfants[$type])) {
639
-				foreach ($enfants[$type] as $t) {
640
-					if (
641
-						isset($reference[$t])
642
-						// cas de la reference donnee dynamiquement par la pagination
643
-						|| isset($reference["@$t"])
644
-					) {
645
-						$type = $t;
646
-						$principal = $reference[$type] ?? $reference["@$type"];
647
-						continue;
648
-					}
649
-				}
650
-			}
651
-		}
652
-		$exposer[$m][$type] = [];
653
-		if ($principal) {
654
-			$principaux = is_array($principal) ? $principal : [$principal];
655
-			foreach ($principaux as $principal) {
656
-				$exposer[$m][$type][$principal] = true;
657
-				if ($type == 'id_mot') {
658
-					if (!$parent) {
659
-						$parent = sql_getfetsel('id_groupe', 'spip_mots', 'id_mot=' . (int) $principal, '', '', '', '', $connect);
660
-					}
661
-					if ($parent) {
662
-						$exposer[$m]['id_groupe'][$parent] = true;
663
-					}
664
-				} else {
665
-					if ($type != 'id_groupe') {
666
-						if (!$parent) {
667
-							if ($type == 'id_rubrique') {
668
-								$parent = $principal;
669
-							}
670
-							if ($type == 'id_article') {
671
-								$parent = quete_rubrique($principal, $connect);
672
-							}
673
-						}
674
-						do {
675
-							$exposer[$m]['id_rubrique'][$parent] = true;
676
-						} while ($parent = quete_parent($parent, $connect));
677
-					}
678
-				}
679
-			}
680
-		}
681
-	}
682
-
683
-	// And the winner is...
684
-	return isset($exposer[$m][$prim]) ? isset($exposer[$m][$prim][$id]) : '';
625
+    static $exposer = [];
626
+
627
+    // Que faut-il exposer ? Tous les elements de $reference
628
+    // ainsi que leur hierarchie ; on ne fait donc ce calcul
629
+    // qu'une fois (par squelette) et on conserve le resultat
630
+    // en static.
631
+    if (!isset($exposer[$m = md5(serialize($reference))][$prim])) {
632
+        $principal = $reference[$type] ?? $reference["@$type"] ?? '';
633
+        // le parent fournit en argument est le parent de $id, pas celui de $principal
634
+        // il n'est donc pas utile
635
+        $parent = 0;
636
+        if (!$principal) { // regarder si un enfant est dans le contexte, auquel cas il expose peut etre le parent courant
637
+            $enfants = ['id_rubrique' => ['id_article'], 'id_groupe' => ['id_mot']];
638
+            if (isset($enfants[$type])) {
639
+                foreach ($enfants[$type] as $t) {
640
+                    if (
641
+                        isset($reference[$t])
642
+                        // cas de la reference donnee dynamiquement par la pagination
643
+                        || isset($reference["@$t"])
644
+                    ) {
645
+                        $type = $t;
646
+                        $principal = $reference[$type] ?? $reference["@$type"];
647
+                        continue;
648
+                    }
649
+                }
650
+            }
651
+        }
652
+        $exposer[$m][$type] = [];
653
+        if ($principal) {
654
+            $principaux = is_array($principal) ? $principal : [$principal];
655
+            foreach ($principaux as $principal) {
656
+                $exposer[$m][$type][$principal] = true;
657
+                if ($type == 'id_mot') {
658
+                    if (!$parent) {
659
+                        $parent = sql_getfetsel('id_groupe', 'spip_mots', 'id_mot=' . (int) $principal, '', '', '', '', $connect);
660
+                    }
661
+                    if ($parent) {
662
+                        $exposer[$m]['id_groupe'][$parent] = true;
663
+                    }
664
+                } else {
665
+                    if ($type != 'id_groupe') {
666
+                        if (!$parent) {
667
+                            if ($type == 'id_rubrique') {
668
+                                $parent = $principal;
669
+                            }
670
+                            if ($type == 'id_article') {
671
+                                $parent = quete_rubrique($principal, $connect);
672
+                            }
673
+                        }
674
+                        do {
675
+                            $exposer[$m]['id_rubrique'][$parent] = true;
676
+                        } while ($parent = quete_parent($parent, $connect));
677
+                    }
678
+                }
679
+            }
680
+        }
681
+    }
682
+
683
+    // And the winner is...
684
+    return isset($exposer[$m][$prim]) ? isset($exposer[$m][$prim][$id]) : '';
685 685
 }
686 686
 
687 687
 /**
@@ -696,23 +696,23 @@  discard block
 block discarded – undo
696 696
  * @return int
697 697
  */
698 698
 function quete_debut_pagination($primary, $valeur, $pas, $iter) {
699
-	// on ne devrait pas arriver ici si la cle primaire est inexistante
700
-	// ou composee, mais verifions
701
-	if (!$primary || preg_match('/[,\s]/', $primary)) {
702
-		return 0;
703
-	}
704
-
705
-	$pos = 0;
706
-	while (($row = $iter->fetch()) && $row[$primary] != $valeur) {
707
-		$pos++;
708
-	}
709
-	// si on a pas trouve
710
-	if (!$row || $row[$primary] != $valeur) {
711
-		return 0;
712
-	}
713
-
714
-	// sinon, calculer le bon numero de page
715
-	return floor($pos / $pas) * $pas;
699
+    // on ne devrait pas arriver ici si la cle primaire est inexistante
700
+    // ou composee, mais verifions
701
+    if (!$primary || preg_match('/[,\s]/', $primary)) {
702
+        return 0;
703
+    }
704
+
705
+    $pos = 0;
706
+    while (($row = $iter->fetch()) && $row[$primary] != $valeur) {
707
+        $pos++;
708
+    }
709
+    // si on a pas trouve
710
+    if (!$row || $row[$primary] != $valeur) {
711
+        return 0;
712
+    }
713
+
714
+    // sinon, calculer le bon numero de page
715
+    return floor($pos / $pas) * $pas;
716 716
 }
717 717
 
718 718
 /**
@@ -722,8 +722,8 @@  discard block
 block discarded – undo
722 722
  * @return boolean
723 723
  */
724 724
 function is_whereable(mixed $value): bool {
725
-	if (is_array($value) && count($value)) {
726
-		return true;
727
-	}
728
-	return is_scalar($value) && strlen($value);
725
+    if (is_array($value) && count($value)) {
726
+        return true;
727
+    }
728
+    return is_scalar($value) && strlen($value);
729 729
 }
Please login to merge, or discard this patch.
ecrire/public/sandbox.php 1 patch
Indentation   +89 added lines, -89 removed lines patch added patch discarded remove patch
@@ -22,7 +22,7 @@  discard block
 block discarded – undo
22 22
  **/
23 23
 
24 24
 if (!defined('_ECRIRE_INC_VERSION')) {
25
-	return;
25
+    return;
26 26
 }
27 27
 
28 28
 /**
@@ -40,7 +40,7 @@  discard block
 block discarded – undo
40 40
  *     texte
41 41
  */
42 42
 function sandbox_composer_texte($texte, &$p) {
43
-	return "'" . str_replace(['\\', "'"], ['\\\\', "\\'"], $texte) . "'";
43
+    return "'" . str_replace(['\\', "'"], ['\\\\', "\\'"], $texte) . "'";
44 44
 }
45 45
 
46 46
 
@@ -56,38 +56,38 @@  discard block
 block discarded – undo
56 56
  * @return string
57 57
  */
58 58
 function sandbox_composer_filtre($fonc, $code, $arglist, &$p, $nb_arg_droite = 1000): string {
59
-	if (isset($GLOBALS['spip_matrice'][$fonc])) {
60
-		$code = "filtrer('$fonc',$code$arglist)";
61
-	}
62
-
63
-	// le filtre est defini sous forme de fonction ou de methode
64
-	// par ex. dans inc_texte, inc_filtres ou mes_fonctions
65
-	elseif ($f = chercher_filtre($fonc)) {
66
-		// cas particulier : le filtre |set doit acceder a la $Pile
67
-		// proto: filtre_set(&$Pile, $val, $args...)
68
-		$refl = strpbrk($f, ':') ? new ReflectionMethod($f) : new ReflectionFunction($f);
69
-		$refs = $refl->getParameters();
70
-		if (isset($refs[0]) && $refs[0]->name == 'Pile') {
71
-			$code = "$f(\$Pile,$code$arglist)";
72
-			$nb_arg_gauche = 2; // la balise à laquelle s'applique le filtre + $Pile
73
-		} else {
74
-			$code = "$f($code$arglist)";
75
-			$nb_arg_gauche = 1; // la balise à laquelle s'applique le filtre
76
-		}
77
-		$nb_args_f = $nb_arg_gauche + $nb_arg_droite;
78
-		$min_f = $refl->getNumberOfRequiredParameters();
79
-		if (($nb_args_f < $min_f)) {
80
-			$msg_args = ['filtre' => texte_script($fonc), 'nb' => $min_f - $nb_args_f];
81
-			erreur_squelette([ 'zbug_erreur_filtre_nbarg_min', $msg_args], $p);
82
-		}
83
-	}
84
-	// le filtre n'existe pas,
85
-	// on le notifie
86
-	else {
87
-		erreur_squelette(['zbug_erreur_filtre', ['filtre' => texte_script($fonc)]], $p);
88
-	}
89
-
90
-	return $code;
59
+    if (isset($GLOBALS['spip_matrice'][$fonc])) {
60
+        $code = "filtrer('$fonc',$code$arglist)";
61
+    }
62
+
63
+    // le filtre est defini sous forme de fonction ou de methode
64
+    // par ex. dans inc_texte, inc_filtres ou mes_fonctions
65
+    elseif ($f = chercher_filtre($fonc)) {
66
+        // cas particulier : le filtre |set doit acceder a la $Pile
67
+        // proto: filtre_set(&$Pile, $val, $args...)
68
+        $refl = strpbrk($f, ':') ? new ReflectionMethod($f) : new ReflectionFunction($f);
69
+        $refs = $refl->getParameters();
70
+        if (isset($refs[0]) && $refs[0]->name == 'Pile') {
71
+            $code = "$f(\$Pile,$code$arglist)";
72
+            $nb_arg_gauche = 2; // la balise à laquelle s'applique le filtre + $Pile
73
+        } else {
74
+            $code = "$f($code$arglist)";
75
+            $nb_arg_gauche = 1; // la balise à laquelle s'applique le filtre
76
+        }
77
+        $nb_args_f = $nb_arg_gauche + $nb_arg_droite;
78
+        $min_f = $refl->getNumberOfRequiredParameters();
79
+        if (($nb_args_f < $min_f)) {
80
+            $msg_args = ['filtre' => texte_script($fonc), 'nb' => $min_f - $nb_args_f];
81
+            erreur_squelette([ 'zbug_erreur_filtre_nbarg_min', $msg_args], $p);
82
+        }
83
+    }
84
+    // le filtre n'existe pas,
85
+    // on le notifie
86
+    else {
87
+        erreur_squelette(['zbug_erreur_filtre', ['filtre' => texte_script($fonc)]], $p);
88
+    }
89
+
90
+    return $code;
91 91
 }
92 92
 
93 93
 // Calculer un <INCLURE(xx.php)>
@@ -110,11 +110,11 @@  discard block
 block discarded – undo
110 110
  * @return string
111 111
  */
112 112
 function sandbox_composer_inclure_php($fichier, &$p, $_contexte) {
113
-	$compil = texte_script(memoriser_contexte_compil($p));
114
-	// si inexistant, on essaiera a l'execution
115
-	$path = ($path = find_in_path($fichier)) ? "\"$path\"" : "find_in_path(\"$fichier\")";
113
+    $compil = texte_script(memoriser_contexte_compil($p));
114
+    // si inexistant, on essaiera a l'execution
115
+    $path = ($path = find_in_path($fichier)) ? "\"$path\"" : "find_in_path(\"$fichier\")";
116 116
 
117
-	return sprintf(CODE_INCLURE_SCRIPT, $path, $fichier, $compil, $_contexte);
117
+    return sprintf(CODE_INCLURE_SCRIPT, $path, $fichier, $compil, $_contexte);
118 118
 }
119 119
 
120 120
 /**
@@ -126,20 +126,20 @@  discard block
 block discarded – undo
126 126
  * @return string
127 127
  */
128 128
 function sandbox_composer_interdire_scripts($code, &$p) {
129
-	// Securite
130
-	if (
131
-		$p->interdire_scripts
132
-		&& $p->etoile != '**'
133
-	) {
134
-		if (!preg_match("/^sinon[(](.*),'([^']*)'[)]$/", $code, $r)) {
135
-			$code = "interdire_scripts($code)";
136
-		} else {
137
-			$code = interdire_scripts($r[2]);
138
-			$code = "sinon(interdire_scripts($r[1]),'$code')";
139
-		}
140
-	}
141
-
142
-	return $code;
129
+    // Securite
130
+    if (
131
+        $p->interdire_scripts
132
+        && $p->etoile != '**'
133
+    ) {
134
+        if (!preg_match("/^sinon[(](.*),'([^']*)'[)]$/", $code, $r)) {
135
+            $code = "interdire_scripts($code)";
136
+        } else {
137
+            $code = interdire_scripts($r[2]);
138
+            $code = "sinon(interdire_scripts($r[1]),'$code')";
139
+        }
140
+    }
141
+
142
+    return $code;
143 143
 }
144 144
 
145 145
 
@@ -158,30 +158,30 @@  discard block
 block discarded – undo
158 158
  * @return mixed|string
159 159
  */
160 160
 function sandbox_filtrer_squelette($skel, $corps, $filtres) {
161
-	$series_filtres = func_get_args();
162
-	array_shift($series_filtres);// skel
163
-	array_shift($series_filtres);// corps
164
-
165
-	// proteger les <INCLUDE> et tous les morceaux de php licites
166
-	if ($skel['process_ins'] == 'php') {
167
-		$corps = preg_replace_callback(',<[?](\s|php|=).*[?]>,UimsS', 'echapper_php_callback', $corps);
168
-	}
169
-
170
-	// recuperer les couples de remplacement
171
-	$replace = echapper_php_callback();
172
-
173
-	foreach ($series_filtres as $filtres) {
174
-		if (is_countable($filtres) ? count($filtres) : 0) {
175
-			foreach ($filtres as $filtre) {
176
-				if ($filtre && ($f = chercher_filtre($filtre))) {
177
-					$corps = $f($corps);
178
-				}
179
-			}
180
-		}
181
-	}
182
-
183
-	// restaurer les echappements
184
-	return str_replace($replace[0], $replace[1], $corps);
161
+    $series_filtres = func_get_args();
162
+    array_shift($series_filtres);// skel
163
+    array_shift($series_filtres);// corps
164
+
165
+    // proteger les <INCLUDE> et tous les morceaux de php licites
166
+    if ($skel['process_ins'] == 'php') {
167
+        $corps = preg_replace_callback(',<[?](\s|php|=).*[?]>,UimsS', 'echapper_php_callback', $corps);
168
+    }
169
+
170
+    // recuperer les couples de remplacement
171
+    $replace = echapper_php_callback();
172
+
173
+    foreach ($series_filtres as $filtres) {
174
+        if (is_countable($filtres) ? count($filtres) : 0) {
175
+            foreach ($filtres as $filtre) {
176
+                if ($filtre && ($f = chercher_filtre($filtre))) {
177
+                    $corps = $f($corps);
178
+                }
179
+            }
180
+        }
181
+    }
182
+
183
+    // restaurer les echappements
184
+    return str_replace($replace[0], $replace[1], $corps);
185 185
 }
186 186
 
187 187
 
@@ -200,21 +200,21 @@  discard block
 block discarded – undo
200 200
  *     - array : Liste( liste des codes PHP, liste des substitutions )
201 201
  **/
202 202
 function echapper_php_callback($r = null) {
203
-	static $src = [];
204
-	static $dst = [];
203
+    static $src = [];
204
+    static $dst = [];
205 205
 
206
-	// si on recoit un tableau, on est en mode echappement
207
-	// on enregistre le code a echapper dans dst, et le code echappe dans src
208
-	if (is_array($r)) {
209
-		$dst[] = $r[0];
206
+    // si on recoit un tableau, on est en mode echappement
207
+    // on enregistre le code a echapper dans dst, et le code echappe dans src
208
+    if (is_array($r)) {
209
+        $dst[] = $r[0];
210 210
 
211
-		return $src[] = '___' . md5($r[0]) . '___';
212
-	}
211
+        return $src[] = '___' . md5($r[0]) . '___';
212
+    }
213 213
 
214
-	// si on recoit pas un tableau, on renvoit les couples de substitution
215
-	// et on RAZ les remplacements
216
-	$r = [$src, $dst];
217
-	$src = $dst = [];
214
+    // si on recoit pas un tableau, on renvoit les couples de substitution
215
+    // et on RAZ les remplacements
216
+    $r = [$src, $dst];
217
+    $src = $dst = [];
218 218
 
219
-	return $r;
219
+    return $r;
220 220
 }
Please login to merge, or discard this patch.
ecrire/public/fonctions.php 1 patch
Indentation   +367 added lines, -367 removed lines patch added patch discarded remove patch
@@ -22,7 +22,7 @@  discard block
 block discarded – undo
22 22
  **/
23 23
 
24 24
 if (!defined('_ECRIRE_INC_VERSION')) {
25
-	return;
25
+    return;
26 26
 }
27 27
 
28 28
 // public/interfaces definit des traitements sur les champs qui utilisent des fonctions de inc/texte
@@ -54,75 +54,75 @@  discard block
 block discarded – undo
54 54
  *     Introduction calculée
55 55
  **/
56 56
 function filtre_introduction_dist($descriptif, $texte, $longueur, $connect, $suite = null) {
57
-	// Si un descriptif est envoye, on l'utilise directement
58
-	if (strlen($descriptif)) {
59
-		return appliquer_traitement_champ($descriptif, 'introduction', '', [], $connect);
60
-	}
61
-
62
-	// De preference ce qui est marque <intro>...</intro>
63
-	$intro = '';
64
-	$texte = preg_replace(',(</?)intro>,i', "\\1intro>", $texte); // minuscules
65
-	while ($fin = strpos($texte, '</intro>')) {
66
-		$zone = substr($texte, 0, $fin);
67
-		$texte = substr($texte, $fin + strlen('</intro>'));
68
-		if (($deb = strpos($zone, '<intro>')) || str_starts_with($zone, '<intro>')) {
69
-			$zone = substr($zone, $deb + 7);
70
-		}
71
-		$intro .= $zone;
72
-	}
73
-
74
-	// [12025] On ne *PEUT* pas couper simplement ici car c'est du texte brut,
75
-	// qui inclus raccourcis et modeles
76
-	// un simple <articlexx> peut etre ensuite transforme en 1000 lignes ...
77
-	// par ailleurs le nettoyage des raccourcis ne tient pas compte
78
-	// des surcharges et enrichissement de propre
79
-	// couper doit se faire apres propre
80
-	//$texte = nettoyer_raccourcis_typo($intro ? $intro : $texte, $connect);
81
-
82
-	// Cependant pour des questions de perfs on coupe quand meme, en prenant
83
-	// large et en se mefiant des tableaux #1323
84
-
85
-	if (strlen($intro)) {
86
-		$texte = $intro;
87
-	} else {
88
-		if (
89
-			!str_contains("\n" . $texte, "\n|")
90
-			&& strlen($texte) > 2.5 * $longueur
91
-		) {
92
-			if (str_contains($texte, '<multi')) {
93
-				$texte = extraire_multi($texte);
94
-			}
95
-			$texte = couper($texte, 2 * $longueur);
96
-		}
97
-	}
98
-
99
-	// ne pas tenir compte des notes
100
-	if ($notes = charger_fonction('notes', 'inc', true)) {
101
-		$notes('', 'empiler');
102
-	}
103
-	// Supprimer les modèles avant le propre afin d'éviter qu'ils n'ajoutent du texte indésirable
104
-	// dans l'introduction.
105
-	$texte = supprime_img($texte, '');
106
-	$texte = appliquer_traitement_champ($texte, 'introduction', '', [], $connect);
107
-
108
-	if ($notes) {
109
-		$notes('', 'depiler');
110
-	}
111
-
112
-	if (is_null($suite) && defined('_INTRODUCTION_SUITE')) {
113
-		$suite = _INTRODUCTION_SUITE;
114
-	}
115
-	$texte = couper($texte, $longueur, $suite);
116
-	// comme on a coupe il faut repasser la typo (on a perdu les insecables)
117
-	$texte = typo($texte, true, $connect, []);
118
-
119
-	// et reparagrapher si necessaire (coherence avec le cas descriptif)
120
-	// une introduction a tojours un <p>
121
-	if ($GLOBALS['toujours_paragrapher']) { // Fermer les paragraphes
122
-	$texte = paragrapher($texte, $GLOBALS['toujours_paragrapher']);
123
-	}
124
-
125
-	return $texte;
57
+    // Si un descriptif est envoye, on l'utilise directement
58
+    if (strlen($descriptif)) {
59
+        return appliquer_traitement_champ($descriptif, 'introduction', '', [], $connect);
60
+    }
61
+
62
+    // De preference ce qui est marque <intro>...</intro>
63
+    $intro = '';
64
+    $texte = preg_replace(',(</?)intro>,i', "\\1intro>", $texte); // minuscules
65
+    while ($fin = strpos($texte, '</intro>')) {
66
+        $zone = substr($texte, 0, $fin);
67
+        $texte = substr($texte, $fin + strlen('</intro>'));
68
+        if (($deb = strpos($zone, '<intro>')) || str_starts_with($zone, '<intro>')) {
69
+            $zone = substr($zone, $deb + 7);
70
+        }
71
+        $intro .= $zone;
72
+    }
73
+
74
+    // [12025] On ne *PEUT* pas couper simplement ici car c'est du texte brut,
75
+    // qui inclus raccourcis et modeles
76
+    // un simple <articlexx> peut etre ensuite transforme en 1000 lignes ...
77
+    // par ailleurs le nettoyage des raccourcis ne tient pas compte
78
+    // des surcharges et enrichissement de propre
79
+    // couper doit se faire apres propre
80
+    //$texte = nettoyer_raccourcis_typo($intro ? $intro : $texte, $connect);
81
+
82
+    // Cependant pour des questions de perfs on coupe quand meme, en prenant
83
+    // large et en se mefiant des tableaux #1323
84
+
85
+    if (strlen($intro)) {
86
+        $texte = $intro;
87
+    } else {
88
+        if (
89
+            !str_contains("\n" . $texte, "\n|")
90
+            && strlen($texte) > 2.5 * $longueur
91
+        ) {
92
+            if (str_contains($texte, '<multi')) {
93
+                $texte = extraire_multi($texte);
94
+            }
95
+            $texte = couper($texte, 2 * $longueur);
96
+        }
97
+    }
98
+
99
+    // ne pas tenir compte des notes
100
+    if ($notes = charger_fonction('notes', 'inc', true)) {
101
+        $notes('', 'empiler');
102
+    }
103
+    // Supprimer les modèles avant le propre afin d'éviter qu'ils n'ajoutent du texte indésirable
104
+    // dans l'introduction.
105
+    $texte = supprime_img($texte, '');
106
+    $texte = appliquer_traitement_champ($texte, 'introduction', '', [], $connect);
107
+
108
+    if ($notes) {
109
+        $notes('', 'depiler');
110
+    }
111
+
112
+    if (is_null($suite) && defined('_INTRODUCTION_SUITE')) {
113
+        $suite = _INTRODUCTION_SUITE;
114
+    }
115
+    $texte = couper($texte, $longueur, $suite);
116
+    // comme on a coupe il faut repasser la typo (on a perdu les insecables)
117
+    $texte = typo($texte, true, $connect, []);
118
+
119
+    // et reparagrapher si necessaire (coherence avec le cas descriptif)
120
+    // une introduction a tojours un <p>
121
+    if ($GLOBALS['toujours_paragrapher']) { // Fermer les paragraphes
122
+    $texte = paragrapher($texte, $GLOBALS['toujours_paragrapher']);
123
+    }
124
+
125
+    return $texte;
126 126
 }
127 127
 
128 128
 
@@ -157,64 +157,64 @@  discard block
 block discarded – undo
157 157
  *     Code HTML de la pagination
158 158
  **/
159 159
 function filtre_pagination_dist(
160
-	$total,
161
-	$nom,
162
-	$position,
163
-	$pas,
164
-	$liste = true,
165
-	$modele = '',
166
-	string $connect = '',
167
-	$env = []
160
+    $total,
161
+    $nom,
162
+    $position,
163
+    $pas,
164
+    $liste = true,
165
+    $modele = '',
166
+    string $connect = '',
167
+    $env = []
168 168
 ) {
169
-	static $ancres = [];
170
-	if ($pas < 1) {
171
-		return '';
172
-	}
173
-	$ancre = 'pagination' . $nom; // #pagination_articles
174
-	$debut = 'debut' . $nom; // 'debut_articles'
175
-
176
-	// n'afficher l'ancre qu'une fois
177
-	$bloc_ancre = isset($ancres[$ancre]) ? '' : ($ancres[$ancre] = "<a id='" . $ancre . "' class='pagination_ancre'></a>");
178
-	// liste = false : on ne veut que l'ancre
179
-	if (!$liste) {
180
-		return $ancres[$ancre];
181
-	}
182
-
183
-	$self = (empty($env['self']) ? self() : $env['self']);
184
-	$pagination = [
185
-		'debut' => $debut,
186
-		'url' => parametre_url($self, 'fragment', ''), // nettoyer l'id ahah eventuel
187
-		'total' => $total,
188
-		'position' => (int) $position,
189
-		'pas' => $pas,
190
-		'nombre_pages' => floor(($total - 1) / $pas) + 1,
191
-		'page_courante' => floor((int) $position / $pas) + 1,
192
-		'ancre' => $ancre,
193
-		'bloc_ancre' => $bloc_ancre
194
-	];
195
-	if (is_array($env)) {
196
-		$pagination = array_merge($env, $pagination);
197
-	}
198
-
199
-	// Pas de pagination
200
-	if ($pagination['nombre_pages'] <= 1) {
201
-		return '';
202
-	}
203
-
204
-	if ($modele) {
205
-		$pagination['type_pagination'] = $modele;
206
-		$modele = trouver_fond('pagination_' . $modele, 'modeles') ? '_' . $modele : '';
207
-	}
208
-
209
-	if (!defined('_PAGINATION_NOMBRE_LIENS_MAX')) {
210
-		define('_PAGINATION_NOMBRE_LIENS_MAX', 10);
211
-	}
212
-	if (!defined('_PAGINATION_NOMBRE_LIENS_MAX_ECRIRE')) {
213
-		define('_PAGINATION_NOMBRE_LIENS_MAX_ECRIRE', 5);
214
-	}
215
-
216
-
217
-	return recuperer_fond("modeles/pagination$modele", $pagination, ['trim' => true], $connect);
169
+    static $ancres = [];
170
+    if ($pas < 1) {
171
+        return '';
172
+    }
173
+    $ancre = 'pagination' . $nom; // #pagination_articles
174
+    $debut = 'debut' . $nom; // 'debut_articles'
175
+
176
+    // n'afficher l'ancre qu'une fois
177
+    $bloc_ancre = isset($ancres[$ancre]) ? '' : ($ancres[$ancre] = "<a id='" . $ancre . "' class='pagination_ancre'></a>");
178
+    // liste = false : on ne veut que l'ancre
179
+    if (!$liste) {
180
+        return $ancres[$ancre];
181
+    }
182
+
183
+    $self = (empty($env['self']) ? self() : $env['self']);
184
+    $pagination = [
185
+        'debut' => $debut,
186
+        'url' => parametre_url($self, 'fragment', ''), // nettoyer l'id ahah eventuel
187
+        'total' => $total,
188
+        'position' => (int) $position,
189
+        'pas' => $pas,
190
+        'nombre_pages' => floor(($total - 1) / $pas) + 1,
191
+        'page_courante' => floor((int) $position / $pas) + 1,
192
+        'ancre' => $ancre,
193
+        'bloc_ancre' => $bloc_ancre
194
+    ];
195
+    if (is_array($env)) {
196
+        $pagination = array_merge($env, $pagination);
197
+    }
198
+
199
+    // Pas de pagination
200
+    if ($pagination['nombre_pages'] <= 1) {
201
+        return '';
202
+    }
203
+
204
+    if ($modele) {
205
+        $pagination['type_pagination'] = $modele;
206
+        $modele = trouver_fond('pagination_' . $modele, 'modeles') ? '_' . $modele : '';
207
+    }
208
+
209
+    if (!defined('_PAGINATION_NOMBRE_LIENS_MAX')) {
210
+        define('_PAGINATION_NOMBRE_LIENS_MAX', 10);
211
+    }
212
+    if (!defined('_PAGINATION_NOMBRE_LIENS_MAX_ECRIRE')) {
213
+        define('_PAGINATION_NOMBRE_LIENS_MAX_ECRIRE', 5);
214
+    }
215
+
216
+
217
+    return recuperer_fond("modeles/pagination$modele", $pagination, ['trim' => true], $connect);
218 218
 }
219 219
 
220 220
 
@@ -233,38 +233,38 @@  discard block
 block discarded – undo
233 233
  *     Liste (première page, dernière page).
234 234
  **/
235 235
 function filtre_bornes_pagination_dist($courante, $nombre, $max = 10) {
236
-	if ($max <= 0 || $max >= $nombre) {
237
-		return [1, $nombre];
238
-	}
239
-	if ($max <= 1) {
240
-		return [$courante, $courante];
241
-	}
242
-
243
-	$premiere = max(1, $courante - floor(($max - 1) / 2));
244
-	$derniere = min($nombre, $premiere + $max - 2);
245
-	$premiere = $derniere == $nombre ? $derniere - $max + 1 : $premiere;
246
-
247
-	return [$premiere, $derniere];
236
+    if ($max <= 0 || $max >= $nombre) {
237
+        return [1, $nombre];
238
+    }
239
+    if ($max <= 1) {
240
+        return [$courante, $courante];
241
+    }
242
+
243
+    $premiere = max(1, $courante - floor(($max - 1) / 2));
244
+    $derniere = min($nombre, $premiere + $max - 2);
245
+    $premiere = $derniere == $nombre ? $derniere - $max + 1 : $premiere;
246
+
247
+    return [$premiere, $derniere];
248 248
 }
249 249
 
250 250
 function filtre_pagination_affiche_texte_lien_page_dist($type_pagination, $numero_page, $rang_item) {
251
-	if ($numero_page === 'tous') {
252
-		return '&#8734;';
253
-	}
254
-	if ($numero_page === 'prev') {
255
-		return '&lt;';
256
-	}
257
-	if ($numero_page === 'next') {
258
-		return '&gt;';
259
-	}
260
-
261
-	return match ($type_pagination) {
262
-		'resultats' => $rang_item + 1, // 1 11 21 31...
263
-		'naturel' => $rang_item ?: 1, // 1 10 20 30...
264
-		'rang' => $rang_item, // 0 10 20 30...
265
-		'page', 'prive' => $numero_page, // 1 2 3 4 5...
266
-		default => $numero_page, // 1 2 3 4 5...
267
-	};
251
+    if ($numero_page === 'tous') {
252
+        return '&#8734;';
253
+    }
254
+    if ($numero_page === 'prev') {
255
+        return '&lt;';
256
+    }
257
+    if ($numero_page === 'next') {
258
+        return '&gt;';
259
+    }
260
+
261
+    return match ($type_pagination) {
262
+        'resultats' => $rang_item + 1, // 1 11 21 31...
263
+        'naturel' => $rang_item ?: 1, // 1 10 20 30...
264
+        'rang' => $rang_item, // 0 10 20 30...
265
+        'page', 'prive' => $numero_page, // 1 2 3 4 5...
266
+        default => $numero_page, // 1 2 3 4 5...
267
+    };
268 268
 }
269 269
 
270 270
 /**
@@ -277,15 +277,15 @@  discard block
 block discarded – undo
277 277
  **/
278 278
 function lister_objets_avec_logos($type) {
279 279
 
280
-	$objet = objet_type($type);
281
-	$ids = sql_allfetsel('L.id_objet', 'spip_documents AS D JOIN spip_documents_liens AS L ON L.id_document=D.id_document', 'D.mode=' . sql_quote('logoon') . ' AND L.objet=' . sql_quote($objet));
282
-	if ($ids) {
283
-		$ids = array_column($ids, 'id_objet');
284
-		return implode(',', $ids);
285
-	}
286
-	else {
287
-		return '0';
288
-	}
280
+    $objet = objet_type($type);
281
+    $ids = sql_allfetsel('L.id_objet', 'spip_documents AS D JOIN spip_documents_liens AS L ON L.id_document=D.id_document', 'D.mode=' . sql_quote('logoon') . ' AND L.objet=' . sql_quote($objet));
282
+    if ($ids) {
283
+        $ids = array_column($ids, 'id_objet');
284
+        return implode(',', $ids);
285
+    }
286
+    else {
287
+        return '0';
288
+    }
289 289
 }
290 290
 
291 291
 
@@ -301,14 +301,14 @@  discard block
 block discarded – undo
301 301
  *     Code HTML des notes
302 302
  **/
303 303
 function calculer_notes() {
304
-	$r = '';
305
-	if ($notes = charger_fonction('notes', 'inc', true)) {
306
-		$r = $notes([]);
307
-		$notes('', 'depiler');
308
-		$notes('', 'empiler');
309
-	}
310
-
311
-	return $r;
304
+    $r = '';
305
+    if ($notes = charger_fonction('notes', 'inc', true)) {
306
+        $r = $notes([]);
307
+        $notes('', 'depiler');
308
+        $notes('', 'empiler');
309
+    }
310
+
311
+    return $r;
312 312
 }
313 313
 
314 314
 
@@ -325,10 +325,10 @@  discard block
 block discarded – undo
325 325
  * @return string
326 326
  */
327 327
 function retrouver_rang_lien($objet_source, $ids, $objet_lie, $idl, $objet_lien) {
328
-	$res = lister_objets_liens($objet_source, $objet_lie, $idl, $objet_lien);
329
-	$res = array_column($res, 'rang_lien', $objet_source);
328
+    $res = lister_objets_liens($objet_source, $objet_lie, $idl, $objet_lien);
329
+    $res = array_column($res, 'rang_lien', $objet_source);
330 330
 
331
-	return ($res[$ids] ?? '');
331
+    return ($res[$ids] ?? '');
332 332
 }
333 333
 
334 334
 
@@ -345,19 +345,19 @@  discard block
 block discarded – undo
345 345
  * @private
346 346
  */
347 347
 function lister_objets_liens($objet_source, $objet, $id_objet, $objet_lien) {
348
-	static $liens = [];
349
-	if (!isset($liens["$objet_source-$objet-$id_objet-$objet_lien"])) {
350
-		include_spip('action/editer_liens');
351
-		// quand $objet == $objet_lien == $objet_source on reste sur le cas par defaut de $objet_lien == $objet_source
352
-		if ($objet_lien == $objet && $objet_lien !== $objet_source) {
353
-			$res = objet_trouver_liens([$objet => $id_objet], [$objet_source => '*']);
354
-		} else {
355
-			$res = objet_trouver_liens([$objet_source => '*'], [$objet => $id_objet]);
356
-		}
357
-
358
-		$liens["$objet_source-$objet-$id_objet-$objet_lien"] = $res;
359
-	}
360
-	return $liens["$objet_source-$objet-$id_objet-$objet_lien"];
348
+    static $liens = [];
349
+    if (!isset($liens["$objet_source-$objet-$id_objet-$objet_lien"])) {
350
+        include_spip('action/editer_liens');
351
+        // quand $objet == $objet_lien == $objet_source on reste sur le cas par defaut de $objet_lien == $objet_source
352
+        if ($objet_lien == $objet && $objet_lien !== $objet_source) {
353
+            $res = objet_trouver_liens([$objet => $id_objet], [$objet_source => '*']);
354
+        } else {
355
+            $res = objet_trouver_liens([$objet_source => '*'], [$objet => $id_objet]);
356
+        }
357
+
358
+        $liens["$objet_source-$objet-$id_objet-$objet_lien"] = $res;
359
+    }
360
+    return $liens["$objet_source-$objet-$id_objet-$objet_lien"];
361 361
 }
362 362
 
363 363
 /**
@@ -371,24 +371,24 @@  discard block
 block discarded – undo
371 371
  * @return int|string
372 372
  */
373 373
 function calculer_rang_smart($titre, $objet_source, $id, $env) {
374
-	// Cas du #RANG utilisé dans #FORMULAIRE_EDITER_LIENS -> attraper le rang du lien
375
-	// permet de voir le rang du lien si il y en a un en base, meme avant un squelette xxxx-lies.html ne gerant pas les liens
376
-	if (
377
-		isset($env['form']) && $env['form']
378
-		&& isset($env['_objet_lien']) && $env['_objet_lien']
379
-		&& (function_exists('lien_triables') || include_spip('action/editer_liens'))
380
-		&& ($r = objet_associable($env['_objet_lien']))
381
-		&& ([$p, $table_lien] = $r)
382
-		&& lien_triables($table_lien)
383
-		&& isset($env['objet']) && $env['objet']
384
-		&& isset($env['id_objet']) && $env['id_objet']
385
-		&& $objet_source
386
-		&& ($id = (int) $id)
387
-	) {
388
-		$rang = retrouver_rang_lien($objet_source, $id, $env['objet'], $env['id_objet'], $env['_objet_lien']);
389
-		return ($rang ?: '');
390
-	}
391
-	return recuperer_numero($titre);
374
+    // Cas du #RANG utilisé dans #FORMULAIRE_EDITER_LIENS -> attraper le rang du lien
375
+    // permet de voir le rang du lien si il y en a un en base, meme avant un squelette xxxx-lies.html ne gerant pas les liens
376
+    if (
377
+        isset($env['form']) && $env['form']
378
+        && isset($env['_objet_lien']) && $env['_objet_lien']
379
+        && (function_exists('lien_triables') || include_spip('action/editer_liens'))
380
+        && ($r = objet_associable($env['_objet_lien']))
381
+        && ([$p, $table_lien] = $r)
382
+        && lien_triables($table_lien)
383
+        && isset($env['objet']) && $env['objet']
384
+        && isset($env['id_objet']) && $env['id_objet']
385
+        && $objet_source
386
+        && ($id = (int) $id)
387
+    ) {
388
+        $rang = retrouver_rang_lien($objet_source, $id, $env['objet'], $env['id_objet'], $env['_objet_lien']);
389
+        return ($rang ?: '');
390
+    }
391
+    return recuperer_numero($titre);
392 392
 }
393 393
 
394 394
 /**
@@ -415,72 +415,72 @@  discard block
 block discarded – undo
415 415
  */
416 416
 function calculer_balise_tri(string $champ_ou_sens, string $libelle, string $classe, string $tri_nom, string $tri_champ, string $tri_sens, $liste_tri_sens_defaut): string {
417 417
 
418
-	$url = self('&');
419
-	$tri_sens = (int) $tri_sens;
420
-	$alias_sens = [
421
-		'<' => -1,
422
-		'>' => 1,
423
-		'inverse' => -1,
424
-	];
425
-
426
-	// Normaliser la liste des sens de tri par défaut
427
-	// On ajoute un jocker pour les champs non présents dans la liste
428
-	// avec la valeur du 1er item de la liste, idem critère {tri}
429
-	if (is_array($liste_tri_sens_defaut)) {
430
-		$liste_tri_sens_defaut['*'] = array_values($liste_tri_sens_defaut)[0];
431
-	} else {
432
-		$liste_tri_sens_defaut = [
433
-			'*' => (int) ($alias_sens[$liste_tri_sens_defaut] ?? $liste_tri_sens_defaut),
434
-		];
435
-	}
436
-
437
-	// Les sens de tri actuel et nouveau :
438
-	// Soit c'est un sens fixe donné en paramètre (< ou >)
439
-	$is_sens_fixe = array_key_exists($champ_ou_sens, $alias_sens);
440
-	if ($is_sens_fixe) {
441
-		$tri_sens_actuel = $tri_sens;
442
-		$tri_sens_nouveau = $alias_sens[$champ_ou_sens];
443
-	// Soit c'est le champ utilisé actuellement pour le tri → on inverse le sens
444
-	} elseif ($champ_ou_sens === $tri_champ) {
445
-		$tri_sens_actuel = $tri_sens;
446
-		$tri_sens_nouveau = $tri_sens * -1;
447
-	// Sinon c'est un nouveau champ, et on prend son tri par défaut
448
-	} else {
449
-		$tri_sens_actuel = $tri_sens_nouveau = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']);
450
-	}
451
-
452
-	// URL : ajouter le champ sur lequel porte le tri
453
-	if (!$is_sens_fixe) {
454
-		$param_tri = "tri$tri_nom";
455
-		$url = parametre_url($url, $param_tri, $champ_ou_sens);
456
-	}
457
-
458
-	// URL : n'ajouter le sens de tri que si nécessaire,
459
-	// c.à.d différent du sens par défaut pour le champ
460
-	$param_sens = "sens$tri_nom";
461
-	$tri_sens_defaut_champ = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']);
462
-	if ($tri_sens_nouveau !== $tri_sens_defaut_champ) {
463
-		$url = parametre_url($url, $param_sens, $tri_sens_nouveau);
464
-	} else {
465
-		$url = parametre_url($url, $param_sens, '');
466
-	}
467
-
468
-	// Drapeau pour garder en session ?
469
-	$param_memo = ($is_sens_fixe ? $param_sens : $param_tri);
470
-	$url = parametre_url($url, 'var_memotri', str_starts_with($tri_nom, 'session') ? $param_memo : '');
471
-
472
-	// Classes : on indique le sens de tri et l'item exposé
473
-	if (!$is_sens_fixe) {
474
-		$classe .= ' item-tri item-tri_' . ($tri_sens_actuel === 1 ? 'asc' : 'desc');
475
-	}
476
-	if ($champ_ou_sens === $tri_champ) {
477
-		$classe .= ' item-tri_actif';
478
-	}
479
-
480
-	// Lien
481
-	$balise = lien_ou_expose($url, $libelle, false, $classe);
482
-
483
-	return $balise;
418
+    $url = self('&');
419
+    $tri_sens = (int) $tri_sens;
420
+    $alias_sens = [
421
+        '<' => -1,
422
+        '>' => 1,
423
+        'inverse' => -1,
424
+    ];
425
+
426
+    // Normaliser la liste des sens de tri par défaut
427
+    // On ajoute un jocker pour les champs non présents dans la liste
428
+    // avec la valeur du 1er item de la liste, idem critère {tri}
429
+    if (is_array($liste_tri_sens_defaut)) {
430
+        $liste_tri_sens_defaut['*'] = array_values($liste_tri_sens_defaut)[0];
431
+    } else {
432
+        $liste_tri_sens_defaut = [
433
+            '*' => (int) ($alias_sens[$liste_tri_sens_defaut] ?? $liste_tri_sens_defaut),
434
+        ];
435
+    }
436
+
437
+    // Les sens de tri actuel et nouveau :
438
+    // Soit c'est un sens fixe donné en paramètre (< ou >)
439
+    $is_sens_fixe = array_key_exists($champ_ou_sens, $alias_sens);
440
+    if ($is_sens_fixe) {
441
+        $tri_sens_actuel = $tri_sens;
442
+        $tri_sens_nouveau = $alias_sens[$champ_ou_sens];
443
+    // Soit c'est le champ utilisé actuellement pour le tri → on inverse le sens
444
+    } elseif ($champ_ou_sens === $tri_champ) {
445
+        $tri_sens_actuel = $tri_sens;
446
+        $tri_sens_nouveau = $tri_sens * -1;
447
+    // Sinon c'est un nouveau champ, et on prend son tri par défaut
448
+    } else {
449
+        $tri_sens_actuel = $tri_sens_nouveau = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']);
450
+    }
451
+
452
+    // URL : ajouter le champ sur lequel porte le tri
453
+    if (!$is_sens_fixe) {
454
+        $param_tri = "tri$tri_nom";
455
+        $url = parametre_url($url, $param_tri, $champ_ou_sens);
456
+    }
457
+
458
+    // URL : n'ajouter le sens de tri que si nécessaire,
459
+    // c.à.d différent du sens par défaut pour le champ
460
+    $param_sens = "sens$tri_nom";
461
+    $tri_sens_defaut_champ = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']);
462
+    if ($tri_sens_nouveau !== $tri_sens_defaut_champ) {
463
+        $url = parametre_url($url, $param_sens, $tri_sens_nouveau);
464
+    } else {
465
+        $url = parametre_url($url, $param_sens, '');
466
+    }
467
+
468
+    // Drapeau pour garder en session ?
469
+    $param_memo = ($is_sens_fixe ? $param_sens : $param_tri);
470
+    $url = parametre_url($url, 'var_memotri', str_starts_with($tri_nom, 'session') ? $param_memo : '');
471
+
472
+    // Classes : on indique le sens de tri et l'item exposé
473
+    if (!$is_sens_fixe) {
474
+        $classe .= ' item-tri item-tri_' . ($tri_sens_actuel === 1 ? 'asc' : 'desc');
475
+    }
476
+    if ($champ_ou_sens === $tri_champ) {
477
+        $classe .= ' item-tri_actif';
478
+    }
479
+
480
+    // Lien
481
+    $balise = lien_ou_expose($url, $libelle, false, $classe);
482
+
483
+    return $balise;
484 484
 }
485 485
 
486 486
 
@@ -496,7 +496,7 @@  discard block
 block discarded – undo
496 496
  * @return string
497 497
  */
498 498
 function tri_protege_champ($t) {
499
-	return preg_replace(',[^\s\w.+\[\]],', '', $t);
499
+    return preg_replace(',[^\s\w.+\[\]],', '', $t);
500 500
 }
501 501
 
502 502
 /**
@@ -509,39 +509,39 @@  discard block
 block discarded – undo
509 509
  * @return string
510 510
  */
511 511
 function tri_champ_order($t, $from = null, $senstri = '') {
512
-	if (str_starts_with($t, 'multi ')) {
513
-		return 'multi' . $senstri;
514
-	}
515
-
516
-	$champ = $t;
517
-
518
-	$prefixe = '';
519
-	foreach (['num ', 'sinum '] as $p) {
520
-		if (str_starts_with($t, $p)) {
521
-			$champ = substr($t, strlen($p));
522
-			$prefixe = $p;
523
-		}
524
-	}
525
-
526
-	// enlever les autres espaces non evacues par tri_protege_champ
527
-	$champ = preg_replace(',\s,', '', $champ);
528
-
529
-	if (is_array($from)) {
530
-		$trouver_table = charger_fonction('trouver_table', 'base');
531
-		foreach ($from as $idt => $table_sql) {
532
-			if (
533
-				($desc = $trouver_table($table_sql)) && isset($desc['field'][$champ])
534
-			) {
535
-				$champ = "$idt.$champ";
536
-				break;
537
-			}
538
-		}
539
-	}
540
-	return match ($prefixe) {
541
-		'num ' => "CASE( 0+$champ ) WHEN 0 THEN 1 ELSE 0 END{$senstri}, 0+$champ{$senstri}",
542
-		'sinum ' => "CASE( 0+$champ ) WHEN 0 THEN 1 ELSE 0 END{$senstri}",
543
-		default => $champ . $senstri,
544
-	};
512
+    if (str_starts_with($t, 'multi ')) {
513
+        return 'multi' . $senstri;
514
+    }
515
+
516
+    $champ = $t;
517
+
518
+    $prefixe = '';
519
+    foreach (['num ', 'sinum '] as $p) {
520
+        if (str_starts_with($t, $p)) {
521
+            $champ = substr($t, strlen($p));
522
+            $prefixe = $p;
523
+        }
524
+    }
525
+
526
+    // enlever les autres espaces non evacues par tri_protege_champ
527
+    $champ = preg_replace(',\s,', '', $champ);
528
+
529
+    if (is_array($from)) {
530
+        $trouver_table = charger_fonction('trouver_table', 'base');
531
+        foreach ($from as $idt => $table_sql) {
532
+            if (
533
+                ($desc = $trouver_table($table_sql)) && isset($desc['field'][$champ])
534
+            ) {
535
+                $champ = "$idt.$champ";
536
+                break;
537
+            }
538
+        }
539
+    }
540
+    return match ($prefixe) {
541
+        'num ' => "CASE( 0+$champ ) WHEN 0 THEN 1 ELSE 0 END{$senstri}, 0+$champ{$senstri}",
542
+        'sinum ' => "CASE( 0+$champ ) WHEN 0 THEN 1 ELSE 0 END{$senstri}",
543
+        default => $champ . $senstri,
544
+    };
545 545
 }
546 546
 
547 547
 /**
@@ -555,17 +555,17 @@  discard block
 block discarded – undo
555 555
  * @return string
556 556
  */
557 557
 function tri_champ_select($t) {
558
-	if (str_starts_with($t, 'multi ')) {
559
-		$t = substr($t, 6);
560
-		$t = preg_replace(',\s,', '', $t);
558
+    if (str_starts_with($t, 'multi ')) {
559
+        $t = substr($t, 6);
560
+        $t = preg_replace(',\s,', '', $t);
561 561
 
562
-		return sql_multi($t, $GLOBALS['spip_lang']);
563
-	}
564
-	if (trim($t) == 'hasard') {
565
-		return 'rand() AS hasard';
566
-	}
562
+        return sql_multi($t, $GLOBALS['spip_lang']);
563
+    }
564
+    if (trim($t) == 'hasard') {
565
+        return 'rand() AS hasard';
566
+    }
567 567
 
568
-	return "''";
568
+    return "''";
569 569
 }
570 570
 
571 571
 /**
@@ -577,15 +577,15 @@  discard block
 block discarded – undo
577 577
  * @return string
578 578
  */
579 579
 function formate_liste_critere_par_ordre_liste($valeurs, $serveur = '') {
580
-	if (!is_array($valeurs)) {
581
-		return '';
582
-	}
583
-	$f = sql_serveur('quote', $serveur, true);
584
-	if (!is_string($f) || !$f) {
585
-		return '';
586
-	}
587
-
588
-	return implode(',', array_map($f, array_unique($valeurs)));
580
+    if (!is_array($valeurs)) {
581
+        return '';
582
+    }
583
+    $f = sql_serveur('quote', $serveur, true);
584
+    if (!is_string($f) || !$f) {
585
+        return '';
586
+    }
587
+
588
+    return implode(',', array_map($f, array_unique($valeurs)));
589 589
 }
590 590
 
591 591
 /**
@@ -608,22 +608,22 @@  discard block
 block discarded – undo
608 608
  *     Valeur $defaut sinon.
609 609
  **/
610 610
 function appliquer_filtre_sinon($arg, $filtre, $args, $defaut = '') {
611
-	// Si c'est un filtre d'image, on utilise image_filtrer()
612
-	// Attention : les 2 premiers arguments sont inversés dans ce cas
613
-	if (trouver_filtre_matrice($filtre) && str_starts_with($filtre, 'image_')) {
614
-		include_spip('inc/filtres_images_lib_mini');
615
-		$args[1] = $args[0];
616
-		$args[0] = $filtre;
617
-		return image_graver(image_filtrer($args));
618
-	}
619
-
620
-	$f = chercher_filtre($filtre);
621
-	if (!$f) {
622
-		return $defaut;
623
-	}
624
-	array_shift($args); // enlever $arg
625
-	array_shift($args); // enlever $filtre
626
-	return $f($arg, ...$args);
611
+    // Si c'est un filtre d'image, on utilise image_filtrer()
612
+    // Attention : les 2 premiers arguments sont inversés dans ce cas
613
+    if (trouver_filtre_matrice($filtre) && str_starts_with($filtre, 'image_')) {
614
+        include_spip('inc/filtres_images_lib_mini');
615
+        $args[1] = $args[0];
616
+        $args[0] = $filtre;
617
+        return image_graver(image_filtrer($args));
618
+    }
619
+
620
+    $f = chercher_filtre($filtre);
621
+    if (!$f) {
622
+        return $defaut;
623
+    }
624
+    array_shift($args); // enlever $arg
625
+    array_shift($args); // enlever $filtre
626
+    return $f($arg, ...$args);
627 627
 }
628 628
 
629 629
 /**
@@ -633,30 +633,30 @@  discard block
 block discarded – undo
633 633
  * @return string
634 634
  */
635 635
 function filtre_styles_inline_page_login_pass_dist(&$Pile, ...$dummy) {
636
-	$styles = '';
637
-	include_spip('inc/config');
638
-	if ($couleur = lire_config('couleur_login')) {
639
-		include_spip('inc/filtres_images_mini');
640
-		$hs = couleur_hex_to_hsl($couleur, 'h, s');
641
-		$l = couleur_hex_to_hsl($couleur, 'l');
642
-		$styles .= ":root {--spip-login-color-theme--hs: {$hs};--spip-login-color-theme--l: {$l};}\n";
643
-	}
644
-	$logo_bg = _DIR_IMG . 'spip_fond_login.jpg';
645
-	if (file_exists($logo_bg)) {
646
-		include_spip('inc/filtres_images_mini');
647
-		$logo_mini = image_reduire($logo_bg, 64, 64);
648
-		$logo_mini = extraire_attribut($logo_mini, 'src');
649
-		$embarque_fichier = charger_filtre('embarque_fichier');
650
-		$logo_mini = $embarque_fichier($logo_mini);
651
-		$logo_bg = timestamp($logo_bg);
652
-		$styles .= ".page_login, .page_spip_pass {background-image:url($logo_bg), url($logo_mini);}\n";
653
-		$Pile[0]['body_class'] = 'fond_image';
654
-	}
655
-	else {
656
-		$Pile[0]['body_class'] = 'sans_fond';
657
-	}
658
-	if ($styles) {
659
-		$styles = "<style type='text/css'>$styles</style>";
660
-	}
661
-	return $styles;
636
+    $styles = '';
637
+    include_spip('inc/config');
638
+    if ($couleur = lire_config('couleur_login')) {
639
+        include_spip('inc/filtres_images_mini');
640
+        $hs = couleur_hex_to_hsl($couleur, 'h, s');
641
+        $l = couleur_hex_to_hsl($couleur, 'l');
642
+        $styles .= ":root {--spip-login-color-theme--hs: {$hs};--spip-login-color-theme--l: {$l};}\n";
643
+    }
644
+    $logo_bg = _DIR_IMG . 'spip_fond_login.jpg';
645
+    if (file_exists($logo_bg)) {
646
+        include_spip('inc/filtres_images_mini');
647
+        $logo_mini = image_reduire($logo_bg, 64, 64);
648
+        $logo_mini = extraire_attribut($logo_mini, 'src');
649
+        $embarque_fichier = charger_filtre('embarque_fichier');
650
+        $logo_mini = $embarque_fichier($logo_mini);
651
+        $logo_bg = timestamp($logo_bg);
652
+        $styles .= ".page_login, .page_spip_pass {background-image:url($logo_bg), url($logo_mini);}\n";
653
+        $Pile[0]['body_class'] = 'fond_image';
654
+    }
655
+    else {
656
+        $Pile[0]['body_class'] = 'sans_fond';
657
+    }
658
+    if ($styles) {
659
+        $styles = "<style type='text/css'>$styles</style>";
660
+    }
661
+    return $styles;
662 662
 }
Please login to merge, or discard this patch.
ecrire/public/composer.php 1 patch
Indentation   +768 added lines, -768 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
 include_spip('inc/texte');
@@ -40,234 +40,234 @@  discard block
 block discarded – undo
40 40
 
41 41
 function public_composer_dist($squelette, $mime_type, $gram, $source, string $connect = '') {
42 42
 
43
-	$skel = null;
44
-	$boucle = null;
45
-	$nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect);
46
-
47
-	//  si deja en memoire (INCLURE  a repetition) c'est bon.
48
-	if (function_exists($nom)) {
49
-		return $nom;
50
-	}
51
-
52
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
53
-		$GLOBALS['debug_objets']['courant'] = $nom;
54
-	}
55
-
56
-	$phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php';
57
-
58
-	// si squelette est deja compile et perenne, le charger
59
-	if (!squelette_obsolete($phpfile, $source)) {
60
-		include_once $phpfile;
61
-		#if (!squelette_obsolete($phpfile, $source)
62
-		#  AND lire_fichier ($phpfile, $skel_code,
63
-		#  array('critique' => 'oui', 'phpcheck' => 'oui'))){
64
-		## eval('?'.'>'.$skel_code);
65
-		#	 spip_log($skel_code, 'comp')
66
-		#}
67
-	}
68
-
69
-	if (file_exists($lib = $squelette . '_fonctions' . '.php')) {
70
-		include_once $lib;
71
-	}
72
-
73
-	// tester si le eval ci-dessus a mis le squelette en memoire
74
-
75
-	if (function_exists($nom)) {
76
-		return $nom;
77
-	}
78
-
79
-	// charger le source, si possible, et compiler
80
-	$skel_code = '';
81
-	if (lire_fichier($source, $skel)) {
82
-		$compiler = charger_fonction('compiler', 'public');
83
-		$skel_code = $compiler($skel, $nom, $gram, $source, $connect);
84
-	}
85
-
86
-	// Ne plus rien faire si le compilateur n'a pas pu operer.
87
-	if (!$skel_code) {
88
-		return false;
89
-	}
90
-
91
-	foreach ($skel_code as $id => $boucle) {
92
-		$f = $boucle->return;
93
-		try {
94
-			eval("return true; $f ;");
95
-		} catch (\ParseError $e) {
96
-			// Code syntaxiquement faux (critere etc mal programme')
97
-			$msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage();
98
-			erreur_squelette($msg, $boucle);
99
-			// continuer pour trouver d'autres fautes eventuelles
100
-			// mais prevenir que c'est mort
101
-			$nom = '';
102
-		}
103
-
104
-		// contexte de compil inutile a present
105
-		// (mais la derniere valeur de $boucle est utilisee ci-dessous)
106
-		$skel_code[$id] = $f;
107
-	}
108
-
109
-	$code = '';
110
-	if ($nom) {
111
-		// Si le code est bon, concatener et mettre en cache
112
-		if (function_exists($nom)) {
113
-			$code = squelette_traduit($skel, $source, $phpfile, $skel_code);
114
-		} else {
115
-			// code semantiquement faux: bug du compilateur
116
-			// $boucle est en fait ici la fct principale du squelette
117
-			$msg = _T('zbug_erreur_compilation');
118
-			erreur_squelette($msg, $boucle);
119
-			$nom = '';
120
-		}
121
-	}
122
-
123
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
124
-		// Tracer ce qui vient d'etre compile
125
-		$GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code;
126
-
127
-		// si c'est ce que demande le debusqueur, lui passer la main
128
-		if (
129
-			$GLOBALS['debug_objets']['sourcefile']
130
-			and (_request('var_mode_objet') == $nom)
131
-			and (_request('var_mode_affiche') == 'code')
132
-		) {
133
-			erreur_squelette();
134
-		}
135
-	}
136
-
137
-	return $nom ?: false;
43
+    $skel = null;
44
+    $boucle = null;
45
+    $nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect);
46
+
47
+    //  si deja en memoire (INCLURE  a repetition) c'est bon.
48
+    if (function_exists($nom)) {
49
+        return $nom;
50
+    }
51
+
52
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
53
+        $GLOBALS['debug_objets']['courant'] = $nom;
54
+    }
55
+
56
+    $phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php';
57
+
58
+    // si squelette est deja compile et perenne, le charger
59
+    if (!squelette_obsolete($phpfile, $source)) {
60
+        include_once $phpfile;
61
+        #if (!squelette_obsolete($phpfile, $source)
62
+        #  AND lire_fichier ($phpfile, $skel_code,
63
+        #  array('critique' => 'oui', 'phpcheck' => 'oui'))){
64
+        ## eval('?'.'>'.$skel_code);
65
+        #	 spip_log($skel_code, 'comp')
66
+        #}
67
+    }
68
+
69
+    if (file_exists($lib = $squelette . '_fonctions' . '.php')) {
70
+        include_once $lib;
71
+    }
72
+
73
+    // tester si le eval ci-dessus a mis le squelette en memoire
74
+
75
+    if (function_exists($nom)) {
76
+        return $nom;
77
+    }
78
+
79
+    // charger le source, si possible, et compiler
80
+    $skel_code = '';
81
+    if (lire_fichier($source, $skel)) {
82
+        $compiler = charger_fonction('compiler', 'public');
83
+        $skel_code = $compiler($skel, $nom, $gram, $source, $connect);
84
+    }
85
+
86
+    // Ne plus rien faire si le compilateur n'a pas pu operer.
87
+    if (!$skel_code) {
88
+        return false;
89
+    }
90
+
91
+    foreach ($skel_code as $id => $boucle) {
92
+        $f = $boucle->return;
93
+        try {
94
+            eval("return true; $f ;");
95
+        } catch (\ParseError $e) {
96
+            // Code syntaxiquement faux (critere etc mal programme')
97
+            $msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage();
98
+            erreur_squelette($msg, $boucle);
99
+            // continuer pour trouver d'autres fautes eventuelles
100
+            // mais prevenir que c'est mort
101
+            $nom = '';
102
+        }
103
+
104
+        // contexte de compil inutile a present
105
+        // (mais la derniere valeur de $boucle est utilisee ci-dessous)
106
+        $skel_code[$id] = $f;
107
+    }
108
+
109
+    $code = '';
110
+    if ($nom) {
111
+        // Si le code est bon, concatener et mettre en cache
112
+        if (function_exists($nom)) {
113
+            $code = squelette_traduit($skel, $source, $phpfile, $skel_code);
114
+        } else {
115
+            // code semantiquement faux: bug du compilateur
116
+            // $boucle est en fait ici la fct principale du squelette
117
+            $msg = _T('zbug_erreur_compilation');
118
+            erreur_squelette($msg, $boucle);
119
+            $nom = '';
120
+        }
121
+    }
122
+
123
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
124
+        // Tracer ce qui vient d'etre compile
125
+        $GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code;
126
+
127
+        // si c'est ce que demande le debusqueur, lui passer la main
128
+        if (
129
+            $GLOBALS['debug_objets']['sourcefile']
130
+            and (_request('var_mode_objet') == $nom)
131
+            and (_request('var_mode_affiche') == 'code')
132
+        ) {
133
+            erreur_squelette();
134
+        }
135
+    }
136
+
137
+    return $nom ?: false;
138 138
 }
139 139
 
140 140
 function squelette_traduit($squelette, $sourcefile, $phpfile, $boucles) {
141 141
 
142
-	$code = null;
143
-	// Le dernier index est '' (fonction principale)
144
-	$noms = substr(join(', ', array_keys($boucles)), 0, -2);
145
-	if (CODE_COMMENTE) {
146
-		$code = "
142
+    $code = null;
143
+    // Le dernier index est '' (fonction principale)
144
+    $noms = substr(join(', ', array_keys($boucles)), 0, -2);
145
+    if (CODE_COMMENTE) {
146
+        $code = "
147 147
 /*
148 148
  * Squelette : $sourcefile
149 149
  * Date :      " . gmdate('D, d M Y H:i:s', @filemtime($sourcefile)) . ' GMT
150 150
  * Compile :   ' . gmdate('D, d M Y H:i:s', time()) . ' GMT
151 151
  * ' . (!$boucles ? 'Pas de boucle' : ('Boucles :   ' . $noms)) . '
152 152
  */ ';
153
-	}
153
+    }
154 154
 
155
-	$code = '<' . "?php\n" . $code . join('', $boucles) . "\n";
156
-	if (!defined('_VAR_NOCACHE') or !_VAR_NOCACHE) {
157
-		ecrire_fichier($phpfile, $code);
158
-	}
155
+    $code = '<' . "?php\n" . $code . join('', $boucles) . "\n";
156
+    if (!defined('_VAR_NOCACHE') or !_VAR_NOCACHE) {
157
+        ecrire_fichier($phpfile, $code);
158
+    }
159 159
 
160
-	return $code;
160
+    return $code;
161 161
 }
162 162
 
163 163
 // Le squelette compile est-il trop vieux ?
164 164
 function squelette_obsolete($skel, $squelette) {
165
-	static $date_change = null;
166
-	// ne verifier la date de mes_fonctions et mes_options qu'une seule fois
167
-	// par hit
168
-	if (is_null($date_change)) {
169
-		if (@file_exists($fonc = 'mes_fonctions.php')) {
170
-			$date_change = @filemtime($fonc);
171
-		} # compatibilite
172
-		if (defined('_FILE_OPTIONS')) {
173
-			$date_change = max($date_change, @filemtime(_FILE_OPTIONS));
174
-		}
175
-	}
176
-
177
-	return (
178
-		(defined('_VAR_MODE') and in_array(_VAR_MODE, ['recalcul', 'preview', 'debug']))
179
-		or !@file_exists($skel)
180
-		or ((@file_exists($squelette) ? @filemtime($squelette) : 0)
181
-			> ($date = @filemtime($skel)))
182
-		or ($date_change > $date)
183
-	);
165
+    static $date_change = null;
166
+    // ne verifier la date de mes_fonctions et mes_options qu'une seule fois
167
+    // par hit
168
+    if (is_null($date_change)) {
169
+        if (@file_exists($fonc = 'mes_fonctions.php')) {
170
+            $date_change = @filemtime($fonc);
171
+        } # compatibilite
172
+        if (defined('_FILE_OPTIONS')) {
173
+            $date_change = max($date_change, @filemtime(_FILE_OPTIONS));
174
+        }
175
+    }
176
+
177
+    return (
178
+        (defined('_VAR_MODE') and in_array(_VAR_MODE, ['recalcul', 'preview', 'debug']))
179
+        or !@file_exists($skel)
180
+        or ((@file_exists($squelette) ? @filemtime($squelette) : 0)
181
+            > ($date = @filemtime($skel)))
182
+        or ($date_change > $date)
183
+    );
184 184
 }
185 185
 
186 186
 // Activer l'invalideur de session
187 187
 function invalideur_session(&$Cache, $code = null) {
188
-	$Cache['session'] = spip_session();
188
+    $Cache['session'] = spip_session();
189 189
 
190
-	return $code;
190
+    return $code;
191 191
 }
192 192
 
193 193
 
194 194
 function analyse_resultat_skel($nom, $cache, $corps, $source = '') {
195
-	static $filtres = [];
196
-	$headers = [];
197
-	$corps ??= '';
198
-
199
-	// Recupere les < ?php header('Xx: y'); ? > pour $page['headers']
200
-	// note: on essaie d'attrapper aussi certains de ces entetes codes
201
-	// "a la main" dans les squelettes, mais evidemment sans exhaustivite
202
-	if (
203
-		stripos($corps, 'header') !== false
204
-		and preg_match_all(
205
-			'/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims',
206
-			$corps,
207
-			$regs,
208
-			PREG_SET_ORDER
209
-		)
210
-	) {
211
-		foreach ($regs as $r) {
212
-			$corps = str_replace($r[0], '', $corps);
213
-			# $j = Content-Type, et pas content-TYPE.
214
-			$j = join('-', array_map('ucwords', explode('-', strtolower($r[2]))));
215
-
216
-			if ($j == 'X-Spip-Filtre' and isset($headers[$j])) {
217
-				$headers[$j] .= '|' . $r[3];
218
-			} else {
219
-				$headers[$j] = str_replace(['\\\\',"\\'",'\\"'], ['\\',"'",'"'], $r[3]);
220
-			}
221
-		}
222
-	}
223
-	// S'agit-il d'un resultat constant ou contenant du code php
224
-	$process_ins = (
225
-		strpos($corps, '<' . '?') === false
226
-		or
227
-		(strpos($corps, '<' . '?xml') !== false and
228
-			strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
229
-	)
230
-		? 'html'
231
-		: 'php';
232
-
233
-	$skel = [
234
-		'squelette' => $nom,
235
-		'source' => $source,
236
-		'process_ins' => $process_ins,
237
-		'invalideurs' => $cache,
238
-		'entetes' => $headers,
239
-		'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0
240
-	];
241
-
242
-	// traiter #FILTRE{} et filtres
243
-	if (!isset($filtres[$nom])) {
244
-		$filtres[$nom] = pipeline('declarer_filtres_squelettes', ['args' => $skel, 'data' => []]);
245
-	}
246
-	$filtres_headers = [];
247
-	if (isset($headers['X-Spip-Filtre']) and strlen($headers['X-Spip-Filtre'])) {
248
-		$filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre']));
249
-		unset($headers['X-Spip-Filtre']);
250
-	}
251
-	if (is_array($filtres[$nom]) || $filtres[$nom] instanceof \Countable ? count($filtres[$nom]) : 0 or count($filtres_headers)) {
252
-		include_spip('public/sandbox');
253
-		$corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]);
254
-
255
-		if ($process_ins == 'html') {
256
-			$skel['process_ins'] = (
257
-				strpos($corps, '<' . '?') === false
258
-				or
259
-				(strpos($corps, '<' . '?xml') !== false and
260
-					strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
261
-			)
262
-				? 'html'
263
-				: 'php';
264
-		}
265
-	}
266
-
267
-	$skel['entetes'] = $headers;
268
-	$skel['texte'] = $corps;
269
-
270
-	return $skel;
195
+    static $filtres = [];
196
+    $headers = [];
197
+    $corps ??= '';
198
+
199
+    // Recupere les < ?php header('Xx: y'); ? > pour $page['headers']
200
+    // note: on essaie d'attrapper aussi certains de ces entetes codes
201
+    // "a la main" dans les squelettes, mais evidemment sans exhaustivite
202
+    if (
203
+        stripos($corps, 'header') !== false
204
+        and preg_match_all(
205
+            '/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims',
206
+            $corps,
207
+            $regs,
208
+            PREG_SET_ORDER
209
+        )
210
+    ) {
211
+        foreach ($regs as $r) {
212
+            $corps = str_replace($r[0], '', $corps);
213
+            # $j = Content-Type, et pas content-TYPE.
214
+            $j = join('-', array_map('ucwords', explode('-', strtolower($r[2]))));
215
+
216
+            if ($j == 'X-Spip-Filtre' and isset($headers[$j])) {
217
+                $headers[$j] .= '|' . $r[3];
218
+            } else {
219
+                $headers[$j] = str_replace(['\\\\',"\\'",'\\"'], ['\\',"'",'"'], $r[3]);
220
+            }
221
+        }
222
+    }
223
+    // S'agit-il d'un resultat constant ou contenant du code php
224
+    $process_ins = (
225
+        strpos($corps, '<' . '?') === false
226
+        or
227
+        (strpos($corps, '<' . '?xml') !== false and
228
+            strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
229
+    )
230
+        ? 'html'
231
+        : 'php';
232
+
233
+    $skel = [
234
+        'squelette' => $nom,
235
+        'source' => $source,
236
+        'process_ins' => $process_ins,
237
+        'invalideurs' => $cache,
238
+        'entetes' => $headers,
239
+        'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0
240
+    ];
241
+
242
+    // traiter #FILTRE{} et filtres
243
+    if (!isset($filtres[$nom])) {
244
+        $filtres[$nom] = pipeline('declarer_filtres_squelettes', ['args' => $skel, 'data' => []]);
245
+    }
246
+    $filtres_headers = [];
247
+    if (isset($headers['X-Spip-Filtre']) and strlen($headers['X-Spip-Filtre'])) {
248
+        $filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre']));
249
+        unset($headers['X-Spip-Filtre']);
250
+    }
251
+    if (is_array($filtres[$nom]) || $filtres[$nom] instanceof \Countable ? count($filtres[$nom]) : 0 or count($filtres_headers)) {
252
+        include_spip('public/sandbox');
253
+        $corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]);
254
+
255
+        if ($process_ins == 'html') {
256
+            $skel['process_ins'] = (
257
+                strpos($corps, '<' . '?') === false
258
+                or
259
+                (strpos($corps, '<' . '?xml') !== false and
260
+                    strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
261
+            )
262
+                ? 'html'
263
+                : 'php';
264
+        }
265
+    }
266
+
267
+    $skel['entetes'] = $headers;
268
+    $skel['texte'] = $corps;
269
+
270
+    return $skel;
271 271
 }
272 272
 
273 273
 //
@@ -281,7 +281,7 @@  discard block
 block discarded – undo
281 281
 inserer_balise_dynamique(balise_%s_dyn(%s), array(%s));
282 282
 if ($lang_select) lang_select();
283 283
 ?'
284
-	. '>');
284
+    . '>');
285 285
 
286 286
 /**
287 287
  * Synthétise une balise dynamique : crée l'appel à l'inclusion
@@ -301,35 +301,35 @@  discard block
 block discarded – undo
301 301
  *     Code PHP pour inclure le squelette de la balise dynamique
302 302
  **/
303 303
 function synthetiser_balise_dynamique($nom, $args, $file, $context_compil) {
304
-	if (
305
-		strncmp($file, '/', 1) !== 0
306
-		// pas de lien symbolique sous Windows
307
-		and !(stristr(PHP_OS, 'WIN') and str_contains($file, ':'))
308
-	) {
309
-		$file = './" . _DIR_RACINE . "' . $file;
310
-	}
311
-
312
-	$lang = $context_compil[4];
313
-	if (preg_match(',\W,', $lang)) {
314
-		$lang = '';
315
-	}
316
-
317
-	$args = array_map('argumenter_squelette', $args);
318
-	if (!empty($context_compil['appel_php_depuis_modele'])) {
319
-		$args[0] = 'arguments_balise_dyn_depuis_modele(' . $args[0] . ')';
320
-	}
321
-	$args = join(', ', $args);
322
-
323
-	$r = sprintf(
324
-		CODE_INCLURE_BALISE,
325
-		$file,
326
-		$lang,
327
-		$nom,
328
-		$args,
329
-		join(', ', array_map('_q', $context_compil))
330
-	);
331
-
332
-	return $r;
304
+    if (
305
+        strncmp($file, '/', 1) !== 0
306
+        // pas de lien symbolique sous Windows
307
+        and !(stristr(PHP_OS, 'WIN') and str_contains($file, ':'))
308
+    ) {
309
+        $file = './" . _DIR_RACINE . "' . $file;
310
+    }
311
+
312
+    $lang = $context_compil[4];
313
+    if (preg_match(',\W,', $lang)) {
314
+        $lang = '';
315
+    }
316
+
317
+    $args = array_map('argumenter_squelette', $args);
318
+    if (!empty($context_compil['appel_php_depuis_modele'])) {
319
+        $args[0] = 'arguments_balise_dyn_depuis_modele(' . $args[0] . ')';
320
+    }
321
+    $args = join(', ', $args);
322
+
323
+    $r = sprintf(
324
+        CODE_INCLURE_BALISE,
325
+        $file,
326
+        $lang,
327
+        $nom,
328
+        $args,
329
+        join(', ', array_map('_q', $context_compil))
330
+    );
331
+
332
+    return $r;
333 333
 }
334 334
 
335 335
 /**
@@ -347,18 +347,18 @@  discard block
 block discarded – undo
347 347
  **/
348 348
 function argumenter_squelette($v) {
349 349
 
350
-	if (is_object($v)) {
351
-		return var_export($v, true);
352
-	} elseif (!is_array($v)) {
353
-		return "'" . texte_script((string) $v) . "'";
354
-	} else {
355
-		$out = [];
356
-		foreach ($v as $k => $val) {
357
-			$out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val);
358
-		}
359
-
360
-		return 'array(' . join(', ', $out) . ')';
361
-	}
350
+    if (is_object($v)) {
351
+        return var_export($v, true);
352
+    } elseif (!is_array($v)) {
353
+        return "'" . texte_script((string) $v) . "'";
354
+    } else {
355
+        $out = [];
356
+        foreach ($v as $k => $val) {
357
+            $out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val);
358
+        }
359
+
360
+        return 'array(' . join(', ', $out) . ')';
361
+    }
362 362
 }
363 363
 
364 364
 /**
@@ -377,13 +377,13 @@  discard block
 block discarded – undo
377 377
  * @return string
378 378
  */
379 379
 function executer_balise_dynamique_dans_un_modele(...$args) {
380
-	if (test_espace_prive()) {
381
-		return executer_balise_dynamique(...$args);
382
-	}
383
-	else {
384
-		$str_args = base64_encode(serialize($args));
385
-		return '<?' . "php \$_zargs=unserialize(base64_decode('$str_args'));echo executer_balise_dynamique(...\$_zargs); ?" . ">\n";
386
-	}
380
+    if (test_espace_prive()) {
381
+        return executer_balise_dynamique(...$args);
382
+    }
383
+    else {
384
+        $str_args = base64_encode(serialize($args));
385
+        return '<?' . "php \$_zargs=unserialize(base64_decode('$str_args'));echo executer_balise_dynamique(...\$_zargs); ?" . ">\n";
386
+    }
387 387
 }
388 388
 
389 389
 
@@ -414,87 +414,87 @@  discard block
 block discarded – undo
414 414
  *     Code PHP d'exécutant l'inclusion du squelette (ou texte) de la balise dynamique
415 415
  **/
416 416
 function executer_balise_dynamique($nom, $args, $context_compil) {
417
-	/** @var string Nom de la balise à charger (balise demandée ou balise générique) */
418
-	$nom_balise = $nom;
419
-	/** @var string Nom de la balise générique (si utilisée) */
420
-	$nom_balise_generique = '';
421
-
422
-	$appel_php_depuis_modele = false;
423
-	if (
424
-		is_array($context_compil)
425
-		and !is_numeric($context_compil[3])
426
-		and empty($context_compil[0])
427
-		and empty($context_compil[1])
428
-		and empty($context_compil[2])
429
-		and empty($context_compil[3])
430
-	) {
431
-		$appel_php_depuis_modele = true;
432
-	}
433
-
434
-	if (!$fonction_balise = charger_fonction($nom_balise, 'balise', true)) {
435
-		// Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article')
436
-		if ($balise_generique = chercher_balise_generique($nom)) {
437
-			// injecter en premier arg le nom de la balise
438
-			array_unshift($args, $nom);
439
-			$nom_balise_generique = $balise_generique['nom_generique'];
440
-			$fonction_balise = $balise_generique['fonction_generique'];
441
-			$nom_balise = $nom_balise_generique;
442
-		}
443
-		unset($balise_generique);
444
-	}
445
-
446
-	if (!$fonction_balise) {
447
-		$msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
448
-		erreur_squelette($msg, $context_compil);
449
-
450
-		return '';
451
-	}
452
-
453
-	// retrouver le fichier qui a déclaré la fonction
454
-	// même si la fonction dynamique est déclarée dans un fichier de fonctions.
455
-	// Attention sous windows, getFileName() retourne un antislash.
456
-	$reflector = new ReflectionFunction($fonction_balise);
457
-	$file = str_replace('\\', '/', $reflector->getFileName());
458
-	if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) {
459
-		$file = substr($file, strlen(_ROOT_RACINE));
460
-	}
461
-
462
-	// Y a-t-il une fonction de traitement des arguments ?
463
-	$f = 'balise_' . $nom_balise . '_stat';
464
-
465
-	$r = !function_exists($f) ? $args : $f($args, $context_compil);
466
-
467
-	if (!is_array($r)) {
468
-		return $r;
469
-	}
470
-
471
-	// verifier que la fonction dyn est la,
472
-	// sinon se replier sur la generique si elle existe
473
-	if (!function_exists('balise_' . $nom_balise . '_dyn')) {
474
-		if (
475
-			$balise_generique = chercher_balise_generique($nom)
476
-			and $nom_balise_generique = $balise_generique['nom_generique']
477
-			and $file = include_spip('balise/' . strtolower($nom_balise_generique))
478
-			and function_exists('balise_' . $nom_balise_generique . '_dyn')
479
-		) {
480
-			// et lui injecter en premier arg le nom de la balise
481
-			array_unshift($r, $nom);
482
-			$nom_balise = $nom_balise_generique;
483
-			if (!_DIR_RESTREINT) {
484
-				$file = _DIR_RESTREINT_ABS . $file;
485
-			}
486
-		} else {
487
-			$msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
488
-			erreur_squelette($msg, $context_compil);
489
-
490
-			return '';
491
-		}
492
-	}
493
-
494
-	if ($appel_php_depuis_modele) {
495
-		$context_compil['appel_php_depuis_modele'] = true;
496
-	}
497
-	return synthetiser_balise_dynamique($nom_balise, $r, $file, $context_compil);
417
+    /** @var string Nom de la balise à charger (balise demandée ou balise générique) */
418
+    $nom_balise = $nom;
419
+    /** @var string Nom de la balise générique (si utilisée) */
420
+    $nom_balise_generique = '';
421
+
422
+    $appel_php_depuis_modele = false;
423
+    if (
424
+        is_array($context_compil)
425
+        and !is_numeric($context_compil[3])
426
+        and empty($context_compil[0])
427
+        and empty($context_compil[1])
428
+        and empty($context_compil[2])
429
+        and empty($context_compil[3])
430
+    ) {
431
+        $appel_php_depuis_modele = true;
432
+    }
433
+
434
+    if (!$fonction_balise = charger_fonction($nom_balise, 'balise', true)) {
435
+        // Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article')
436
+        if ($balise_generique = chercher_balise_generique($nom)) {
437
+            // injecter en premier arg le nom de la balise
438
+            array_unshift($args, $nom);
439
+            $nom_balise_generique = $balise_generique['nom_generique'];
440
+            $fonction_balise = $balise_generique['fonction_generique'];
441
+            $nom_balise = $nom_balise_generique;
442
+        }
443
+        unset($balise_generique);
444
+    }
445
+
446
+    if (!$fonction_balise) {
447
+        $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
448
+        erreur_squelette($msg, $context_compil);
449
+
450
+        return '';
451
+    }
452
+
453
+    // retrouver le fichier qui a déclaré la fonction
454
+    // même si la fonction dynamique est déclarée dans un fichier de fonctions.
455
+    // Attention sous windows, getFileName() retourne un antislash.
456
+    $reflector = new ReflectionFunction($fonction_balise);
457
+    $file = str_replace('\\', '/', $reflector->getFileName());
458
+    if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) {
459
+        $file = substr($file, strlen(_ROOT_RACINE));
460
+    }
461
+
462
+    // Y a-t-il une fonction de traitement des arguments ?
463
+    $f = 'balise_' . $nom_balise . '_stat';
464
+
465
+    $r = !function_exists($f) ? $args : $f($args, $context_compil);
466
+
467
+    if (!is_array($r)) {
468
+        return $r;
469
+    }
470
+
471
+    // verifier que la fonction dyn est la,
472
+    // sinon se replier sur la generique si elle existe
473
+    if (!function_exists('balise_' . $nom_balise . '_dyn')) {
474
+        if (
475
+            $balise_generique = chercher_balise_generique($nom)
476
+            and $nom_balise_generique = $balise_generique['nom_generique']
477
+            and $file = include_spip('balise/' . strtolower($nom_balise_generique))
478
+            and function_exists('balise_' . $nom_balise_generique . '_dyn')
479
+        ) {
480
+            // et lui injecter en premier arg le nom de la balise
481
+            array_unshift($r, $nom);
482
+            $nom_balise = $nom_balise_generique;
483
+            if (!_DIR_RESTREINT) {
484
+                $file = _DIR_RESTREINT_ABS . $file;
485
+            }
486
+        } else {
487
+            $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
488
+            erreur_squelette($msg, $context_compil);
489
+
490
+            return '';
491
+        }
492
+    }
493
+
494
+    if ($appel_php_depuis_modele) {
495
+        $context_compil['appel_php_depuis_modele'] = true;
496
+    }
497
+    return synthetiser_balise_dynamique($nom_balise, $r, $file, $context_compil);
498 498
 }
499 499
 
500 500
 /**
@@ -509,23 +509,23 @@  discard block
 block discarded – undo
509 509
  * @return array|null
510 510
  */
511 511
 function chercher_balise_generique($nom) {
512
-	if (!str_contains($nom, '_')) {
513
-		return null;
514
-	}
515
-	$nom_generique = $nom;
516
-	while (false !== ($p = strrpos($nom_generique, '_'))) {
517
-		$nom_generique = substr($nom_generique, 0, $p + 1);
518
-		$fonction_generique = charger_fonction($nom_generique, 'balise', true);
519
-		if ($fonction_generique) {
520
-			return [
521
-				'nom' => $nom,
522
-				'nom_generique' => $nom_generique,
523
-				'fonction_generique' => $fonction_generique,
524
-			];
525
-		}
526
-		$nom_generique = substr($nom_generique, 0, -1);
527
-	}
528
-	return null;
512
+    if (!str_contains($nom, '_')) {
513
+        return null;
514
+    }
515
+    $nom_generique = $nom;
516
+    while (false !== ($p = strrpos($nom_generique, '_'))) {
517
+        $nom_generique = substr($nom_generique, 0, $p + 1);
518
+        $fonction_generique = charger_fonction($nom_generique, 'balise', true);
519
+        if ($fonction_generique) {
520
+            return [
521
+                'nom' => $nom,
522
+                'nom_generique' => $nom_generique,
523
+                'fonction_generique' => $fonction_generique,
524
+            ];
525
+        }
526
+        $nom_generique = substr($nom_generique, 0, -1);
527
+    }
528
+    return null;
529 529
 }
530 530
 
531 531
 
@@ -549,50 +549,50 @@  discard block
 block discarded – undo
549 549
  * @return null;
550 550
  **/
551 551
 function lang_select_public($lang, $lang_select, $titre = null) {
552
-	// Cas 1. forcer_lang = true et pas de critere {lang_select}
553
-	if (
554
-		isset($GLOBALS['forcer_lang']) and $GLOBALS['forcer_lang']
555
-		and $lang_select !== 'oui'
556
-	) {
557
-		$lang = $GLOBALS['spip_lang'];
558
-	} // Cas 2. l'objet n'a pas de langue definie (ou definie a '')
559
-	elseif (!strlen($lang)) {
560
-		$lang = $GLOBALS['spip_lang'];
561
-	} // Cas 3. l'objet est multilingue !
562
-	elseif (
563
-		$lang_select !== 'oui'
564
-		and strlen($titre) > 10
565
-		and str_contains($titre, '<multi>')
566
-		and str_contains(echappe_html($titre), '<multi>')
567
-	) {
568
-		$lang = $GLOBALS['spip_lang'];
569
-	}
570
-
571
-	// faire un lang_select() eventuellement sur la langue inchangee
572
-	lang_select($lang);
573
-
574
-	return;
552
+    // Cas 1. forcer_lang = true et pas de critere {lang_select}
553
+    if (
554
+        isset($GLOBALS['forcer_lang']) and $GLOBALS['forcer_lang']
555
+        and $lang_select !== 'oui'
556
+    ) {
557
+        $lang = $GLOBALS['spip_lang'];
558
+    } // Cas 2. l'objet n'a pas de langue definie (ou definie a '')
559
+    elseif (!strlen($lang)) {
560
+        $lang = $GLOBALS['spip_lang'];
561
+    } // Cas 3. l'objet est multilingue !
562
+    elseif (
563
+        $lang_select !== 'oui'
564
+        and strlen($titre) > 10
565
+        and str_contains($titre, '<multi>')
566
+        and str_contains(echappe_html($titre), '<multi>')
567
+    ) {
568
+        $lang = $GLOBALS['spip_lang'];
569
+    }
570
+
571
+    // faire un lang_select() eventuellement sur la langue inchangee
572
+    lang_select($lang);
573
+
574
+    return;
575 575
 }
576 576
 
577 577
 
578 578
 // Si un tableau &doublons[articles] est passe en parametre,
579 579
 // il faut le nettoyer car il pourrait etre injecte en SQL
580 580
 function nettoyer_env_doublons($envd) {
581
-	foreach ($envd as $table => $liste) {
582
-		$n = '';
583
-		foreach (explode(',', $liste) as $val) {
584
-			if ($a = intval($val) and $val === strval($a)) {
585
-				$n .= ',' . $val;
586
-			}
587
-		}
588
-		if (strlen($n)) {
589
-			$envd[$table] = $n;
590
-		} else {
591
-			unset($envd[$table]);
592
-		}
593
-	}
594
-
595
-	return $envd;
581
+    foreach ($envd as $table => $liste) {
582
+        $n = '';
583
+        foreach (explode(',', $liste) as $val) {
584
+            if ($a = intval($val) and $val === strval($a)) {
585
+                $n .= ',' . $val;
586
+            }
587
+        }
588
+        if (strlen($n)) {
589
+            $envd[$table] = $n;
590
+        } else {
591
+            unset($envd[$table]);
592
+        }
593
+    }
594
+
595
+    return $envd;
596 596
 }
597 597
 
598 598
 /**
@@ -611,21 +611,21 @@  discard block
 block discarded – undo
611 611
  *     Opérateur trouvé (SELF ou SUBSELECT) sinon false.
612 612
  **/
613 613
 function match_self($w) {
614
-	if (is_string($w)) {
615
-		return false;
616
-	}
617
-	if (is_array($w)) {
618
-		if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
619
-			return $w;
620
-		}
621
-		foreach (array_filter($w, 'is_array') as $sw) {
622
-			if ($m = match_self($sw)) {
623
-				return $m;
624
-			}
625
-		}
626
-	}
627
-
628
-	return false;
614
+    if (is_string($w)) {
615
+        return false;
616
+    }
617
+    if (is_array($w)) {
618
+        if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
619
+            return $w;
620
+        }
621
+        foreach (array_filter($w, 'is_array') as $sw) {
622
+            if ($m = match_self($sw)) {
623
+                return $m;
624
+            }
625
+        }
626
+    }
627
+
628
+    return false;
629 629
 }
630 630
 
631 631
 /**
@@ -641,16 +641,16 @@  discard block
 block discarded – undo
641 641
  *     est remplacée par son code.
642 642
  **/
643 643
 function remplace_sous_requete($w, $sousrequete) {
644
-	if (is_array($w)) {
645
-		if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
646
-			return $sousrequete;
647
-		}
648
-		foreach ($w as $k => $sw) {
649
-			$w[$k] = remplace_sous_requete($sw, $sousrequete);
650
-		}
651
-	}
652
-
653
-	return $w;
644
+    if (is_array($w)) {
645
+        if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
646
+            return $sousrequete;
647
+        }
648
+        foreach ($w as $k => $sw) {
649
+            $w[$k] = remplace_sous_requete($sw, $sousrequete);
650
+        }
651
+    }
652
+
653
+    return $w;
654 654
 }
655 655
 
656 656
 /**
@@ -664,17 +664,17 @@  discard block
 block discarded – undo
664 664
  *     - Conditions avec des sous requêtes
665 665
  **/
666 666
 function trouver_sous_requetes($where) {
667
-	$where_simples = [];
668
-	$where_sous = [];
669
-	foreach ($where as $k => $w) {
670
-		if (match_self($w)) {
671
-			$where_sous[$k] = $w;
672
-		} else {
673
-			$where_simples[$k] = $w;
674
-		}
675
-	}
676
-
677
-	return [$where_simples, $where_sous];
667
+    $where_simples = [];
668
+    $where_sous = [];
669
+    foreach ($where as $k => $w) {
670
+        if (match_self($w)) {
671
+            $where_sous[$k] = $w;
672
+        } else {
673
+            $where_simples[$k] = $w;
674
+        }
675
+    }
676
+
677
+    return [$where_simples, $where_sous];
678 678
 }
679 679
 
680 680
 
@@ -700,292 +700,292 @@  discard block
 block discarded – undo
700 700
  * @return resource
701 701
  */
702 702
 function calculer_select(
703
-	$select = [],
704
-	$from = [],
705
-	$from_type = [],
706
-	$where = [],
707
-	$join = [],
708
-	$groupby = [],
709
-	$orderby = [],
710
-	$limit = '',
711
-	$having = [],
712
-	$table = '',
713
-	$id = '',
714
-	$serveur = '',
715
-	$requeter = true
703
+    $select = [],
704
+    $from = [],
705
+    $from_type = [],
706
+    $where = [],
707
+    $join = [],
708
+    $groupby = [],
709
+    $orderby = [],
710
+    $limit = '',
711
+    $having = [],
712
+    $table = '',
713
+    $id = '',
714
+    $serveur = '',
715
+    $requeter = true
716 716
 ) {
717 717
 
718
-	// retirer les criteres vides:
719
-	// {X ?} avec X absent de l'URL
720
-	// {par #ENV{X}} avec X absent de l'URL
721
-	// IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil)
722
-	$menage = false;
723
-	foreach ($where as $k => $v) {
724
-		if (is_array($v) and count($v)) {
725
-			if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) {
726
-				$op = false;
727
-			} elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) {
728
-				$op = false;
729
-			} else {
730
-				$op = $v[0] ?: $v;
731
-			}
732
-		} else {
733
-			$op = $v;
734
-		}
735
-		if ((!$op) or ($op == 1) or ($op == '0=0')) {
736
-			unset($where[$k]);
737
-			$menage = true;
738
-		}
739
-	}
740
-
741
-	// evacuer les eventuels groupby vide issus d'un calcul dynamique
742
-	$groupby = array_diff($groupby, ['']);
743
-
744
-	// remplacer les sous requetes recursives au calcul
745
-	[$where_simples, $where_sous] = trouver_sous_requetes($where);
746
-	foreach ($where_sous as $k => $w) {
747
-		$menage = true;
748
-		// on recupere la sous requete
749
-		$sous = match_self($w);
750
-		if ($sous[0] == 'SELF') {
751
-			// c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where)
752
-			array_push($where_simples, $sous[2]);
753
-			$wheresub = [
754
-				$sous[2],
755
-				'0=0'
756
-			]; // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where
757
-			$jsub = $join;
758
-			// trouver les jointures utiles a
759
-			// reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees
760
-			// ie L1.objet='article'
761
-			// on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction
762
-			$i = 0;
763
-			do {
764
-				$where[$k] = remplace_sous_requete($w, '(' . calculer_select(
765
-					[$sous[1] . ' AS id'],
766
-					$from,
767
-					$from_type,
768
-					$wheresub,
769
-					$jsub,
770
-					[],
771
-					[],
772
-					'',
773
-					$having,
774
-					$table,
775
-					$id,
776
-					$serveur,
777
-					false
778
-				) . ')');
779
-				if (!$i) {
780
-					$i = 1;
781
-					$wherestring = calculer_where_to_string($where[$k]);
782
-					foreach ($join as $cle => $wj) {
783
-						if (
784
-							(is_countable($wj) ? count($wj) : 0) == 4
785
-							and str_contains($wherestring, (string) "{$cle}.")
786
-						) {
787
-							$i = 0;
788
-							$wheresub[] = $wj[3];
789
-							unset($jsub[$cle][3]);
790
-						}
791
-					}
792
-				}
793
-			} while ($i++ < 1);
794
-		}
795
-		if ($sous[0] == 'SUBSELECT') {
796
-			// c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having)
797
-			array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ?
798
-			$where[$k] = remplace_sous_requete($w, '(' . calculer_select(
799
-				$sous[1], # select
800
-				$sous[2], #from
801
-				[], #from_type
802
-				$sous[3] ? (is_array($sous[3]) ? $sous[3] : [$sous[3]]) : [],
803
-				#where, qui peut etre de la forme string comme dans sql_select
804
-					[], #join
805
-				$sous[4] ?: [], #groupby
806
-				$sous[5] ?: [], #orderby
807
-				$sous[6], #limit
808
-				$sous[7] ?: [], #having
809
-				$table,
810
-				$id,
811
-				$serveur,
812
-				false
813
-			) . ')');
814
-		}
815
-		array_pop($where_simples);
816
-	}
817
-
818
-	foreach ($having as $k => $v) {
819
-		if ((!$v) or ($v == 1) or ($v == '0=0')) {
820
-			unset($having[$k]);
821
-		}
822
-	}
823
-
824
-	// Installer les jointures.
825
-	// Retirer celles seulement utiles aux criteres finalement absents mais
826
-	// parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln
827
-	// si elle est seulement utile a Ln+1 elle meme inutile
828
-
829
-	$afrom = [];
830
-	$equiv = [];
831
-	$k = count($join);
832
-	foreach (array_reverse($join, true) as $cledef => $j) {
833
-		$cle = $cledef;
834
-		// le format de join est :
835
-		// array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]])
836
-		$join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber
837
-		if (count($join[$cle]) == 2) {
838
-			$join[$cle][] = $join[$cle][1];
839
-		}
840
-		if ((is_array($join[$cle]) || $join[$cle] instanceof \Countable ? count($join[$cle]) : 0) == 3) {
841
-			$join[$cle][] = '';
842
-		}
843
-		[$t, $c, $carr, $and] = $join[$cle];
844
-		// si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste
845
-		// pour compat avec ancienne convention
846
-		if (is_numeric($cle)) {
847
-			$cle = "L$k";
848
-		}
849
-		$cle_where_lie = "JOIN-$cle";
850
-		if (
851
-			!$menage
852
-			or isset($afrom[$cle])
853
-			or calculer_jointnul($cle, $select)
854
-			or calculer_jointnul($cle, array_diff_key($join, [$cle => $join[$cle]]))
855
-			or calculer_jointnul($cle, $having)
856
-			or calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => '']))
857
-		) {
858
-			// corriger les references non explicites dans select
859
-			// ou groupby
860
-			foreach ($select as $i => $s) {
861
-				if ($s == $c) {
862
-					$select[$i] = "$cle.$c AS $c";
863
-					break;
864
-				}
865
-			}
866
-			foreach ($groupby as $i => $g) {
867
-				if ($g == $c) {
868
-					$groupby[$i] = "$cle.$c";
869
-					break;
870
-				}
871
-			}
872
-			// on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin
873
-			// sans recours a preg_match
874
-			// un implode(' ',..) est fait dans reinjecte_joint un peu plus bas
875
-			$afrom[$t][$cle] = [
876
-				"\n" .
877
-				($from_type[$cle] ?? 'INNER') . ' JOIN',
878
-				$from[$cle],
879
-				"AS $cle",
880
-				'ON (',
881
-				"$cle.$c",
882
-				'=',
883
-				"$t.$carr",
884
-				($and ? 'AND ' . $and : '') .
885
-				')'
886
-			];
887
-			if (isset($afrom[$cle])) {
888
-				$afrom[$t] = $afrom[$t] + $afrom[$cle];
889
-				unset($afrom[$cle]);
890
-			}
891
-			$equiv[] = $carr;
892
-		} else {
893
-			unset($join[$cledef]);
894
-			if (isset($where_simples[$cle_where_lie])) {
895
-				unset($where_simples[$cle_where_lie]);
896
-				unset($where[$cle_where_lie]);
897
-			}
898
-		}
899
-		unset($from[$cle]);
900
-		$k--;
901
-	}
902
-
903
-	if (count($afrom)) {
904
-		// Regarder si la table principale ne sert finalement a rien comme dans
905
-		//<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3>
906
-		//<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2>
907
-		//<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5>
908
-		// ou dans
909
-		//<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8>
910
-		// qui comporte plusieurs jointures
911
-		// ou dans
912
-		// <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6>
913
-		// <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7>
914
-		// penser a regarder aussi la clause orderby pour ne pas simplifier abusivement
915
-		// <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9>
916
-		// penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement
917
-		// <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10>
918
-
919
-		$t = key($from);
920
-		$c = current($from);
921
-		reset($from);
922
-		$e = '/\b(' . "$t\\." . join('|' . $t . '\.', $equiv) . ')\b/';
923
-		if (
924
-			!(strpos($t, ' ') or // jointure des le depart cf boucle_doc
925
-				calculer_jointnul($t, $select, $e) or
926
-				calculer_jointnul($t, $join, $e) or
927
-				calculer_jointnul($t, $where, $e) or
928
-				calculer_jointnul($t, $orderby, $e) or
929
-				calculer_jointnul($t, $groupby, $e) or
930
-				calculer_jointnul($t, $having, $e))
931
-			&& count($afrom[$t])
932
-		) {
933
-			$nfrom = reset($afrom[$t]);
934
-			$nt = array_key_first($afrom[$t]);
935
-			unset($from[$t]);
936
-			$from[$nt] = $nfrom[1];
937
-			unset($afrom[$t][$nt]);
938
-			$afrom[$nt] = $afrom[$t];
939
-			unset($afrom[$t]);
940
-			$e = '/\b' . preg_quote($nfrom[6]) . '\b/';
941
-			$t = $nfrom[4];
942
-			$alias = '';
943
-			// verifier que les deux cles sont homonymes, sinon installer un alias dans le select
944
-			$oldcle = explode('.', $nfrom[6]);
945
-			$oldcle = end($oldcle);
946
-			$newcle = explode('.', $nfrom[4]);
947
-			$newcle = end($newcle);
948
-			if ($newcle != $oldcle) {
949
-				// si l'ancienne cle etait deja dans le select avec un AS
950
-				// reprendre simplement ce AS
951
-				$as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/';
952
-				if (preg_match($as, implode(',', $select), $m)) {
953
-					$alias = '';
954
-				} else {
955
-					$alias = ', ' . $nfrom[4] . " AS $oldcle";
956
-				}
957
-			}
958
-			$select = remplacer_jointnul($t . $alias, $select, $e);
959
-			$join = remplacer_jointnul($t, $join, $e);
960
-			$where = remplacer_jointnul($t, $where, $e);
961
-			$having = remplacer_jointnul($t, $having, $e);
962
-			$groupby = remplacer_jointnul($t, $groupby, $e);
963
-			$orderby = remplacer_jointnul($t, $orderby, $e);
964
-		}
965
-		$from = reinjecte_joint($afrom, $from);
966
-	}
967
-	if (empty($GLOBALS['debug']) or !is_array($GLOBALS['debug'])) {
968
-		$wasdebug = empty($GLOBALS['debug']) ? false : $GLOBALS['debug'];
969
-		$GLOBALS['debug'] = [];
970
-		if ($wasdebug) {
971
-			$GLOBALS['debug']['debug'] = true;
972
-		}
973
-	}
974
-	$GLOBALS['debug']['aucasou'] = [$table, $id, $serveur, $requeter];
975
-	$r = sql_select(
976
-		$select,
977
-		$from,
978
-		$where,
979
-		$groupby,
980
-		array_filter($orderby),
981
-		$limit,
982
-		$having,
983
-		$serveur,
984
-		$requeter
985
-	);
986
-	unset($GLOBALS['debug']['aucasou']);
987
-
988
-	return $r;
718
+    // retirer les criteres vides:
719
+    // {X ?} avec X absent de l'URL
720
+    // {par #ENV{X}} avec X absent de l'URL
721
+    // IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil)
722
+    $menage = false;
723
+    foreach ($where as $k => $v) {
724
+        if (is_array($v) and count($v)) {
725
+            if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) {
726
+                $op = false;
727
+            } elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) {
728
+                $op = false;
729
+            } else {
730
+                $op = $v[0] ?: $v;
731
+            }
732
+        } else {
733
+            $op = $v;
734
+        }
735
+        if ((!$op) or ($op == 1) or ($op == '0=0')) {
736
+            unset($where[$k]);
737
+            $menage = true;
738
+        }
739
+    }
740
+
741
+    // evacuer les eventuels groupby vide issus d'un calcul dynamique
742
+    $groupby = array_diff($groupby, ['']);
743
+
744
+    // remplacer les sous requetes recursives au calcul
745
+    [$where_simples, $where_sous] = trouver_sous_requetes($where);
746
+    foreach ($where_sous as $k => $w) {
747
+        $menage = true;
748
+        // on recupere la sous requete
749
+        $sous = match_self($w);
750
+        if ($sous[0] == 'SELF') {
751
+            // c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where)
752
+            array_push($where_simples, $sous[2]);
753
+            $wheresub = [
754
+                $sous[2],
755
+                '0=0'
756
+            ]; // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where
757
+            $jsub = $join;
758
+            // trouver les jointures utiles a
759
+            // reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees
760
+            // ie L1.objet='article'
761
+            // on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction
762
+            $i = 0;
763
+            do {
764
+                $where[$k] = remplace_sous_requete($w, '(' . calculer_select(
765
+                    [$sous[1] . ' AS id'],
766
+                    $from,
767
+                    $from_type,
768
+                    $wheresub,
769
+                    $jsub,
770
+                    [],
771
+                    [],
772
+                    '',
773
+                    $having,
774
+                    $table,
775
+                    $id,
776
+                    $serveur,
777
+                    false
778
+                ) . ')');
779
+                if (!$i) {
780
+                    $i = 1;
781
+                    $wherestring = calculer_where_to_string($where[$k]);
782
+                    foreach ($join as $cle => $wj) {
783
+                        if (
784
+                            (is_countable($wj) ? count($wj) : 0) == 4
785
+                            and str_contains($wherestring, (string) "{$cle}.")
786
+                        ) {
787
+                            $i = 0;
788
+                            $wheresub[] = $wj[3];
789
+                            unset($jsub[$cle][3]);
790
+                        }
791
+                    }
792
+                }
793
+            } while ($i++ < 1);
794
+        }
795
+        if ($sous[0] == 'SUBSELECT') {
796
+            // c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having)
797
+            array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ?
798
+            $where[$k] = remplace_sous_requete($w, '(' . calculer_select(
799
+                $sous[1], # select
800
+                $sous[2], #from
801
+                [], #from_type
802
+                $sous[3] ? (is_array($sous[3]) ? $sous[3] : [$sous[3]]) : [],
803
+                #where, qui peut etre de la forme string comme dans sql_select
804
+                    [], #join
805
+                $sous[4] ?: [], #groupby
806
+                $sous[5] ?: [], #orderby
807
+                $sous[6], #limit
808
+                $sous[7] ?: [], #having
809
+                $table,
810
+                $id,
811
+                $serveur,
812
+                false
813
+            ) . ')');
814
+        }
815
+        array_pop($where_simples);
816
+    }
817
+
818
+    foreach ($having as $k => $v) {
819
+        if ((!$v) or ($v == 1) or ($v == '0=0')) {
820
+            unset($having[$k]);
821
+        }
822
+    }
823
+
824
+    // Installer les jointures.
825
+    // Retirer celles seulement utiles aux criteres finalement absents mais
826
+    // parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln
827
+    // si elle est seulement utile a Ln+1 elle meme inutile
828
+
829
+    $afrom = [];
830
+    $equiv = [];
831
+    $k = count($join);
832
+    foreach (array_reverse($join, true) as $cledef => $j) {
833
+        $cle = $cledef;
834
+        // le format de join est :
835
+        // array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]])
836
+        $join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber
837
+        if (count($join[$cle]) == 2) {
838
+            $join[$cle][] = $join[$cle][1];
839
+        }
840
+        if ((is_array($join[$cle]) || $join[$cle] instanceof \Countable ? count($join[$cle]) : 0) == 3) {
841
+            $join[$cle][] = '';
842
+        }
843
+        [$t, $c, $carr, $and] = $join[$cle];
844
+        // si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste
845
+        // pour compat avec ancienne convention
846
+        if (is_numeric($cle)) {
847
+            $cle = "L$k";
848
+        }
849
+        $cle_where_lie = "JOIN-$cle";
850
+        if (
851
+            !$menage
852
+            or isset($afrom[$cle])
853
+            or calculer_jointnul($cle, $select)
854
+            or calculer_jointnul($cle, array_diff_key($join, [$cle => $join[$cle]]))
855
+            or calculer_jointnul($cle, $having)
856
+            or calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => '']))
857
+        ) {
858
+            // corriger les references non explicites dans select
859
+            // ou groupby
860
+            foreach ($select as $i => $s) {
861
+                if ($s == $c) {
862
+                    $select[$i] = "$cle.$c AS $c";
863
+                    break;
864
+                }
865
+            }
866
+            foreach ($groupby as $i => $g) {
867
+                if ($g == $c) {
868
+                    $groupby[$i] = "$cle.$c";
869
+                    break;
870
+                }
871
+            }
872
+            // on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin
873
+            // sans recours a preg_match
874
+            // un implode(' ',..) est fait dans reinjecte_joint un peu plus bas
875
+            $afrom[$t][$cle] = [
876
+                "\n" .
877
+                ($from_type[$cle] ?? 'INNER') . ' JOIN',
878
+                $from[$cle],
879
+                "AS $cle",
880
+                'ON (',
881
+                "$cle.$c",
882
+                '=',
883
+                "$t.$carr",
884
+                ($and ? 'AND ' . $and : '') .
885
+                ')'
886
+            ];
887
+            if (isset($afrom[$cle])) {
888
+                $afrom[$t] = $afrom[$t] + $afrom[$cle];
889
+                unset($afrom[$cle]);
890
+            }
891
+            $equiv[] = $carr;
892
+        } else {
893
+            unset($join[$cledef]);
894
+            if (isset($where_simples[$cle_where_lie])) {
895
+                unset($where_simples[$cle_where_lie]);
896
+                unset($where[$cle_where_lie]);
897
+            }
898
+        }
899
+        unset($from[$cle]);
900
+        $k--;
901
+    }
902
+
903
+    if (count($afrom)) {
904
+        // Regarder si la table principale ne sert finalement a rien comme dans
905
+        //<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3>
906
+        //<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2>
907
+        //<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5>
908
+        // ou dans
909
+        //<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8>
910
+        // qui comporte plusieurs jointures
911
+        // ou dans
912
+        // <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6>
913
+        // <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7>
914
+        // penser a regarder aussi la clause orderby pour ne pas simplifier abusivement
915
+        // <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9>
916
+        // penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement
917
+        // <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10>
918
+
919
+        $t = key($from);
920
+        $c = current($from);
921
+        reset($from);
922
+        $e = '/\b(' . "$t\\." . join('|' . $t . '\.', $equiv) . ')\b/';
923
+        if (
924
+            !(strpos($t, ' ') or // jointure des le depart cf boucle_doc
925
+                calculer_jointnul($t, $select, $e) or
926
+                calculer_jointnul($t, $join, $e) or
927
+                calculer_jointnul($t, $where, $e) or
928
+                calculer_jointnul($t, $orderby, $e) or
929
+                calculer_jointnul($t, $groupby, $e) or
930
+                calculer_jointnul($t, $having, $e))
931
+            && count($afrom[$t])
932
+        ) {
933
+            $nfrom = reset($afrom[$t]);
934
+            $nt = array_key_first($afrom[$t]);
935
+            unset($from[$t]);
936
+            $from[$nt] = $nfrom[1];
937
+            unset($afrom[$t][$nt]);
938
+            $afrom[$nt] = $afrom[$t];
939
+            unset($afrom[$t]);
940
+            $e = '/\b' . preg_quote($nfrom[6]) . '\b/';
941
+            $t = $nfrom[4];
942
+            $alias = '';
943
+            // verifier que les deux cles sont homonymes, sinon installer un alias dans le select
944
+            $oldcle = explode('.', $nfrom[6]);
945
+            $oldcle = end($oldcle);
946
+            $newcle = explode('.', $nfrom[4]);
947
+            $newcle = end($newcle);
948
+            if ($newcle != $oldcle) {
949
+                // si l'ancienne cle etait deja dans le select avec un AS
950
+                // reprendre simplement ce AS
951
+                $as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/';
952
+                if (preg_match($as, implode(',', $select), $m)) {
953
+                    $alias = '';
954
+                } else {
955
+                    $alias = ', ' . $nfrom[4] . " AS $oldcle";
956
+                }
957
+            }
958
+            $select = remplacer_jointnul($t . $alias, $select, $e);
959
+            $join = remplacer_jointnul($t, $join, $e);
960
+            $where = remplacer_jointnul($t, $where, $e);
961
+            $having = remplacer_jointnul($t, $having, $e);
962
+            $groupby = remplacer_jointnul($t, $groupby, $e);
963
+            $orderby = remplacer_jointnul($t, $orderby, $e);
964
+        }
965
+        $from = reinjecte_joint($afrom, $from);
966
+    }
967
+    if (empty($GLOBALS['debug']) or !is_array($GLOBALS['debug'])) {
968
+        $wasdebug = empty($GLOBALS['debug']) ? false : $GLOBALS['debug'];
969
+        $GLOBALS['debug'] = [];
970
+        if ($wasdebug) {
971
+            $GLOBALS['debug']['debug'] = true;
972
+        }
973
+    }
974
+    $GLOBALS['debug']['aucasou'] = [$table, $id, $serveur, $requeter];
975
+    $r = sql_select(
976
+        $select,
977
+        $from,
978
+        $where,
979
+        $groupby,
980
+        array_filter($orderby),
981
+        $limit,
982
+        $having,
983
+        $serveur,
984
+        $requeter
985
+    );
986
+    unset($GLOBALS['debug']['aucasou']);
987
+
988
+    return $r;
989 989
 }
990 990
 
991 991
 /**
@@ -996,79 +996,79 @@  discard block
 block discarded – undo
996 996
  * @return string
997 997
  */
998 998
 function calculer_where_to_string($v, $join = 'AND') {
999
-	if (empty($v)) {
1000
-		return '';
1001
-	}
1002
-
1003
-	if (!is_array($v)) {
1004
-		return $v;
1005
-	} else {
1006
-		$exp = '';
1007
-		if (strtoupper($join) === 'AND') {
1008
-			return $exp . join(" $join ", array_map('calculer_where_to_string', $v));
1009
-		} else {
1010
-			return $exp . join($join, $v);
1011
-		}
1012
-	}
999
+    if (empty($v)) {
1000
+        return '';
1001
+    }
1002
+
1003
+    if (!is_array($v)) {
1004
+        return $v;
1005
+    } else {
1006
+        $exp = '';
1007
+        if (strtoupper($join) === 'AND') {
1008
+            return $exp . join(" $join ", array_map('calculer_where_to_string', $v));
1009
+        } else {
1010
+            return $exp . join($join, $v);
1011
+        }
1012
+    }
1013 1013
 }
1014 1014
 
1015 1015
 
1016 1016
 //condition suffisante (mais non necessaire) pour qu'une table soit utile
1017 1017
 
1018 1018
 function calculer_jointnul($cle, $exp, $equiv = '') {
1019
-	if (!is_array($exp)) {
1020
-		if ($equiv) {
1021
-			$exp = preg_replace($equiv, '', $exp);
1022
-		}
1023
-
1024
-		return preg_match("/\\b$cle\\./", $exp);
1025
-	} else {
1026
-		foreach ($exp as $v) {
1027
-			if (calculer_jointnul($cle, $v, $equiv)) {
1028
-				return true;
1029
-			}
1030
-		}
1031
-
1032
-		return false;
1033
-	}
1019
+    if (!is_array($exp)) {
1020
+        if ($equiv) {
1021
+            $exp = preg_replace($equiv, '', $exp);
1022
+        }
1023
+
1024
+        return preg_match("/\\b$cle\\./", $exp);
1025
+    } else {
1026
+        foreach ($exp as $v) {
1027
+            if (calculer_jointnul($cle, $v, $equiv)) {
1028
+                return true;
1029
+            }
1030
+        }
1031
+
1032
+        return false;
1033
+    }
1034 1034
 }
1035 1035
 
1036 1036
 function reinjecte_joint($afrom, $from) {
1037
-	$from_synth = [];
1038
-	foreach ($from as $k => $v) {
1039
-		$from_synth[$k] = $from[$k];
1040
-		if (isset($afrom[$k])) {
1041
-			foreach ($afrom[$k] as $kk => $vv) {
1042
-				$afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]);
1043
-			}
1044
-			$from_synth["$k@"] = implode(' ', $afrom[$k]);
1045
-			unset($afrom[$k]);
1046
-		}
1047
-	}
1048
-
1049
-	return $from_synth;
1037
+    $from_synth = [];
1038
+    foreach ($from as $k => $v) {
1039
+        $from_synth[$k] = $from[$k];
1040
+        if (isset($afrom[$k])) {
1041
+            foreach ($afrom[$k] as $kk => $vv) {
1042
+                $afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]);
1043
+            }
1044
+            $from_synth["$k@"] = implode(' ', $afrom[$k]);
1045
+            unset($afrom[$k]);
1046
+        }
1047
+    }
1048
+
1049
+    return $from_synth;
1050 1050
 }
1051 1051
 
1052 1052
 function remplacer_jointnul($cle, $exp, $equiv = '') {
1053
-	if (!is_array($exp)) {
1054
-		return preg_replace($equiv, $cle, $exp);
1055
-	} else {
1056
-		foreach ($exp as $k => $v) {
1057
-			$exp[$k] = remplacer_jointnul($cle, $v, $equiv);
1058
-		}
1059
-
1060
-		return $exp;
1061
-	}
1053
+    if (!is_array($exp)) {
1054
+        return preg_replace($equiv, $cle, $exp);
1055
+    } else {
1056
+        foreach ($exp as $k => $v) {
1057
+            $exp[$k] = remplacer_jointnul($cle, $v, $equiv);
1058
+        }
1059
+
1060
+        return $exp;
1061
+    }
1062 1062
 }
1063 1063
 
1064 1064
 // calcul du nom du squelette
1065 1065
 function calculer_nom_fonction_squel($skel, $mime_type = 'html', string $connect = '') {
1066
-	// ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine
1067
-	if ($l = strlen(_DIR_RACINE) and strncmp($skel, _DIR_RACINE, $l) == 0) {
1068
-		$skel = substr($skel, strlen(_DIR_RACINE));
1069
-	}
1070
-
1071
-	return $mime_type
1072
-	. (!$connect ? '' : preg_replace('/\W/', '_', $connect)) . '_'
1073
-	. md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : ''));
1066
+    // ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine
1067
+    if ($l = strlen(_DIR_RACINE) and strncmp($skel, _DIR_RACINE, $l) == 0) {
1068
+        $skel = substr($skel, strlen(_DIR_RACINE));
1069
+    }
1070
+
1071
+    return $mime_type
1072
+    . (!$connect ? '' : preg_replace('/\W/', '_', $connect)) . '_'
1073
+    . md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : ''));
1074 1074
 }
Please login to merge, or discard this patch.