Subversion Repositories Sites.tela-botanica.org

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7 david 1
<?php
2
 
3
//
4
// Ce fichier ne sera execute qu'une fois
5
if (defined("_INC_CALCUL_SQUEL")) return;
6
define("_INC_CALCUL_SQUEL", "1");
7
 
8
 
9
include_local("inc-champ-squel.php3");
10
 
11
 
12
//////////////////////////////////////////////////////////////////////////////
13
//
14
//              Parsing des squelettes
15
//
16
//////////////////////////////////////////////////////////////////////////////
17
 
18
 
19
class Texte {
20
	var $type = 'texte';
21
	var $texte;
22
}
23
 
24
class Champ {
25
	var $type = 'champ';
26
	var $nom_champ, $id_champ;
27
	var $cond_avant, $cond_apres; // tableaux d'objets
28
	var $fonctions;
29
}
30
 
31
class Boucle {
32
	var $type = 'boucle';
33
	var $id_boucle, $id_parent;
34
	var $avant, $cond_avant, $milieu, $cond_apres, $cond_altern, $apres; // tableaux d'objets
35
	var $commande;
36
	var $requete;
37
	var $type_requete;
38
	var $separateur;
39
	var $doublons;
40
	var $lang_select;
41
	var $partie, $total_parties;
42
}
43
 
44
 
45
function parser_boucle($texte, $id_parent) {
46
	global $rubriques_publiques;
47
	global $recherche;
48
	global $tables_relations;
49
 
50
	//
51
	// Detecter et parser la boucle
52
	//
53
 
54
	$p = strpos($texte, '<BOUCLE');
55
	if (!$p && (substr($texte, 0, strlen('<BOUCLE')) != '<BOUCLE')) {
56
		$result = new Texte;
57
		$result->texte = $texte;
58
		return $result;
59
	}
60
 
61
	$result = new Boucle;
62
 
63
	$debut = substr($texte, 0, $p);
64
	$milieu = substr($texte, $p);
65
 
66
	if (!ereg("^(<BOUCLE([0-9]+|[-_][-_.a-zA-Z0-9]*)[[:space:]]*(\([^)]*\)([[:space:]]*\{[^}]*\})*)[[:space:]]*>)", $milieu, $match)) {
67
		include_ecrire ("inc_presentation.php3");
68
		install_debut_html(_T('erreur_boucle_syntaxe'));
69
		$milieu = entites_html($milieu);
70
		echo '<p>'._T('erreur_boucle_syntaxe2', array('milieu' => $milieu));
71
		install_fin_html();
72
		exit;
73
	}
74
 
75
	$commande = $match[1];
76
	$id_boucle = $match[2];
77
	$suite_commande = $match[3];
78
 
79
	//
80
	// Decomposer les structures conditionnelles
81
	//
82
 
83
	$s = "<B$id_boucle>";
84
 
85
	$p = strpos($debut, $s);
86
	if ($p || (substr($debut, 0, strlen($s)) == $s)) {
87
		$cond_avant = substr($debut, $p + strlen($s));
88
		$debut = substr($debut, 0, $p);
89
	}
90
 
91
	$milieu = substr($milieu, strlen($commande));
92
	$s = "</BOUCLE$id_boucle>";
93
	$p = strpos($milieu, $s);
94
	if ((!$p) && (substr($milieu, 0, strlen($s)) != $s)) {
95
		include_ecrire ("inc_presentation.php3");
96
		install_debut_html(_T('erreur_boucle_syntaxe'));
97
		echo '<p>'._T('erreur_boucle_fermant', array('id'=>$id_boucle));
98
		install_fin_html();
99
		exit;
100
	}
101
 
102
	$fin = substr($milieu, $p + strlen($s));
103
	$milieu = substr($milieu, 0, $p);
104
 
105
	$s = "</B$id_boucle>";
106
	$p = strpos($fin, $s);
107
	if ($p || (substr($fin, 0, strlen($s)) == $s)) {
108
		$cond_fin = substr($fin, 0, $p);
109
		$fin = substr($fin, $p + strlen($s));
110
	}
111
 
112
	$s = "<//B$id_boucle>";
113
	$p = strpos($fin, $s);
114
	if ($p || (substr($fin, 0, strlen($s)) == $s)) {
115
		$cond_altern = substr($fin, 0, $p);
116
		$fin = substr($fin, $p + strlen($s));
117
	}
118
 
119
	$id_boucle = ereg_replace("-","_",$id_boucle);
120
 
121
	//
122
	// Parser la commande de la boucle
123
	//
124
 
125
	if (ereg('\(([^)]*)\)', $suite_commande, $regs)) {
126
		$_type = $regs[1];
127
		$s = "($_type)";
128
		$p = strpos($suite_commande, $s);
129
 
130
		// Exploser les parametres
131
		$params = substr($suite_commande, $p + strlen($s));
132
		if (ereg('^[[:space:]]*\{(.*)\}[[:space:]]*$', $params, $match)) $params = $match[1];
133
		$params = split('\}[[:space:]]*\{', $params);
134
		$type = strtolower($_type);
135
 
136
		//
137
		// Type boucle (recursion)
138
		//
139
 
140
		if ($type == 'sites') $type = 'syndication';
141
 
142
		if (substr($type, 0, 6) == 'boucle') {
143
			$requete = substr($_type, 6);
144
			$type = 'boucle';
145
		}
146
		else {
147
			//
148
			// Initialisation separee par type
149
			//
150
 
151
			switch($type) {
152
			case 'articles':
153
				$table = "articles";
154
				$req_from[] = "spip_articles AS $table";
155
				$id_objet = "id_article";
156
				break;
157
 
158
			case 'auteurs':
159
				$table = "auteurs";
160
				$req_from[] = "spip_auteurs AS $table";
161
				$id_objet = "id_auteur";
162
				break;
163
 
164
			case 'breves':
165
				$table = "breves";
166
				$req_from[] = "spip_breves AS $table";
167
				$id_objet = "id_breve";
168
				$col_date = "date_heure";
169
				break;
170
 
171
			case 'forums':
172
				$table = "forums";
173
				$req_from[] = "spip_forum AS $table";
174
				$id_objet = "id_forum";
175
				$col_date = "date_heure";
176
				break;
177
 
178
			case 'signatures':
179
				$table = "signatures";
180
				$req_from[] = "spip_signatures AS $table";
181
				$id_objet = "id_signature";
182
				$col_date = "date_time";
183
				break;
184
 
185
			case 'documents':
186
				$table = "documents";
187
				$req_select[] = "$table.*";
188
				$req_select[] = "types_d.titre AS type_document";
189
				$req_select[] = "types_d.extension AS extension_document";
190
				$req_from[] = "spip_documents AS $table";
191
				$req_from[] = "spip_types_documents AS types_d";
192
				$req_where[] = "$table.id_type = types_d.id_type";
193
				$id_objet = "id_document";
194
				break;
195
 
196
			case 'types_documents':
197
				$table = "types_documents";
198
				$req_from[] = "spip_types_documents AS $table";
199
				$id_objet = "id_type";
200
				break;
201
 
202
			case 'groupes_mots':
203
				$table = "groupes_mots";
204
				$req_from[] = "spip_groupes_mots AS $table";
205
				$id_objet = "id_groupe";
206
				break;
207
 
208
			case 'mots':
209
				$table = "mots";
210
				$req_from[] = "spip_mots AS $table";
211
				$id_objet = "id_mot";
212
				break;
213
 
214
			case 'rubriques':
215
				$table = "rubriques";
216
				$req_from[] = "spip_rubriques AS $table";
217
				$id_objet = "id_rubrique";
218
				break;
219
 
220
			case 'syndication':
221
				$table = "syndic";
222
				$req_from[] = "spip_syndic AS $table";
223
				$req_where[] = "$table.statut='publie'";
224
				$id_objet = "id_syndic";
225
				break;
226
 
227
			case 'syndic_articles':
228
				$table = "articles";
229
				$req_from[] = "spip_syndic_articles AS $table";
230
				$req_from[] = "spip_syndic AS source";
231
				$req_where[] = "$table.id_syndic=source.id_syndic";
232
				$req_where[] = "$table.statut='publie'";
233
				$req_where[] = "source.statut='publie'";
234
				$id_objet = "id_syndic_article";
235
				break;
236
			}
237
			if ($table) {
238
				if ($type == 'articles') {
239
					$s = "$table.id_article,$table.id_rubrique,$table.id_secteur,".
240
						"$table.surtitre,$table.titre,$table.soustitre,$table.date,$table.date_redac,$table.date_modif,".
241
						"$table.visites,$table.popularite,$table.statut,$table.accepter_forum,$table.lang,$table.id_trad";
242
					if (ereg('\#(TEXTE|INTRODUCTION)', $milieu))
243
						$s .= ",$table.texte";
244
					if (ereg('\#(CHAPO|INTRODUCTION)', $milieu))
245
						$s .= ",$table.chapo";
246
					if (ereg('\#(DESCRIPTIF|INTRODUCTION)', $milieu))
247
						$s .= ",$table.descriptif";
248
					if (ereg('\#(PS)', $milieu))
249
						$s .= ",$table.ps";
250
					if (ereg('\#(EXTRA)', $milieu))
251
						$s .= ",$table.extra";
252
					if (ereg("\#(NOM_SITE|URL_SITE)", $milieu))
253
						$s .= ",$table.nom_site,$table.url_site";
254
					$req_select[] = $s;
255
				}
256
				else $req_select[] = "$table.*";
257
			}
258
			if (!$col_date) $col_date = "date";
259
 
260
			//
261
			// Parametres : premiere passe
262
			//
263
			unset($params2);
264
			if ($params) {
265
				reset($params);
266
				while (list(, $param) = each($params)) {
267
					$param = trim($param);
268
					if ($param == 'exclus') {
269
						$req_where[] = "$table.$id_objet!=\$$id_objet";
270
					}
271
					else if ($param == 'tout' OR $param == 'tous') {
272
						$tout = true;
273
					}
274
					else if ($param == 'plat') {
275
						$plat = true;
276
					}
277
					else if ($param == 'unique' OR $param == 'doublons') {
278
						$doublons = 'oui';
279
						$req_where[] = "$table.$id_objet NOT IN (\$id_doublons[$type])";
280
					}
281
					else if (ereg('^(!)? *lang_select(=(oui|non))?$', $param, $match)) {
282
						if (!$lang_select = $match[3]) $lang_select = 'oui';
283
						if ($match[1]) $lang_select = ($lang_select=='oui')?'non':'oui';
284
					}
285
					else if (ereg('^ *"([^"]*)" *$', $param, $match)) {
286
						$separateur = ereg_replace("'","\'",$match[1]);
287
					}
288
					else if (ereg('^([0-9]+),([0-9]*)', $param, $match)) {
289
						$req_limit = $match[1].','.$match[2];
290
					}
291
					else if (ereg('^debut([-_a-zA-Z0-9]+),([0-9]*)$', $param, $match)) {
292
						$debut_lim = "debut".$match[1];
293
						$req_limit = '".intval($GLOBALS[\'HTTP_GET_VARS\'][\''.$debut_lim.'\']).",'.$match[2];
294
					}
295
					else if (ereg('^([0-9]+)/([0-9]+)$', $param, $match)) {
296
						$partie = $match[1];
297
						$total_parties = $match[2];
298
					}
299
					else if ($param == 'recherche') {
300
						if ($type == 'syndication') $req_from[] = "spip_index_syndic AS rec";
301
						else if ($type == 'forums') $req_from[] = "spip_index_forum AS rec";
302
						else $req_from[] = "spip_index_$type AS rec";
303
						$req_select[] = "SUM(rec.points + 100*(rec.hash IN (\$hash_recherche_strict))) AS points";
304
						$req_where[] = "rec.$id_objet=$table.$id_objet";
305
						$req_group = " GROUP BY $table.$id_objet";
306
						$req_where[] = "rec.hash IN (\$hash_recherche)";
307
					}
308
					else $params2[] = $param;
309
				}
310
			}
311
			$params = $params2;
312
 
313
			//
314
			// Parametres : deuxieme passe
315
			//
316
			if ($params) {
317
				reset($params);
318
				while (list(, $param) = each($params)) {
319
 
320
					// Classement par ordre inverse
321
					if ($param == 'inverse') {
322
						if ($req_order) $req_order .= ' DESC';
323
					}
324
					// Gerer les traductions
325
					else if ($param == 'traduction') {
326
						$req_where[] = "$table.id_trad > 0 AND $table.id_trad = \$id_trad";
327
					}
328
					else if ($param == 'origine_traduction') {
329
						$req_where[] = "$table.id_trad = $table.id_article";
330
					}
331
 
332
					// Special rubriques
333
					else if ($param == 'meme_parent') {
334
						$req_where[] = "$table.id_parent=\$id_parent";
335
						if ($type == 'forums') {
336
							$req_where[] = "$table.id_parent > 0";
337
							$plat = true;
338
						}
339
					}
340
					else if ($param == 'racine') {
341
						$req_where[] = "$table.id_parent=0";
342
					}
343
					else if (ereg("^branche *(\??)", $param, $regs)) {
344
						if (!$regs[1])
345
							$req_where[] = "$table.id_rubrique IN (\".calcul_branche(\$id_rubrique).\")";
346
						else
347
							$req_where[] = "('\$id_rubrique'='' OR $table.id_rubrique IN (\".calcul_branche(\$id_rubrique).\"))";
348
 					}
349
 
350
					// Restriction de valeurs (implicite ou explicite)
351
					else if (ereg('^([a-zA-Z_]+) *(\??) *((!?)(<=?|>=?|==?|\?) *"?([^<>=!"?]*))?"?$', $param, $match)) {
352
						// Variable comparee
353
						$col = $match[1];
354
						$col_table = $table;
355
 
356
						// Valeur de comparaison
357
						if ($match[3])
358
							$val = $match[6];
359
						else {
360
							$val = $match[1];
361
							// Si id_parent, comparer l'id_parent avec l'id_objet de la boucle superieure
362
							if ($val == 'id_parent')
363
								$val = $id_objet;
364
							// Si id_enfant, comparer l'id_objet avec l'id_parent de la boucle superieure
365
							else if ($val == 'id_enfant')
366
								$val = 'id_parent';
367
							$val = '$'.$val;
368
						}
369
 
370
						// operateur optionnel {lang?}
371
						$ou_rien = ($match[2]) ? "'$val'='' OR " : '';
372
 
373
						// Traitement general des relations externes
374
						if ($s = $tables_relations[$type][$col]) {
375
							$col_table = "rel_$type";
376
							$req_from[] = "$s AS $col_table";
377
							$req_where[] = "$table.$id_objet=$col_table.$id_objet";
378
							$req_group = " GROUP BY $table.$id_objet";
379
							$flag_lien = true;
380
						}
381
						// Cas particulier pour les raccourcis 'type_mot' et 'titre_mot'
382
						else if ($type != 'mots' AND ($col == 'type_mot' OR $col == 'titre_mot' OR $col == 'id_groupe')) {
383
							if ($type == 'forums')
384
								$col_lien = "spip_mots_forum";
385
							else if ($type == 'syndication')
386
								$col_lien = "spip_mots_syndic";
387
							else
388
								$col_lien = 'spip_mots_'.$type;
389
							$req_from[] = "$col_lien AS lien_mot";
390
							$req_from[] = 'spip_mots AS mots';
391
							$req_where[] = "$table.$id_objet=lien_mot.$id_objet";
392
							$req_where[] = "lien_mot.id_mot=mots.id_mot";
393
							$req_group = " GROUP BY $table.$id_objet";
394
							$col_table = 'mots';
395
							$flag_lien = true;
396
							if ($col == 'type_mot')
397
								$col = 'type';
398
							else if ($col == 'titre_mot')
399
								$col = 'titre';
400
							else if ($col == 'id_groupe')
401
								$col = 'id_groupe';
402
						}
403
 
404
						// Cas particulier : selection des documents selon l'extension
405
						if ($type == 'documents' AND $col == 'extension') {
406
							$col_table = 'types_d';
407
						}
408
						// HACK : selection des documents selon mode 'image' (a creer en dur dans la base)
409
						else if ($type == 'documents' AND $col == 'mode' AND $val == 'image') {
410
							$val = 'vignette';
411
						}
412
						// Cas particulier : lier les articles syndiques au site correspondant
413
						else if ($type == 'syndic_articles' AND !ereg("^(id_syndic_article|titre|url|date|descriptif|lesauteurs)$",$col))
414
							$col_table = 'source';
415
 
416
						// Cas particulier : id_enfant => utiliser la colonne id_objet
417
						if ($col == 'id_enfant')
418
							$col = $id_objet;
419
						// Cas particulier : id_secteur = id_rubrique pour certaines tables
420
						else if (($type == 'breves' OR $type == 'forums') AND $col == 'id_secteur')
421
							$col = 'id_rubrique';
422
 
423
						// Cas particulier : expressions de date
424
						if (ereg("^(date|mois|annee|age|age_relatif|jour_relatif|mois_relatif|annee_relatif)(_redac)?$", $col, $regs)) {
425
							$col = $regs[1];
426
							if ($regs[2]) {
427
								$date_orig = "$table.date_redac";
428
								$date_compare = 'date_redac';
429
							}
430
							else {
431
								$date_orig = "$table.$col_date";
432
								$date_compare = 'date';
433
							}
434
 
435
							if ($col == 'date') {
436
								$col = $date_orig;
437
								$col_table = '';
438
							}
439
							else if ($col == 'mois') {
440
								$col = "MONTH($date_orig)";
441
								$col_table = '';
442
							}
443
							else if ($col == 'annee') {
444
								$col = "YEAR($date_orig)";
445
								$col_table = '';
446
							}
447
							else if ($col == 'age') {
448
								$col = "(LEAST((UNIX_TIMESTAMP(now())-UNIX_TIMESTAMP($date_orig))/86400, TO_DAYS(now())-TO_DAYS($date_orig), DAYOFMONTH(now())-DAYOFMONTH($date_orig)+30.4368*(MONTH(now())-MONTH($date_orig))+365.2422*(YEAR(now())-YEAR($date_orig))))";
449
								$col_table = '';
450
							}
451
							else if ($col == 'age_relatif') {
452
								$col = "LEAST((UNIX_TIMESTAMP('\$$date_compare')-UNIX_TIMESTAMP($date_orig))/86400, TO_DAYS('\$$date_compare')-TO_DAYS($date_orig), DAYOFMONTH('\$$date_compare')-DAYOFMONTH($date_orig)+30.4368*(MONTH('\$$date_compare')-MONTH($date_orig))+365.2422*(YEAR('\$$date_compare')-YEAR($date_orig)))";
453
								$col_table = '';
454
							}
455
							else if ($col == 'jour_relatif') {
456
								$col = "LEAST(TO_DAYS('\$$date_compare')-TO_DAYS($date_orig), DAYOFMONTH('\$$date_compare')-DAYOFMONTH($date_orig)+30.4368*(MONTH('\$$date_compare')-MONTH($date_orig))+365.2422*(YEAR('\$$date_compare')-YEAR($date_orig)))";
457
								$col_table = '';
458
							}
459
							else if ($col == 'mois_relatif') {
460
								$col = "(MONTH('\$$date_compare')-MONTH($date_orig)+12*(YEAR('\$$date_compare')-YEAR($date_orig)))";
461
								$col_table = '';
462
							}
463
							else if ($col == 'annee_relatif') {
464
								$col = "YEAR('\$$date_compare')-YEAR($date_orig)";
465
								$col_table = '';
466
							}
467
						}
468
 
469
						if ($type == 'forums' AND ($col == 'id_parent' OR $col == 'id_forum'))
470
							$plat = true;
471
 
472
						// Operateur de comparaison
473
						if ($match[5]) {
474
							$op = $match[5];
475
							if ($op == '==') $op = ' REGEXP ';
476
						}
477
						else {
478
							$op = '=';
479
						}
480
 
481
						if ($col_table) $col_table .= '.';
482
						$where = "($ou_rien$col_table$col$op'".addslashes($val)."')";
483
 
484
						if ($match[4] == '!') $where = "NOT ($where)";
485
						$req_where[] = $where;
486
					}
487
 
488
					// Selection du classement
489
					else if (ereg('^par[[:space:]]+([^}]*)$', $param, $match)) {
490
						$tri = trim($match[1]);
491
						if ($tri == 'hasard') { // par hasard
492
							$req_select[] = "MOD($table.$id_objet * UNIX_TIMESTAMP(), 32767) & UNIX_TIMESTAMP() AS alea";
493
							$req_order = " ORDER BY alea";
494
						}
495
						else if ($tri == 'titre_mot'){ // par titre_mot
496
							$req_order= " ORDER BY mots.titre";
497
						}
498
						else if ($tri == 'type_mot'){ // par type_mot
499
							$req_order= " ORDER BY mots.type";
500
						}
501
						else if ($tri == 'points'){ // par points
502
							$req_order= " ORDER BY points";
503
						}
504
						else if (ereg("^num[[:space:]]+([^,]*)(,.*)?",$tri, $match2)) { // par num champ
505
							$req_select[] = "0+$table.".$match2[1]." AS num";
506
							$req_order = " ORDER BY num".$match2[2];
507
						}
508
						else if (ereg("^[a-z0-9]+$", $tri)) { // par champ
509
							$col = $tri;
510
							if ($col == 'date') $col = $col_date;
511
							$req_order = " ORDER BY $table.$col";
512
						}
513
						else { // tris bizarres, par formule composee, virgules, etc.
514
							$req_order = " ORDER BY ".$tri;
515
						}
516
					}
517
				}
518
			}
519
 
520
			//
521
			// Post-traitement separe par type
522
			//
523
 
524
			switch($type) {
525
			case 'articles':
526
				$post_dates = lire_meta("post_dates");
527
				if ($post_dates == 'non') $req_where[] = "$table.date<NOW()";
528
				$req_where[] = "$table.statut='publie'";
529
				break;
530
 
531
			case 'groupes_mots':
532
				// pas de restriction sur les groupes de_mots
533
				break;
534
 
535
			case 'mots':
536
				// pas de restriction sur les mots
537
				break;
538
 
539
			case 'breves':
540
				$req_where[] = "$table.statut='publie'";
541
				break;
542
 
543
			case 'rubriques':
544
				if (!$tout) $req_where[] = "$table.statut='publie'";
545
				break;
546
 
547
			case 'forums':
548
				// Par defaut, selectionner uniquement les forums sans pere
549
				if (!$plat) $req_where[] = "$table.id_parent=0";
550
				$req_where[] = "$table.statut='publie'";
551
				break;
552
 
553
			case 'signatures':
554
				$req_from[] = 'spip_petitions AS petitions';
555
				$req_from[] = 'spip_articles AS articles';
556
				$req_where[] = "petitions.id_article=articles.id_article";
557
				$req_where[] = "petitions.id_article=$table.id_article";
558
 
559
				$req_where[] = "$table.statut='publie'";
560
				$req_group = " GROUP BY $table.$id_objet";
561
				break;
562
 
563
			case 'syndic_articles':
564
				$req_select[]='syndic.nom_site AS nom_site';
565
				$req_select[]='syndic.url_site AS url_site';
566
				$req_from[]='spip_syndic AS syndic';
567
				$req_where[] = "syndic.id_syndic=$table.id_syndic";
568
				break;
569
 
570
			case 'documents':
571
				$req_where[] = "$table.taille > 0";
572
				break;
573
 
574
			case 'auteurs':
575
				// Si pas de lien avec un article, selectionner
576
				// uniquement les auteurs d'un article publie
577
				if (!$tout AND !$flag_lien) {
578
					$req_from[] = 'spip_auteurs_articles AS lien';
579
					$req_from[] = 'spip_articles AS articles';
580
					$req_where[] = "lien.id_auteur=$table.id_auteur";
581
					$req_where[] = "lien.id_article=articles.id_article";
582
					$req_where[] = "articles.statut='publie'";
583
					$req_group = " GROUP BY $table.$id_objet";
584
				}
585
				// pas d'auteurs poubellises
586
				$req_where[] = "NOT($table.statut='5poubelle')";
587
				break;
588
			}
589
		}
590
 
591
		//
592
		// Construire la requete
593
		//
594
		if ($type == 'hierarchie')
595
			$requete = $req_limit;
596
		else if ($req_select) {
597
			$requete = 'SELECT '.join(',', $req_select)." FROM ".join(',', $req_from);
598
			if ($req_where) $requete .= " WHERE ".join(" AND ", $req_where);
599
			$requete .= $req_group;
600
			$requete .= $req_order;
601
			if ($req_limit) $requete .= " LIMIT ".$req_limit;
602
		}
603
		$result->type_requete = $type;
604
		$result->requete = $requete;
605
		$result->doublons = $doublons;
606
		$result->lang_select = $lang_select;
607
		$result->separateur = $separateur;
608
	}
609
 
610
 
611
	//
612
	// Stocker le tout dans le resultat de la fonction
613
	//
614
 
615
	$result->id_boucle = $id_boucle;
616
	$result->id_parent = $id_parent;
617
	$result->commande = $commande;
618
	$result->avant = $debut;
619
	$result->cond_avant = parser_texte($cond_avant, $id_parent);
620
	$result->cond_apres = parser_texte($cond_fin, $id_parent);
621
	$result->cond_altern = parser_texte($cond_altern, $id_parent);
622
	$result->milieu = parser_texte($milieu, $id_boucle);
623
	$result->apres = $fin;
624
	$result->partie = $partie;
625
	$result->total_parties = $total_parties;
626
 
627
	return $result;
628
}
629
 
630
 
631
 
632
function parser_champs($texte) {
633
	global $champs;
634
	global $champs_count;
635
	global $champs_valides;
636
	global $champs_traitement;
637
	global $champs_pretraitement;
638
	global $champs_posttraitement;
639
 
640
	$debut = '';
641
	$result=Array();
642
	while ($texte) {
643
		$r = ereg('(#([a-zA-Z_]+)(\*?))', $texte, $regs);
644
		if ($r) {
645
			unset($champ);
646
			$nom_champ = $regs[2];
647
			$flag_brut = $regs[3];
648
			$s = $regs[1];
649
			$p = strpos($texte, $s);
650
			if ($champs_valides[$nom_champ]) {
651
				$debut .= substr($texte, 0, $p);
652
				if ($debut) {
653
					$champ = new Texte;
654
					$champ->texte = $debut;
655
					$result[] = $champ;
656
				}
657
				$champ = new Champ;
658
				$champ->nom_champ = $nom_champ;
659
				$champ->fonctions = $champs_pretraitement[$nom_champ];
660
				if (!$flag_brut AND $champs_traitement[$nom_champ]) {
661
					reset($champs_traitement[$nom_champ]);
662
					while (list(, $f) = each($champs_traitement[$nom_champ])) {
663
						$champ->fonctions[] = $f;
664
					}
665
				}
666
				if ($champs_posttraitement[$nom_champ]) {
667
					reset($champs_posttraitement[$nom_champ]);
668
					while (list(, $f) = each($champs_posttraitement[$nom_champ])) {
669
						$champ->fonctions[] = $f;
670
					}
671
				}
672
				$champs_count++;
673
				$champ->id_champ = $champs_count;
674
				$champs[$champs_count] = $champ;
675
				$result[] = $champ;
676
				$debut = '';
677
			}
678
			else {
679
				$debut .= substr($texte, 0, $p + strlen($s));
680
			}
681
			$texte = substr($texte, $p + strlen($s));
682
		}
683
		else {
684
			$champ = new Texte;
685
			$champ->texte = $debut.$texte;
686
			if ($champ->texte) $result[] = $champ;
687
			break;
688
		}
689
	}
690
	return $result;
691
}
692
 
693
 
694
function parser_champs_etendus($texte) {
695
	global $champs;
696
	global $champs_count;
697
	global $champs_valides;
698
	global $champs_traitement;
699
	global $champs_pretraitement;
700
	global $champs_posttraitement;
701
 
702
	$debut = '';
703
	while ($texte) {
704
		$r = ereg('(\[([^\[]*)\(#([a-zA-Z_]+)(\*?)([^])]*)\)([^]]*)\])', $texte, $regs);
705
 
706
		if ($r) {
707
			$cond_avant = $regs[2];
708
			$nom_champ = $regs[3];
709
			$flag_brut = $regs[4];
710
			$fonctions = $regs[5];
711
			$cond_apres = $regs[6];
712
			$s = $regs[1];
713
			$p = strpos($texte, $s);
714
			if ($champs_valides[$nom_champ]) {
715
				$debut .= substr($texte, 0, $p);
716
				if ($debut) {
717
					$c = parser_champs($debut);
718
					reset($c);
719
					while (list(, $val) = each($c)) $result[] = $val;
720
				}
721
				$champ = new Champ;
722
				$champ->nom_champ = $nom_champ;
723
				$champ->cond_avant = parser_champs($cond_avant);
724
				$champ->cond_apres = parser_champs($cond_apres);
725
				$champ->fonctions = $champs_pretraitement[$nom_champ];
726
				if (!$flag_brut AND $champs_traitement[$nom_champ]) {
727
					reset($champs_traitement[$nom_champ]);
728
					while (list(, $f) = each($champs_traitement[$nom_champ])) {
729
						$champ->fonctions[] = $f;
730
					}
731
				}
732
				if ($fonctions) {
733
					$fonctions = explode('|', ereg_replace("^\|", "", $fonctions));
734
					reset($fonctions);
735
					while (list(, $f) = each($fonctions)) $champ->fonctions[] = $f;
736
				}
737
				if ($champs_posttraitement[$nom_champ]) {
738
					reset($champs_posttraitement[$nom_champ]);
739
					while (list(, $f) = each($champs_posttraitement[$nom_champ])) {
740
						$champ->fonctions[] = $f;
741
					}
742
				}
743
				$champs_count++;
744
				$champ->id_champ = $champs_count;
745
				$champs[$champs_count] = $champ;
746
				$result[] = $champ;
747
				$debut = '';
748
			}
749
			else {
750
				$debut .= substr($texte, 0, $p + strlen($s));
751
			}
752
			$texte = substr($texte, $p + strlen($s));
753
		}
754
		else {
755
			$c = parser_champs($debut.$texte);
756
			reset($c);
757
			while (list(, $val) = each($c)) $result[] = $val;
758
			break;
759
		}
760
	}
761
	return $result;
762
}
763
 
764
function parser_texte($texte, $id_boucle) {
765
	global $boucles;
766
 
767
	$i = 0;
768
 
769
	while ($texte) {
770
		$boucle = parser_boucle($texte, $id_boucle);
771
		if ($boucle->type == 'texte') {
772
			if ($c = parser_champs_etendus($boucle->texte)) {
773
				reset($c);
774
				while (list(, $val) = each($c)) {
775
					$result[$i] = $val;
776
					$i++;
777
				}
778
			}
779
			$texte = '';
780
		}
781
		else {
782
			if ($c = parser_champs_etendus($boucle->avant)) {
783
				reset($c);
784
				while (list(, $val) = each($c)) {
785
					$result[$i] = $val;
786
					$i++;
787
				}
788
			}
789
			$texte = $boucle->apres;
790
			$boucle->avant = '';
791
			$boucle->apres = '';
792
			$result[$i] = $boucle;
793
			$i++;
794
			if (!$boucles[$boucle->id_boucle])
795
				$boucles[$boucle->id_boucle] = $boucle;
796
			else {
797
				include_ecrire ("inc_presentation.php3");
798
				install_debut_html(_T('erreur_boucle_syntaxe'));
799
				$id = $boucle->id_boucle;
800
				echo '<p>'._T('erreur_boucle_double', array('id'=>$id));
801
				install_fin_html();
802
				exit;
803
			}
804
		}
805
	}
806
 
807
	return $result;
808
}
809
 
810
 
811
function parser($texte) {
812
	global $racine;
813
 
814
	// Parser le texte et retourner le tableau racine
815
 
816
	$racine = parser_texte($texte, '');
817
}
818
 
819
 
820
 
821
 
822
//////////////////////////////////////////////////////////////////////////////
823
//
824
//              Calcul des squelettes
825
//
826
//////////////////////////////////////////////////////////////////////////////
827
 
828
//
829
// appliquer les filtres a un champ
830
//
831
function applique_filtres ($fonctions, $code) {
832
	if ($fonctions) {
833
		while (list(, $fonc) = each($fonctions)) {
834
			if ($fonc) {
835
				$arglist = '';
836
				if (ereg('([^\{\}]*)\{(.+)\}$', $fonc, $regs)) {
837
					$fonc = $regs[1];
838
					if (trim($regs[2]))
839
						$arglist = ','.$regs[2];
840
				}
841
				if (function_exists($fonc))
842
					$code = "$fonc($code$arglist)";
843
				else
844
					$code = "'"._T('erreur_filtre', array('filtre' => $fonc))."'";
845
			}
846
		}
847
	}
848
	return $code;
849
}
850
 
851
 
852
//
853
// Generer le code PHP correspondant a un champ SPIP
854
//
855
 
856
function calculer_champ($id_champ, $id_boucle, $nom_var)
857
{
858
	global $les_notes;
859
	global $boucles;
860
	global $champs;
861
	global $flag_ob;
862
	global $flag_pcre;
863
 
864
	$idb = $id_boucle;
865
 
866
	//
867
	// Calculer $id_row en prenant la boucle la plus proche
868
	// (i.e. la plus profonde) qui autorise le champ demande
869
	//
870
 
871
	$offset_boucle = 0;
872
	while (strlen($idb)) {
873
		// $rows_articles, etc. : tables pregenerees contenant les correspondances
874
		// (nom du champ -> numero de colonne mysql) en fonction du type de requete
875
		$id_row = $GLOBALS['rows_'.$boucles[$idb]->type_requete][$champs[$id_champ]->nom_champ];
876
		if ($id_row) break;
877
		$idb = $boucles[$idb]->id_parent;
878
		$offset_boucle++;
879
	}
880
 
881
	//
882
	// Si cas general (le plus simple), generation
883
	// du code php effectuant le calcul du champ
884
	//
885
 
886
	if ($id_row) {
887
		$fonctions = $champs[$id_champ]->fonctions;
888
 
889
		if ($offset_boucle) $code = "\$pile_boucles[\$id_instance-$offset_boucle]->row[$id_row]";
890
		else $code = "\$row[$id_row]";
891
 
892
		$code = applique_filtres ($fonctions, $code);
893
 
894
		return "	\$$nom_var = $code;\n";
895
	}
896
 
897
 
898
	//
899
	// Ici traitement des cas particuliers
900
	//
901
 
902
/*	$milieu = '<blink>#'.$champs[$id_champ]->nom_champ.'</blink>'; // pour debugger les squelettes
903
	$milieu = "	\$$nom_var = '$milieu';\n";*/
904
 
905
	$fonctions = $champs[$id_champ]->fonctions;
906
	switch($nom_champ = $champs[$id_champ]->nom_champ) {
907
 
908
	//
909
	// Les logos (rubriques, articles...)
910
	//
911
 
912
	case 'LOGO_ARTICLE':
913
	case 'LOGO_ARTICLE_NORMAL':
914
	case 'LOGO_ARTICLE_RUBRIQUE':
915
	case 'LOGO_ARTICLE_SURVOL':
916
	case 'LOGO_AUTEUR':
917
	case 'LOGO_AUTEUR_NORMAL':
918
	case 'LOGO_AUTEUR_SURVOL':
919
	case 'LOGO_SITE':
920
	case 'LOGO_BREVE':
921
	case 'LOGO_BREVE_RUBRIQUE':
922
	case 'LOGO_MOT':
923
	case 'LOGO_RUBRIQUE':
924
	case 'LOGO_RUBRIQUE_NORMAL':
925
	case 'LOGO_RUBRIQUE_SURVOL':
926
	case 'LOGO_DOCUMENT':
927
		$milieu = '';
928
		ereg("^LOGO_(([a-zA-Z]+).*)$", $nom_champ, $regs);
929
		$type_logo = $regs[1];
930
		$type_objet = strtolower($regs[2]);
931
		$filtres = '';
932
		if ($fonctions) {
933
			while (list(, $nom) = each($fonctions)) {
934
				if (ereg('^(left|right|center|top|bottom)$', $nom))
935
					$align = $nom;
936
				else if ($nom == 'lien') {
937
					$flag_lien_auto = 'oui';
938
					$flag_stop = true;
939
				}
940
				else if ($nom == 'fichier') {
941
					$flag_fichier = 'oui';
942
					$flag_stop = true;
943
				}
944
				else if ($nom == '')	// double || signifie "on passe aux filtres"
945
					$flag_stop = true;
946
				else if (!$flag_stop) {
947
					$lien = $nom;
948
					$flag_stop = true;
949
				}
950
				else // apres un URL ou || ou |fichier ce sont des filtres (sauf left...lien...fichier)
951
					$filtres[] = $nom;
952
			}
953
			// recuperer les filtres s'il y en a
954
			$fonctions = $filtres;
955
		}
956
		if ($flag_lien_auto && !$lien) {
957
			$milieu .= "
958
			\$lien = generer_url_$type_objet(\$contexte['id_$type_objet']);
959
			";
960
		}
961
		else {
962
			$milieu .= '
963
			$lien = transformer_lien_logo($contexte, \''.addslashes($lien).'\');
964
			';
965
		}
966
 
967
		if ($type_logo == 'RUBRIQUE') {
968
			$milieu .= '
969
			list($logon, $logoff) = IMG_image(image_rubrique($contexte["id_rubrique"]));
970
			';
971
		}
972
		else if ($type_logo == 'RUBRIQUE_NORMAL') {
973
			$milieu .= '
974
			list($logon,) = IMG_image(image_rubrique($contexte["id_rubrique"]));
975
			$logoff = "";
976
			';
977
		}
978
		else if ($type_logo == 'RUBRIQUE_SURVOL') {
979
			$milieu .= '
980
			list(,$logon) = IMG_image(image_rubrique($contexte["id_rubrique"]));
981
			$logoff = "";
982
			';
983
		}
984
		else if ($type_logo == 'DOCUMENT'){
985
			$milieu .= '
986
			$logon = integre_image($contexte["id_document"],"","fichier_vignette");
987
			$logoff = "";
988
			';
989
		}
990
		else if ($type_logo == 'AUTEUR') {
991
			$milieu .= '
992
			list($logon, $logoff) = IMG_image(image_auteur($contexte["id_auteur"]));
993
			';
994
		}
995
		else if ($type_logo == 'AUTEUR_NORMAL') {
996
			$milieu .= '
997
			list($logon,) = IMG_image(image_auteur($contexte["id_auteur"]));
998
			$logoff = "";
999
			';
1000
		}
1001
		else if ($type_logo == 'AUTEUR_SURVOL') {
1002
			$milieu .= '
1003
			list(,$logon) = IMG_image(image_auteur($contexte["id_auteur"]));
1004
			$logoff = "";
1005
			';
1006
		}
1007
		else if ($type_logo == 'BREVE') {
1008
			$milieu .= '
1009
			list($logon, $logoff) = IMG_image(image_breve($contexte["id_breve"]));
1010
			';
1011
		}
1012
		else if ($type_logo == 'BREVE_RUBRIQUE') {
1013
		  $milieu .= '
1014
			list($logon, $logoff) = IMG_image(image_breve($contexte["id_breve"]));
1015
			if (!$logon)
1016
				list($logon, $logoff) = IMG_image(image_rubrique($contexte["id_rubrique"]));
1017
		  ';
1018
		}
1019
		else if ($type_logo == 'SITE') {
1020
			$milieu .= '
1021
			list($logon, $logoff) = IMG_image(image_site($contexte["id_syndic"]));
1022
			';
1023
		}
1024
		else if ($type_logo == 'MOT') {
1025
			$milieu .= '
1026
			list($logon, $logoff) = IMG_image(image_mot($contexte["id_mot"]));
1027
			';
1028
		}
1029
		else if ($type_logo == 'ARTICLE') {
1030
			$milieu .= '
1031
			list($logon, $logoff) = IMG_image(image_article($contexte["id_article"]));
1032
			';
1033
		}
1034
		else if ($type_logo == 'ARTICLE_NORMAL') {
1035
			$milieu .= '
1036
			list($logon,) = IMG_image(image_article($contexte["id_article"]));
1037
			$logoff = "";
1038
			';
1039
		}
1040
		else if ($type_logo == 'ARTICLE_SURVOL') {
1041
			$milieu .= '
1042
			list(,$logon) = IMG_image(image_article($contexte["id_article"]));
1043
			$logoff = "";
1044
			';
1045
		}
1046
		else if ($type_logo == 'ARTICLE_RUBRIQUE') {
1047
			$milieu .= '
1048
			list($logon, $logoff) = IMG_image(image_article($contexte["id_article"]));
1049
			if (!$logon)
1050
				list($logon, $logoff) = IMG_image(image_rubrique($contexte["id_rubrique"]));
1051
			';
1052
		}
1053
		if ($flag_fichier)
1054
			$milieu .= "		\$$nom_var = ereg_replace('^/?IMG/','',\$logon);\n"; // compatibilite ascendante : pas de 'IMG/'
1055
		else
1056
			$milieu .= "		\$$nom_var = affiche_logos(\$logon, \$logoff, \$lien, '".addslashes($align)."');\n";
1057
		break;
1058
 
1059
	//
1060
	// Liste des auteurs d'un article
1061
	//
1062
 
1063
	case 'LESAUTEURS':
1064
		$milieu = '
1065
		if ($i = $contexte["id_article"]) {
1066
			$query_auteurs = "SELECT auteurs.nom, auteurs.email FROM spip_auteurs AS auteurs, spip_auteurs_articles AS lien WHERE lien.id_article=$i AND auteurs.id_auteur=lien.id_auteur";
1067
			$result_auteurs = spip_query($query_auteurs);
1068
			$auteurs = "";
1069
			while($row_auteur = spip_fetch_array($result_auteurs)) {
1070
				$nom_auteur = typo($row_auteur["nom"]);
1071
				$email_auteur = $row_auteur["email"];
1072
				if ($email_auteur) {
1073
					$auteurs[] = "<A HREF=\"mailto:$email_auteur\">$nom_auteur</A>";
1074
				}
1075
				else {
1076
					$auteurs[] = "$nom_auteur";
1077
				}
1078
			}
1079
			if ($auteurs) $'.$nom_var.' = join($auteurs, ", ");
1080
			else $'.$nom_var.' = "";
1081
		}
1082
		';
1083
		break;
1084
 
1085
	//
1086
	// Introduction (d'un article, d'une breve ou d'un message de forum)
1087
	//
1088
 
1089
	case 'INTRODUCTION':
1090
		$code = 'calcul_introduction($pile_boucles[$id_instance]->type_requete,
1091
			$pile_boucles[$id_instance]->row[\'texte\'],
1092
			$pile_boucles[$id_instance]->row[\'chapo\'],
1093
			$pile_boucles[$id_instance]->row[\'descriptif\'])';
1094
		break;
1095
 
1096
	//
1097
	// Divers types de champs
1098
	//
1099
 
1100
	case 'URL_SITE_SPIP':
1101
		$code = "lire_meta('adresse_site')";
1102
		break;
1103
 
1104
	case 'NOM_SITE_SPIP':
1105
		$code = "lire_meta('nom_site')";
1106
		break;
1107
 
1108
	case 'EMAIL_WEBMASTER':
1109
		$code = "lire_meta('email_webmaster')";
1110
		break;
1111
 
1112
	case 'CHARSET':
1113
		$code = "lire_meta('charset')";
1114
		break;
1115
 
1116
	case 'LANG':
1117
		$code = "\$GLOBALS['spip_lang']";
1118
		break;
1119
 
1120
	case 'LANG_LEFT':
1121
		$code = "lang_dir(\$GLOBALS['spip_lang'],'left','right')";
1122
		break;
1123
 
1124
	case 'LANG_RIGHT':
1125
		$code = "lang_dir(\$GLOBALS['spip_lang'],'right','left')";
1126
		break;
1127
 
1128
	case 'LANG_DIR':
1129
		$code = "lang_dir(\$GLOBALS['spip_lang'],'ltr','rtl')";
1130
		break;
1131
 
1132
	case 'PUCE':
1133
		$code = '$GLOBALS["puce"]';
1134
		break;
1135
 
1136
	case 'DATE':
1137
		// Uniquement hors-boucles, pour la date passee dans l'URL ou le contexte inclusion
1138
		$code = "\$contexte['date']";
1139
		break;
1140
 
1141
	case 'DATE_NOUVEAUTES':
1142
		$milieu = "if (lire_meta('quoi_de_neuf') == 'oui' AND lire_meta('majnouv'))
1143
			\$$nom_var = normaliser_date(lire_meta('majnouv'));
1144
		else
1145
			\$$nom_var = \"'0000-00-00'\";
1146
		";
1147
		break;
1148
 
1149
	case 'URL_ARTICLE':
1150
		$code = "url_var_recherche(generer_url_article(\$contexte['id_article']), \$contexte['activer_url_recherche'])";
1151
		break;
1152
 
1153
	case 'URL_RUBRIQUE':
1154
		$code = "url_var_recherche(generer_url_rubrique(\$contexte['id_rubrique']), \$contexte['activer_url_recherche'])";
1155
		break;
1156
 
1157
	case 'URL_BREVE':
1158
		$code = "url_var_recherche(generer_url_breve(\$contexte['id_breve']), \$contexte['activer_url_recherche'])";
1159
		break;
1160
 
1161
	case 'URL_FORUM':
1162
		$code = "url_var_recherche(generer_url_forum(\$contexte['id_forum']), \$contexte['activer_url_recherche'])";
1163
		break;
1164
 
1165
	case 'URL_MOT':
1166
		$code = "url_var_recherche(generer_url_mot(\$contexte['id_mot']), \$contexte['activer_url_recherche'])";
1167
		break;
1168
 
1169
	case 'URL_AUTEUR':
1170
		$code = "url_var_recherche(generer_url_auteur(\$contexte['id_auteur']), \$contexte['activer_url_recherche'])";
1171
		break;
1172
 
1173
	case 'URL_DOCUMENT':
1174
		$code = "generer_url_document(\$contexte['id_document'])";
1175
		break;
1176
 
1177
	case 'NOTES':
1178
		$milieu = '$'.$nom_var.' = $GLOBALS["les_notes"];
1179
			$GLOBALS["les_notes"] = "";
1180
			$GLOBALS["compt_note"] = 0;
1181
			$GLOBALS["marqueur_notes"] ++;
1182
			';
1183
		break;
1184
 
1185
	case 'RECHERCHE':
1186
		$code = 'htmlspecialchars($GLOBALS["recherche"])';
1187
		break;
1188
 
1189
	case 'COMPTEUR_BOUCLE':
1190
		$code = '$pile_boucles[$id_instance]->compteur_boucle';
1191
		break;
1192
 
1193
	case 'TOTAL_BOUCLE':
1194
		$code = '$pile_boucles[$id_instance_cond]->total_boucle';
1195
		break;
1196
 
1197
	case 'POPULARITE':
1198
		$code = 'ceil(min(100, 100 * $pile_boucles[$id_instance]->row[\'popularite\'] / max(1 , 0 + lire_meta(\'popularite_max\'))))';
1199
		break;
1200
 
1201
	case 'POPULARITE_ABSOLUE':
1202
		$code = 'ceil($pile_boucles[$id_instance]->row[\'popularite\'])';
1203
		break;
1204
 
1205
	case 'POPULARITE_SITE':
1206
		$code = 'ceil(lire_meta(\'popularite_total\'))';
1207
		break;
1208
 
1209
	case 'POPULARITE_MAX':
1210
		$code = 'ceil(lire_meta(\'popularite_max\'))';
1211
		break;
1212
 
1213
	case 'EXTRA':
1214
		$code = 'trim($pile_boucles[$id_instance]->row[\'extra\'])';
1215
		if ($fonctions) {
1216
			// Gerer la notation [(#EXTRA|isbn)]
1217
			include_ecrire("inc_extra.php3");
1218
			reset($fonctions);
1219
			list($key, $champ_extra) = each($fonctions);
1220
			$type_extra = $boucles[$id_boucle]->type_requete;
1221
			if (extra_champ_valide($type_extra, $champ_extra)) {
1222
				unset($fonctions[$key]);
1223
				$code = "extra($code, '".addslashes($champ_extra)."')";
1224
			}
1225
			// Appliquer les filtres definis par le webmestre
1226
			$filtres = extra_filtres($type_extra, $champ_extra);
1227
			if ($filtres) {
1228
				reset($filtres);
1229
				while (list(, $f) = each($filtres)) $code = "$f($code)";
1230
			}
1231
		}
1232
		break;
1233
 
1234
	case 'EXPOSER':
1235
		$on = 'on';
1236
		$off='';
1237
		if ($fonctions) {
1238
			// Gerer la notation [(#EXPOSER|on,off)]
1239
			reset($fonctions);
1240
			list(, $onoff) = each($fonctions);
1241
			ereg("([^,]*)(,(.*))?", $onoff, $regs);
1242
			$on = addslashes($regs[1]);
1243
			$off = addslashes($regs[3]);
1244
 
1245
			// autres filtres
1246
			$filtres=Array();
1247
			while (list(, $nom) = each($fonctions)) {
1248
				$filtres[] = $nom;
1249
			}
1250
			$fonctions = $filtres;
1251
		}
1252
		$id_on_off = $GLOBALS['tables_doublons'][$boucles[$id_boucle]->type_requete];
1253
		if ($id_on_off)
1254
			$code = "(\$GLOBALS[contexte_inclus]['$id_on_off'] == \$contexte['$id_on_off']) ? '$on' : '$off'";
1255
		else
1256
			$code = "'$off'";
1257
		break;
1258
 
1259
	//
1260
	// Inserer directement un document dans le squelette
1261
	//
1262
	case 'EMBED_DOCUMENT':
1263
		if ($fonctions) $fonctions = join($fonctions, "|");
1264
		$milieu = "
1265
			include_ecrire('inc_documents.php3');
1266
			\$$nom_var = embed_document(\$contexte['id_document'], '$fonctions', false) ;
1267
		";
1268
		$fonctions = "";
1269
		break;
1270
 
1271
 
1272
	//
1273
	// Formulaire de recherche sur le site
1274
	//
1275
	case 'FORMULAIRE_RECHERCHE':
1276
		if ($fonctions) {
1277
			list(, $lien) = each($fonctions);	// le premier est un url
1278
			while (list(, $filtre) = each($fonctions)) {
1279
				$filtres[] = $filtre;			// les suivants sont des filtres
1280
			}
1281
			$fonctions = $filtres;
1282
		}
1283
		if (!$lien) $lien = 'recherche.php3';
1284
		$milieu = "
1285
		if (lire_meta('activer_moteur') != 'oui') {
1286
			\$$nom_var = '';
1287
		}
1288
		else {
1289
			\$rech = _T('info_rechercher');
1290
			\$$nom_var = \"
1291
				<form action='$lien' method='get' name='form_rech'>
1292
				<input type='text' id='formulaire_recherche' name='recherche' value=\\\"\$rech\\\" size='20' class='formrecherche'\";
1293
			\$$nom_var .= \"></form>\";
1294
		}
1295
		";
1296
		break;
1297
 
1298
	//
1299
	// Formulaire d'inscription comme redacteur
1300
	// (dans inc-formulaires.php3)
1301
	case 'FORMULAIRE_INSCRIPTION':
1302
		$milieu = '
1303
		$request_uri = $GLOBALS["REQUEST_URI"];
1304
		$spip_lang = $GLOBALS["spip_lang"];
1305
		$accepter_inscriptions = lire_meta("accepter_inscriptions");
1306
		if ($accepter_inscriptions == "oui") {
1307
			$'.$nom_var.' = "<"."?php
1308
				include_local(\"inc-formulaires.php3\");
1309
				lang_select(\"$spip_lang\");
1310
				formulaire_inscription(\"redac\");
1311
				lang_dselect(); ?".">";
1312
		}
1313
		else {
1314
			$'.$nom_var.' = "";
1315
		}
1316
		';
1317
 
1318
		break;
1319
 
1320
	//
1321
	// Formulaire de changement de langue
1322
	case 'MENU_LANG':
1323
		$milieu = '
1324
		$'.$nom_var.' = "<"."?php
1325
			include_ecrire(\"inc_lang.php3\");
1326
			echo menu_langues(\"var_lang\", \$menu_lang);
1327
			?".">";
1328
		';
1329
 
1330
		break;
1331
 
1332
 
1333
	//
1334
	// Formulaire de changement de langue / page de login
1335
	case 'MENU_LANG_ECRIRE':
1336
		$milieu = '
1337
		$'.$nom_var.' = "<"."?php
1338
			include_ecrire(\"inc_lang.php3\");
1339
			echo menu_langues(\"var_lang_ecrire\", \$menu_lang);
1340
			?".">";
1341
		';
1342
 
1343
		break;
1344
 
1345
 
1346
	//
1347
	// Formulaire pour ecrire a l'auteur
1348
	//
1349
	case 'FORMULAIRE_ECRIRE_AUTEUR':
1350
 
1351
		$milieu = '
1352
		if (email_valide($row[\'email\'])) {
1353
			$email = trim($row[\'email\']);
1354
			$spip_lang = $GLOBALS["spip_lang"];
1355
			$'.$nom_var.' = "<'.'?php
1356
				include (\'inc-formulaires.php3\');
1357
				lang_select(\"$spip_lang\");
1358
				formulaire_ecrire_auteur(".$row[\'id_auteur\'].",\'$email\');
1359
				lang_dselect();
1360
			?'.'>";
1361
		}
1362
		';
1363
 
1364
		break;
1365
 
1366
	//
1367
	// Formulaire de signature d'une petition
1368
	//
1369
	case 'FORMULAIRE_SIGNATURE':
1370
 
1371
		$milieu = '
1372
		$spip_lang = $GLOBALS["spip_lang"];
1373
		$id_petition = $contexte["id_article"];
1374
 
1375
		$query_petition = "SELECT id_article FROM spip_petitions WHERE id_article=$id_petition";
1376
 		$result_petition = spip_query($query_petition);
1377
 
1378
		if ($row_petition = spip_fetch_array($result_petition)) {
1379
			include_local("inc-formulaires.php3");
1380
			$texte_formulaire = formulaire_signature($id_petition);
1381
			$'.$nom_var.' = "<div class=\'formulaire\'><a name=\'sp$id_petition\'></a>\n";
1382
			$'.$nom_var.' .= "<"."?php
1383
				if (\$GLOBALS[\'val_confirm\']) {
1384
					include_local(\'inc-formulaires.php3\');
1385
					lang_select(\'$spip_lang\');
1386
					reponse_confirmation($id_petition);
1387
					lang_dselect();
1388
				}
1389
				else if (\$GLOBALS[\'nom_email\'] AND \$GLOBALS[\'adresse_email\']) {
1390
					include_local(\'inc-formulaires.php3\');
1391
					lang_select(\'$spip_lang\');
1392
					reponse_signature($id_petition);
1393
					lang_dselect();
1394
				}
1395
				else {?".">".$texte_formulaire."<"."?php
1396
				}
1397
				?".">";
1398
			$'.$nom_var.' .= "</div>\n";
1399
		}
1400
		else {
1401
			$'.$nom_var.' = "";
1402
		}
1403
		';
1404
 
1405
		break;
1406
 
1407
	//
1408
	// Formulaire de referencement d'un site
1409
	//
1410
	case 'FORMULAIRE_SITE':
1411
 
1412
		$milieu = '
1413
		$request_uri = $GLOBALS["REQUEST_URI"];
1414
		$proposer_sites = lire_meta("proposer_sites");
1415
		$spip_lang = $GLOBALS["spip_lang"];
1416
 
1417
		if ($proposer_sites == "2") {
1418
			$'.$nom_var.' = "<"."?php
1419
				include_local(\"inc-formulaires.php3\");
1420
				lang_select(\"$spip_lang\");
1421
				formulaire_site($contexte[id_rubrique]);
1422
				lang_dselect();
1423
				?".">";
1424
		}
1425
		else {
1426
			$'.$nom_var.' = "";
1427
		}
1428
		';
1429
 
1430
		break;
1431
 
1432
	//
1433
	// Champ testant la presence d'une petition
1434
	//
1435
	case 'PETITION':
1436
		$milieu = '
1437
		$query_petition = "SELECT id_article FROM spip_petitions WHERE id_article=$contexte[id_article]";
1438
		$result_petition = spip_query($query_petition);
1439
		if (spip_num_rows($result_petition) > 0) $'.$nom_var.' = " ";
1440
		else $'.$nom_var.' = "";
1441
		';
1442
		break;
1443
 
1444
	//
1445
	// Formulaire de reponse a un forum
1446
	//
1447
	case 'FORMULAIRE_FORUM':
1448
		$milieu = '
1449
		$spip_lang = $GLOBALS["spip_lang"];
1450
		$'.$nom_var.' = "<"."?php include_local(\'inc-forum.php3\'); lang_select(\'$spip_lang\'); ";
1451
		$'.$nom_var.' .= "';
1452
		switch ($boucles[$id_boucle]->type_requete) {
1453
		case "articles":
1454
			$milieu .= 'echo retour_forum(0, 0, $contexte[id_article], 0, 0); ';
1455
			break;
1456
 
1457
		case "breves":
1458
			$milieu .= 'echo retour_forum(0, 0, 0, $contexte[id_breve], 0); ';
1459
			break;
1460
 
1461
		case "forums":
1462
			$milieu .= 'echo retour_forum(0, $contexte[id_forum], 0, 0, 0); ';
1463
			break;
1464
 
1465
		case "rubriques":
1466
			$milieu .= 'echo retour_forum($contexte[id_rubrique], 0, 0, 0, 0); ';
1467
			break;
1468
 
1469
		case "syndication":
1470
			$milieu .= 'echo retour_forum(0, 0, 0, 0, $contexte[id_syndic]); ';
1471
			break;
1472
 
1473
		default:
1474
			$milieu .= 'echo retour_forum(\'$contexte[id_rubrique]\', \'$contexte[id_forum]\', \'$contexte[id_article]\', \'$contexte[id_breve]\', \'$contexte[id_syndic]\'); ';
1475
			break;
1476
		}
1477
		$milieu .= '"; $'.$nom_var.' .= "lang_dselect(); ?".">";
1478
		';
1479
		break;
1480
 
1481
	//
1482
	// Parametres d'appel du formulaire de reponse a un forum
1483
	//
1484
	case 'PARAMETRES_FORUM':
1485
		$milieu = '
1486
		$request_uri = $GLOBALS["REQUEST_URI"];
1487
		$http_get_vars = $GLOBALS["HTTP_GET_VARS"];
1488
		$forums_publics = lire_meta("forums_publics");
1489
		if (($contexte["accepter_forum"] == "" AND $forums_publics != "non") OR ($contexte["accepter_forum"] != "" AND $contexte["accepter_forum"] != "non")) {
1490
			$lien = substr($request_uri, strrpos($request_uri, "/") + 1);
1491
			if (!$lien_retour = $http_get_vars["retour"])
1492
				$lien_retour = $lien;
1493
			$lien_retour = rawurlencode($lien_retour);
1494
 
1495
			switch ($pile_boucles[$id_instance]->type_requete) {
1496
			case "articles":
1497
				$'.$nom_var.' = "id_article=$contexte[id_article]";
1498
				break;
1499
 
1500
			case "breves":
1501
				$'.$nom_var.' = "id_breve=$contexte[id_breve]";
1502
				break;
1503
 
1504
			case "rubriques":
1505
				$'.$nom_var.' = "id_rubrique=$contexte[id_rubrique]";
1506
				break;
1507
 
1508
			case "syndication":
1509
				$'.$nom_var.' = "id_syndic=$contexte[id_syndic]";
1510
				break;
1511
 
1512
			case "forums":
1513
			default:
1514
				$liste_champs = array ("id_article","id_breve","id_rubrique","id_syndic","id_forum");
1515
				unset($element);
1516
				while (list(,$champ) = each ($liste_champs)) {
1517
					if ($contexte[$champ]) $element[] = "$champ=$contexte[$champ]";
1518
				}
1519
				if ($element) $'.$nom_var.' = join("&",$element);
1520
				break;
1521
 
1522
			}
1523
			$'.$nom_var.' .= "&retour=$lien_retour";
1524
		}
1525
		else {
1526
			$'.$nom_var.' = "";
1527
		}
1528
		';
1529
		break;
1530
 
1531
	//
1532
	// Debut et fin de surlignage auto des mots de la recherche
1533
	//
1534
	case 'DEBUT_SURLIGNE':
1535
		if ($flag_ob AND $flag_pcre) {
1536
			$milieu = '
1537
				$'.$nom_var.' = "<"."?php if (\$var_recherche) { \$mode_surligne = debut_surligne(\$var_recherche, \$mode_surligne); } ?".">";
1538
			';
1539
		}
1540
		break;
1541
	case 'FIN_SURLIGNE':
1542
		if ($flag_ob AND $flag_pcre) {
1543
			$milieu = '
1544
				$'.$nom_var.' = "<"."?php if (\$var_recherche) { \$mode_surligne = fin_surligne(\$var_recherche, \$mode_surligne); } ?".">";
1545
			';
1546
		}
1547
		break;
1548
 
1549
	//
1550
	// Formulaires de login
1551
	//
1552
	case 'LOGIN_PRIVE':
1553
		$milieu = '
1554
			$'.$nom_var.' = "<"."?php include_local (\'inc-login.php3\');
1555
				login (\'\', \'prive\'); ?".">";
1556
			';
1557
		break;
1558
 
1559
	case 'LOGIN_PUBLIC':
1560
		$lacible = '\$GLOBALS[\'clean_link\']';
1561
		if ($fonctions) {
1562
			$filtres = array();
1563
			while (list(, $nom) = each($fonctions))
1564
				$lacible = "new Link('".$nom."')";
1565
			$fonctions = $filtres;
1566
		}
1567
		$milieu = '
1568
			$'.$nom_var.' = "<"."?php include_local (\'inc-login.php3\');
1569
				\$cible = ' . $lacible . ';
1570
				login (\$cible, false); ?".">";
1571
			';
1572
		break;
1573
 
1574
	case 'URL_LOGOUT':
1575
		if ($fonctions) {
1576
			$url = "&url=".$fonctions[0];
1577
			$fonctions = array();
1578
		} else {
1579
			$url = '&url=\'.urlencode(\$clean_link->getUrl()).\'';
1580
		}
1581
		$milieu = '
1582
			$'.$nom_var.' = "<"."?php
1583
				if (\$GLOBALS[\'auteur_session\'][\'login\']) {
1584
					echo \'spip_cookie.php3?logout_public=\'.\$GLOBALS[\'auteur_session\'][\'login\'].\'' . $url . '\';
1585
				} ?".">";
1586
			';
1587
		break;
1588
 
1589
 
1590
	//
1591
	// Boutons d'administration
1592
	//
1593
	case 'FORMULAIRE_ADMIN':
1594
		$milieu = '
1595
			$'.$nom_var.' = "<"."?php \$GLOBALS[\"flag_boutons_admin\"] = true;
1596
				if (\$GLOBALS[\"HTTP_COOKIE_VARS\"][\"spip_admin\"]) {
1597
					include_local(\"inc-admin.php3\");
1598
					afficher_boutons_admin();
1599
				} ?".">";
1600
		';
1601
		break;
1602
 
1603
	default:
1604
		$milieu = '<blink>#'.$champs[$id_champ]->nom_champ.'</blink>'; // pour debugger les squelettes
1605
		$milieu = "	\$$nom_var = '$milieu';\n";
1606
		break;
1607
	} // switch
1608
 
1609
	if (!$code) $code = "\$$nom_var";
1610
 
1611
	$code = applique_filtres ($fonctions, $code);
1612
 
1613
	if ($code != "\$$nom_var") $milieu .= "\t\$$nom_var = $code;\n";
1614
 
1615
	return $milieu;
1616
}
1617
 
1618
 
1619
//
1620
// Generer le code PHP correspondant a une boucle
1621
//
1622
 
1623
function calculer_boucle($id_boucle, $prefix_boucle)
1624
{
1625
	global $boucles;
1626
	global $tables_code_contexte, $tables_doublons;
1627
 
1628
	$func = $prefix_boucle.$id_boucle;
1629
	$boucle = $boucles[$id_boucle];
1630
 
1631
	//
1632
	// Ecrire le debut de la fonction
1633
	//
1634
 
1635
	$texte .= "function $func".'($contexte) {
1636
	global $pile_boucles, $ptr_pile_boucles, $id_doublons, $rubriques_publiques;
1637
 
1638
	';
1639
 
1640
	//
1641
	// Recherche : recuperer les hash a partir de la chaine de recherche
1642
	//
1643
	if (strpos($boucle->requete, '$hash_recherche')) {
1644
		$texte .= '
1645
		global $recherche, $hash_recherche, $hash_recherche_strict;
1646
		$contexte[\'activer_url_recherche\'] = true;
1647
		if (!$hash_recherche)
1648
			list($hash_recherche, $hash_recherche_strict) = requete_hash($recherche);
1649
		';
1650
	} else
1651
		$texte .= '
1652
		$contexte[\'activer_url_recherche\'] = false;
1653
		';
1654
 
1655
	if (ereg('\$date_redac[^_]', $boucle->requete)) {
1656
		$texte .= '$contexte[\'date_redac\'] = normaliser_date($contexte[\'date_redac\']);
1657
		';
1658
	}
1659
	if (ereg('\$date[^_]', $boucle->requete)) {
1660
		$texte .= '$contexte[\'date\'] = normaliser_date($contexte[\'date\']);
1661
		';
1662
	}
1663
 
1664
	//
1665
	// Recuperation du contexte et creation de l'instance de boucle
1666
	//
1667
 
1668
	$texte .= '
1669
	if ($contexte) {
1670
		reset($contexte);
1671
		while (list($key, $val) = each($contexte)) $$key = addslashes($val);
1672
	}
1673
 
1674
	$id_instance = $ptr_pile_boucles++;
1675
	$id_instance_cond = $id_instance;
1676
 
1677
	$instance = new InstanceBoucle;
1678
 
1679
	$instance->id_boucle = \''.$boucle->id_boucle.'\';
1680
	$instance->type_requete = \''.$boucle->type_requete.'\';
1681
	$instance->partie = \''.$boucle->partie.'\';
1682
	$instance->total_parties = \''.$boucle->total_parties.'\';
1683
 
1684
	$instance->id_instance = $id_instance;
1685
 
1686
	$pile_boucles[$id_instance] = $instance;
1687
 
1688
	$retour = "";
1689
	';
1690
 
1691
	//
1692
	// Preparation du code de fermeture
1693
	//
1694
 
1695
	$code_fin = "
1696
	\$ptr_pile_boucles--;
1697
	return \$retour;\n}\n";
1698
 
1699
	$type_boucle = $boucle->type_requete;
1700
	$requete = $boucle->requete;
1701
	$doublons = $boucle->doublons;
1702
	$partie = $boucle->partie;
1703
	$total_parties = $boucle->total_parties;
1704
	$lang_select = ($boucle->lang_select != "non") &&
1705
		($type_boucle == 'articles' OR $type_boucle == 'rubriques'
1706
		OR $type_boucle == 'hierarchie' OR $type_boucle == 'breves');
1707
 
1708
	//
1709
	// Boucle recursive : simplement appeler la boucle interieure
1710
	//
1711
	if ($type_boucle == 'boucle') {
1712
		$texte .= calculer_liste(array($boucles[$boucle->requete]), $prefix_boucle, $id_boucle);
1713
		$texte .= $code_fin;
1714
		return $texte;
1715
	}
1716
 
1717
	//
1718
	// Boucle 'hierarchie' : preparation de la requete principale
1719
	//
1720
	else if ($type_boucle == 'hierarchie') {
1721
		$texte .= '
1722
		if ($id_article || $id_syndic) $hierarchie = construire_hierarchie($id_rubrique);
1723
		else $hierarchie = construire_hierarchie($id_parent);
1724
		if ($hierarchie) {
1725
			$hierarchie = explode("-", substr($hierarchie, 0, -1));
1726
			$hierarchie = join(",", $hierarchie);
1727
		}
1728
		else $hierarchie = "0";';
1729
 
1730
		$deb_class = 0;
1731
		$fin_class = 10000;
1732
		if (ereg("([0-9]+),([0-9]*)", $boucle->requete, $match)) {
1733
			$deb_class = $match[1];
1734
			if ($match[2]) $fin_class = $match[2];
1735
		}
1736
		if ($doublons == "oui")
1737
			$requete = "SELECT *, FIELD(id_rubrique, \$hierarchie) AS _field FROM spip_rubriques WHERE id_rubrique IN (\$hierarchie) AND id_rubrique NOT IN (\$id_doublons[rubriques])";
1738
		else
1739
			$requete = "SELECT *, FIELD(id_rubrique, \$hierarchie) AS _field FROM spip_rubriques WHERE id_rubrique IN (\$hierarchie)";
1740
		$requete .= " ORDER BY _field LIMIT $deb_class,$fin_class";
1741
	}
1742
 
1743
 
1744
	//
1745
	// Pour les forums, ajouter le code de gestion du cache
1746
	// et de l'activation / desactivation par article
1747
	//
1748
	if ($type_boucle == 'forums') {
1749
		$texte .= '
1750
		global $fichier_cache, $requetes_cache;
1751
		if (!$id_rubrique AND !$id_article AND !$id_breve AND $id_forum)
1752
			$my_id_forum = $id_forum;
1753
		else
1754
			$my_id_forum = 0;
1755
		if (!$id_article) $id_article = 0;
1756
		if (!$id_rubrique) $id_rubrique = 0;
1757
		if (!$id_breve) $id_breve = 0;
1758
		$valeurs = "$id_article, $id_rubrique, $id_breve, $my_id_forum, \'$fichier_cache\'";
1759
		if (!$requetes_cache[$valeurs]) {
1760
			$query_cache = "INSERT INTO spip_forum_cache (id_article, id_rubrique, id_breve, id_forum, fichier) VALUES ($valeurs)";
1761
			spip_query($query_cache);
1762
			$requetes_cache[$valeurs] = 1;
1763
		}
1764
		';
1765
 
1766
	} // forums
1767
 
1768
 
1769
 
1770
	//
1771
	// Ecrire le code d'envoi de la requete, de recuperation du nombre
1772
	// de resultats et de traitement des boucles par parties (e.g. 1/2)
1773
	//
1774
 
1775
	$texte .= '	$query = "'.$requete.'";
1776
	$result = @spip_query($query);
1777
	if (!$result) {
1778
		$GLOBALS["delais"]=0;
1779
		include_local("inc-debug-squel.php3");
1780
		return erreur_requete_boucle($query, $instance->id_boucle);
1781
	}
1782
	$total_boucle = @spip_num_rows($result);';
1783
 
1784
	if ($partie AND $total_parties) {
1785
		$flag_parties = true;
1786
		$texte .= '
1787
		$debut_boucle = floor(($total_boucle * ($instance->partie - 1) + $instance->total_parties - 1) / $instance->total_parties) + 1;
1788
		$fin_boucle = floor(($total_boucle * ($instance->partie) + $instance->total_parties - 1) / $instance->total_parties);
1789
		$pile_boucles[$id_instance]->total_boucle = $fin_boucle - $debut_boucle + 1;';
1790
	}
1791
	else {
1792
		$flag_parties = false;
1793
		$texte .= '
1794
		$pile_boucles[$id_instance]->total_boucle = $total_boucle;';
1795
	}
1796
 
1797
	$texte_debut .= '
1798
	$pile_boucles[$id_instance]->compteur_boucle = 0;
1799
	$compteur_boucle = 0;';
1800
 
1801
	//
1802
	// Ecrire le code de recuperation des resultats
1803
	//
1804
 
1805
	if ($lang_select)
1806
		$texte_debut .= "\n\t\$old_lang = \$GLOBALS['spip_lang'];\n";
1807
	$texte_debut .= '
1808
	while ($row = @spip_fetch_array($result)) {';
1809
 
1810
	if ($flag_parties) {
1811
		$texte_debut .= '
1812
		$compteur_boucle++;
1813
		if ($compteur_boucle >= $debut_boucle AND $compteur_boucle <= $fin_boucle) {';
1814
	}
1815
	$texte_debut .= '
1816
		$pile_boucles[$id_instance]->compteur_boucle++;
1817
		$pile_boucles[$id_instance]->row = $row;';
1818
	if ($boucle->separateur)
1819
		$texte_debut .= '
1820
		if ($retour) $retour .= \''.$boucle->separateur."';";
1821
	if ($lang_select)
1822
		$texte_debut .= '
1823
		if ($row["lang"]) {
1824
			$GLOBALS["spip_lang"] = $row["lang"];
1825
			$contexte["lang"] = $row["lang"];
1826
		}';
1827
 
1828
	// Traitement different selon le type de boucle
1829
	$texte_debut .= $tables_code_contexte[$type_boucle];
1830
	if ($doublons == "oui")
1831
		$texte_debut .= "\n\t\t\$id_doublons['$type_boucle'] .= ','.\$row['".$tables_doublons[$type_boucle]."'];";
1832
 
1833
	// Inclusion du code correspondant a l'interieur de la boucle
1834
	$texte_liste = calculer_liste($boucle->milieu, $prefix_boucle, $id_boucle);
1835
 
1836
	// On n'ecrit la boucle "while" que si elle contient du code utile,
1837
	// sinon on utlise plutot spip_num_rows() pour recuperer le nombre d'iterations
1838
	if ($texte_liste OR $doublons == 'oui') {
1839
		$texte .= $texte_debut . $texte_liste;
1840
 
1841
		if ($flag_parties) {
1842
			$texte .= "\n\t\t}\n";
1843
		}
1844
 
1845
		// Fermeture de la boucle spip_fetch_array et liberation des resultats
1846
		$texte .= "\n\t}\n\t@spip_free_result(\$result);\n";
1847
		if ($lang_select)
1848
			$texte .= '	$GLOBALS["spip_lang"] = $old_lang;'."\n";
1849
	}
1850
	else {
1851
		$texte .= '	$pile_boucles[$id_instance]->compteur_boucle = $pile_boucles[$id_instance]->total_boucle;'."\n";
1852
	}
1853
	$texte .= $code_fin;
1854
	return $texte;
1855
}
1856
 
1857
 
1858
//
1859
// Generer le code PHP correspondant a un texte brut
1860
//
1861
 
1862
function calculer_texte($texte)
1863
{
1864
	global $dossier_squelettes;
1865
	$dossier = ($dossier_squelettes ? $dossier_squelettes.'/' : '');
1866
	$code = "";
1867
 
1868
	$texte = ereg_replace("([\\\\'])", "\\\\1", $texte);
1869
 
1870
	//
1871
	// Parties textuelles du squelette
1872
	//
1873
 
1874
	// bloc multi
1875
	if (eregi('<multi>', $texte)) {
1876
		$ouvre_multi = 'extraire_multi(';
1877
		$ferme_multi = ')';
1878
	} else {
1879
		$ouvre_multi = $ferme_multi = '';
1880
	}
1881
 
1882
 
1883
	// Reperer les balises de traduction <:toto:>
1884
	while (eregi("<:(([a-z0-9_]+):)?([a-z0-9_]+)(\|[^>]*)?:>", $texte, $match)) {
1885
		$chaine = strtolower($match[3]);
1886
		if (!($module = $match[2]))
1887
			$module = 'local/public/spip';	// ordre des modules a explorer
1888
		$remplace = "_T('$module:$chaine')";
1889
		if ($filtres = $match[4]) {
1890
			$filtres = explode('|',substr($filtres,1));
1891
			$remplace = applique_filtres($filtres, $remplace);
1892
		}
1893
		$texte = str_replace($match[0], "'$ferme_multi.$remplace.$ouvre_multi'", $texte);
1894
	}
1895
 
1896
 
1897
	//
1898
	// Reperer les directives d'inclusion de squelette <INCLURE>
1899
	//
1900
	while (ereg("(<INCLU[DR]E[[:space:]]*\(([-_0-9a-zA-Z./ ]+)\)(([[:space:]]*\{[^}]*\})*)[[:space:]]*>)", $texte, $match)) {
1901
		$s = $match[0];
1902
		$p = strpos($texte, $s);
1903
		$debut = substr($texte, 0, $p);
1904
		$texte = substr($texte, $p + strlen($s));
1905
		if ($debut)
1906
			$code .= "	\$retour .= $ouvre_multi'$debut'$ferme_multi;\n";
1907
 
1908
		//
1909
		// Traiter la directive d'inclusion
1910
		//
1911
		$fichier = $match[2];
1912
		ereg('^\\{(.*)\\}$', trim($match[3]), $params);
1913
		$code .= "	\$retour .= '<"."?php ';\n";
1914
		$code .= "	\$retour .= '\$contexte_inclus = \'\'; ';\n";
1915
 
1916
		if ($params) {
1917
			// Traiter chaque parametre de contexte
1918
			$params = split("\}[[:space:]]*\{", $params[1]);
1919
			reset($params);
1920
			while (list(, $param) = each($params)) {
1921
				if (ereg("^([_0-9a-zA-Z]+)[[:space:]]*(=[[:space:]]*([^}]+))?$", $param, $args)) {
1922
					$var = $args[1];
1923
					$val = $args[3];
1924
 
1925
					// cas de la langue
1926
					if ($var == 'lang') {
1927
						$lang_inclus = "\\'".addslashes($val)."\\'";
1928
						if (! $val)
1929
							$val = $lang_inclus = '$GLOBALS[spip_lang]';
1930
						$code .= "	\$retour .= '\$contexte_inclus[$var] = $val; ';\n";
1931
					}
1932
					else if ($val)
1933
						$code .= "	\$retour .= '\$contexte_inclus[$var] = \'".addslashes($val)."\'; ';\n";
1934
					else
1935
						$code .= "	\$retour .= '\$contexte_inclus[$var] = \''.addslashes(\$contexte[$var]).'\'; ';\n";
1936
				}
1937
			}
1938
		}
1939
 
1940
		if (!$lang_inclus) $lang_inclus = 'lire_meta(\\\'langue_site\\\')';
1941
		$code .= "	\$retour .= 'include_ecrire(\'inc_lang.php3\'); lang_select($lang_inclus);';\n";
1942
 
1943
		// inclure en priorite dans le dossier_squelettes
1944
		if ($dossier_squelettes) {
1945
			$code .= "	\$retour .= '
1946
			if (@file_exists(\'$dossier_squelettes/$fichier\')){
1947
				include(\'$dossier_squelettes/$fichier\');
1948
			} else {
1949
				include(\'$fichier\');
1950
			}';\n";
1951
		} else
1952
			$code .= "	\$retour .= 'include(\'$fichier\');';\n";
1953
 
1954
		$code .= "	\$retour .= 'lang_dselect(); ?".">';\n";
1955
	}
1956
 
1957
	if ($texte)
1958
		$code .= "	\$retour .= $ouvre_multi'$texte'$ferme_multi;\n";
1959
 
1960
	return $code;
1961
}
1962
 
1963
 
1964
//
1965
// Generer le code PHP correspondant a une liste d'objets syntaxiques
1966
//
1967
 
1968
function calculer_liste($tableau, $prefix_boucle, $id_boucle)
1969
{
1970
	global $boucles;
1971
	global $champs;
1972
	global $nb_milieu;
1973
 
1974
	$texte = '';
1975
	if (!$tableau) return $texte;
1976
 
1977
	reset($tableau);
1978
	while (list(, $objet) = each($tableau)) {
1979
		$milieu = '';
1980
		switch($objet->type) {
1981
 
1982
		/////////////////////
1983
		// Texte
1984
		//
1985
		case 'texte':
1986
			$texte .= calculer_texte($objet->texte);
1987
			break;
1988
 
1989
 
1990
		/////////////////////
1991
		// Boucle
1992
		//
1993
		case 'boucle':
1994
			$nb_milieu++;
1995
			$nom_var = "milieu$nb_milieu";
1996
			$nom_func = $prefix_boucle.$objet->id_boucle;
1997
			if ($objet->cond_avant || $objet->cond_apres || $objet->cond_altern) {
1998
				$texte .= "	\$$nom_var = $nom_func(\$contexte);\n";
1999
				$texte .= "	if (\$$nom_var) {\n";
2000
				if ($s = $objet->cond_avant) {
2001
					$texte .= calculer_liste($s, $prefix_boucle, $id_boucle);
2002
				}
2003
				$texte .= "	\$retour .= \$$nom_var;\n";
2004
				if ($s = $objet->cond_apres) {
2005
					$texte2 = calculer_liste($s, $prefix_boucle, $id_boucle);
2006
					if (strpos($texte2, '$id_instance_cond')) {
2007
						$texte .= "	\$id_instance_cond++;\n";
2008
						$texte .= $texte2;
2009
						$texte .= "	\$id_instance_cond--;\n";
2010
					}
2011
					else $texte .= $texte2;
2012
				}
2013
				$texte .= "	}\n";
2014
				if ($s = $objet->cond_altern) {
2015
					$texte .= "	else {\n";
2016
					$texte2 = calculer_liste($s, $prefix_boucle, $id_boucle);
2017
					if (strpos($texte2, '$id_instance_cond')) {
2018
						$texte .= "	\$id_instance_cond++;\n";
2019
						$texte .= $texte2;
2020
						$texte .= "	\$id_instance_cond--;\n";
2021
					}
2022
					else $texte .= $texte2;
2023
					$texte .= "	}\n";
2024
				}
2025
			}
2026
			else {
2027
				$texte .= "	\$retour .= $nom_func(\$contexte);\n";
2028
			}
2029
			$nb_milieu--;
2030
 
2031
			break;
2032
 
2033
 
2034
		/////////////////////
2035
		// Champ
2036
		//
2037
		case 'champ':
2038
			$nb_milieu++;
2039
			if ($objet->cond_avant || $objet->cond_apres) {
2040
				$nom_var = "milieu$nb_milieu";
2041
				$texte .= calculer_champ($objet->id_champ, $id_boucle, $nom_var);
2042
 
2043
				$texte .= "	if (\$$nom_var) {\n";
2044
				if ($s = $objet->cond_avant) {
2045
					$texte .= calculer_liste($s, $prefix_boucle, $id_boucle);
2046
				}
2047
				$texte .= "	\$retour .= \$$nom_var;\n";
2048
				if ($s = $objet->cond_apres) {
2049
					$texte .= calculer_liste($s, $prefix_boucle, $id_boucle);
2050
				}
2051
				$texte .= "	}\n";
2052
			}
2053
			else {
2054
				$nom_var = "milieu$nb_milieu";
2055
				$texte2 = calculer_champ($objet->id_champ, $id_boucle, $nom_var);
2056
				$c = count(explode("\$$nom_var", $texte2));
2057
				if ($c <= 2) {
2058
					$texte2 = str_replace("\$$nom_var = ", "\$retour .= ", $texte2);
2059
					$texte .= $texte2;
2060
				}
2061
				else {
2062
					$texte .= $texte2;
2063
					$texte .= "	\$retour .= \$$nom_var;\n";
2064
				}
2065
			}
2066
			$nb_milieu--;
2067
			break;
2068
 
2069
		} // switch
2070
 
2071
	} // while
2072
 
2073
	return $texte;
2074
}
2075
 
2076
 
2077
//
2078
// Calculer le squelette : i.e. generer le fichier PHP correspondant
2079
//
2080
 
2081
function calculer_squelette($squelette, $fichier) {
2082
	global $racine;
2083
	global $boucles;
2084
 
2085
	$boucles = '';
2086
	$racine = '';
2087
 
2088
	$html = join(file("$squelette.html"), "");
2089
	parser($html);
2090
 
2091
	$squelette_nom = ereg_replace("[^a-zA-Z0-9_]", "_", $squelette);
2092
	$func = 'squelette_'.$squelette_nom.'_executer';
2093
	$prefix = $func.'_boucle';
2094
	$define = strtoupper("_SKEL_$squelette_nom");
2095
 
2096
	// Debut du fichier
2097
	$texte .= "<"."?php\n\n";
2098
	$texte .= "\$func_squelette_executer = '$func';\n\n";
2099
	$texte .= "if (defined(\"$define\")) return;\n";
2100
	$texte .= "define(\"$define\", \"1\");\n\n\n";
2101
 
2102
	// Calculer le code PHP des boucles
2103
	if ($boucles) {
2104
		reset($boucles);
2105
		while (list($id_boucle, ) = each($boucles)) {
2106
			$texte .= calculer_boucle($id_boucle, $prefix);
2107
			$texte .= "\n\n";
2108
		}
2109
	}
2110
 
2111
	// Calculer le code PHP de la racine
2112
	$texte .= "function $func(\$contexte) {\n";
2113
	$texte .= " global \$pile_boucles, \$id_instance_cond;\n \$pile_boucles = Array();\n \$id_instance_cond = -1;\n"; // pour #TOTAL_BOUCLE
2114
	$texte .= calculer_liste($racine, $prefix, '');
2115
	$texte .= "	return \$retour;\n";
2116
	$texte .= "}\n\n";
2117
 
2118
	// Fin du fichier
2119
	$texte .= '?'.'>';
2120
 
2121
	$f = fopen($fichier, "wb");
2122
	fwrite($f, $texte);
2123
	fclose($f);
2124
}
2125
 
2126
 
2127
?>