Subversion Repositories Sites.tela-botanica.org

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 david 1
<?php
2
 
3
/***************************************************************************\
4
 *  SPIP, Systeme de publication pour l'internet                           *
5
 *                                                                         *
6
 *  Copyright (c) 2001-2005                                                *
7
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8
 *                                                                         *
9
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
10
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
11
\***************************************************************************/
12
 
13
 
14
 
15
// fonctions de recherche et de reservation
16
// dans l'arborescence des boucles
17
 
18
// Ce fichier ne sera execute qu'une fois
19
if (defined("_INC_COMPILO_INDEX")) return;
20
define("_INC_COMPILO_INDEX", "1");
21
 
22
// index_pile retourne la position dans la pile du champ SQL $nom_champ
23
// en prenant la boucle la plus proche du sommet de pile (indique par $idb).
24
// Si on ne trouve rien, on considere que ca doit provenir du contexte
25
// (par l'URL ou l'include) qui a ete recopie dans Pile[0]
26
// (un essai d'affinage a debouche sur un bug vicieux)
27
// Si ca reference un champ SQL, on le memorise dans la structure $boucles
28
// afin de construire un requete SQL minimale (plutot qu'un brutal 'SELECT *')
29
 
30
function index_pile($idb, $nom_champ, &$boucles, $explicite='') {
31
  global $exceptions_des_tables, $table_des_tables, $tables_des_serveurs_sql;
32
 
33
	$i = 0;
34
	if (strlen($explicite)) {
35
	// Recherche d'un champ dans un etage superieur
36
	  while (($idb != $explicite) && ($idb !='')) {
37
#		spip_log("Cherchexpl: $nom_champ '$explicite' '$idb' '$i'");
38
			$i++;
39
			$idb = $boucles[$idb]->id_parent;
40
		}
41
	}
42
 
43
#	spip_log("Cherche: $nom_champ a partir de '$idb'");
44
	$c = strtolower($nom_champ);
45
	// attention: entre la boucle nommee 0, "" et le tableau vide,
46
	// il y a incoherences qu'il vaut mieux eviter
47
	while ($boucles[$idb]) {
48
		$r = $boucles[$idb]->type_requete;
49
		$s = $boucles[$idb]->sql_serveur;
50
		if (!$s)
51
		  { $s = 'localhost';
52
    // indirection (pour les rares cas ou le nom de la table!=type)
53
		    $t = $table_des_tables[$r];
54
		  }
55
		// pour les tables non Spip
56
		if (!$t) {$nom_table = $t = $r; }
57
		else $nom_table = 'spip_' . $t;
58
 
59
#		spip_log("Go: idb='$idb' r='$r' c='$c' nom='$nom_champ' s=$s t=$t");
60
		$desc = $tables_des_serveurs_sql[$s][$nom_table];
61
		if (!$desc) {
62
			erreur_squelette(_T('zbug_table_inconnue', array('table' => $r)),
63
				"'$idb'");
64
			# continuer pour chercher l'erreur suivante
65
			return  "'#" . $r . ':' . $nom_champ . "'";
66
		}
67
		$excep = $exceptions_des_tables[$r][$c];
68
		if ($excep) {
69
			// entite SPIP alias d'un champ SQL
70
			if (!is_array($excep)) {
71
				$e = $excep;
72
				$c = $excep;
73
			}
74
			// entite SPIP alias d'un champ dans une autre table SQL
75
			else {
76
				$t = $excep[0];
77
				$e = $excep[1].' AS '.$c;
78
			}
79
		}
80
		else {
81
			// $e est le type SQL de l'entree
82
			// entite SPIP homonyme au champ SQL
83
			if ($desc['field'][$c])
84
				$e = $c;
85
			else
86
				unset($e);
87
		}
88
 
89
#		spip_log("Dans $idb ('$t' '$e' '$c'): $desc");
90
 
91
		// On l'a trouve
92
		if ($e) {
93
		  $t .= ".$e";
94
		  if (!in_array($t, $boucles[$idb]->select))
95
		    $boucles[$idb]->select[] = $t;
96
		  return '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']';
97
		}
98
#		spip_log("On remonte vers $i");
99
		// Sinon on remonte d'un cran
100
		$idb = $boucles[$idb]->id_parent;
101
		$i++;
102
	}
103
 
104
#	spip_log("Pas vu $nom_champ");
105
	// esperons qu'il y sera
106
	return('$Pile[0][\''. strtolower($nom_champ) . '\']');
107
}
108
 
109
// cette fonction sert d'API pour demander le champ '$champ' dans la pile
110
function champ_sql($champ, $p) {
111
	return index_pile($p->id_boucle, $champ, $p->boucles, $p->nom_boucle);
112
}
113
 
114
// cette fonction sert d'API pour demander une balise Spip avec filtres
115
 
116
function calculer_champ($p) {
117
	$p = calculer_balise($p->nom_champ, $p);
118
	return applique_filtres($p);
119
}
120
 
121
// cette fonction sert d'API pour demander une balise Spip sans filtres
122
function calculer_balise($nom, $p) {
123
 
124
	// regarder s'il existe une fonction personnalisee balise_NOM()
125
	$f = 'balise_' . $nom;
126
	if (function_exists($f))
127
		return $f($p);
128
 
129
	// regarder s'il existe une fonction standard balise_NOM_dist()
130
	$f = 'balise_' . $nom . '_dist';
131
	if (function_exists($f))
132
		return $f($p);
133
 
134
	// regarder s'il existe un fichier d'inclusion au nom de la balise
135
	// contenant une fonction balise_NOM_collecte
136
	$file = 'inc-' . strtolower($nom) . _EXTENSION_PHP;
137
	if ($file = find_in_path($file)) {
138
		include_local($file);
139
		# une globale ?? defined ou function_exists(..._dyn) serait mieux ?
140
		$f = $GLOBALS['balise_' . $nom . '_collecte'];
141
		if (is_array($f))
142
			return calculer_balise_dynamique($p, $nom, $f);
143
	}
144
 
145
	// S'agit-il d'un logo ? Une fonction speciale les traite tous
146
	if (ereg('^LOGO_', $nom))
147
		return calculer_balise_logo($p);
148
 
149
	// ca pourrait etre un champ SQL homonyme,
150
	$p->code = index_pile($p->id_boucle, $nom, $p->boucles, $p->nom_boucle);
151
 
152
	if (strpos($nom, 'ID_') === 0) $p->statut = 'num';
153
 
154
	// Compatibilite ascendante avec les couleurs html (#FEFEFE) :
155
	// SI le champ SQL n'est pas trouve
156
	// ET si la balise a une forme de couleur
157
	// ET s'il n'y a ni filtre ni etoile
158
	// ALORS retourner la couleur.
159
	// Ca permet si l'on veut vraiment de recuperer [(#ACCEDE*)]
160
	if (preg_match("/^[A-F]{1,6}$/i", $nom)
161
	AND !$p->etoile
162
	AND !$p->fonctions) {
163
		$p->code = "'#$nom'";
164
		$p->statut = 'php';
165
	}
166
 
167
	return $p;
168
}
169
 
170
//
171
// Traduction des balises dynamiques, notamment les "formulaire_*"
172
// Inclusion du fichier associe a son nom.
173
// Ca donne les arguments a chercher dans la pile,on compile leur localisation
174
// Ensuite on delegue a une fonction generale definie dans inc-calcul-outils
175
// qui recevra a l'execution la valeur des arguments,
176
// ainsi que les pseudo filtres qui ne sont donc pas traites a la compil
177
// mais on traite le vrai parametre si present.
178
 
179
function calculer_balise_dynamique($p, $nom, $l) {
180
	balise_distante_interdite($p);
181
	$param = "";
182
	if ($a = $p->param) {
183
		$c = array_shift($a);
184
		if  (!array_shift($c)) {
185
		  $p->fonctions = $a;
186
		  array_shift( $p->param );
187
		  $param = compose_filtres_args($p, $c, ',');
188
		}
189
	}
190
	$collecte = join(',',collecter_balise_dynamique($l, $p));
191
	$p->code = "executer_balise_dynamique('" . $nom . "',\n\tarray("
192
	  . $collecte
193
	  . ($collecte ? $param : substr($param,1)) # virer la virgule
194
	  . "),\n\tarray("
195
	  . argumenter_balise($p->param, "', '")
196
	  . "), \$GLOBALS['spip_lang'],"
197
	  . $p->ligne
198
	  . ')';
199
	$p->statut = 'php';
200
	$p->fonctions = array();
201
	$p->param = array();
202
 
203
	// Cas particulier de #FORMULAIRE_FORUM : inserer l'invalideur
204
	if ($nom == 'FORMULAIRE_FORUM')
205
		$p->code = code_invalideur_forums($p, $p->code);
206
 
207
	return $p;
208
}
209
 
210
// construire un tableau des valeurs interessant un formulaire
211
 
212
function collecter_balise_dynamique($l, $p) {
213
	$args = array();
214
	foreach($l as $c) { $x = calculer_balise($c, $p); $args[] = $x->code;}
215
	return $args;
216
}
217
 
218
function applique_filtres($p) {
219
 
220
	// pretraitements standards (explication dans inc-compilo-index)
221
	switch ($statut) {
222
		case 'num':
223
			$code = "intval($code)";
224
			break;
225
		case 'php':
226
			break;
227
		case 'html':
228
		default:
229
			$code = "trim($code)";
230
			break;
231
	}
232
 
233
//  processeurs standards (cf inc-balises.php3)
234
	$code = ($p->etoile ? $p->code : champs_traitements($p));
235
	// Appliquer les filtres perso
236
	if ($p->param) $code = compose_filtres($p, $code);
237
	// post-traitement securite
238
	if ($p->statut == 'html') $code = "interdire_scripts($code)";
239
	return $code;
240
}
241
 
242
function compose_filtres($p, $code)
243
{
244
  foreach($p->param as $filtre) {
245
    $fonc = array_shift($filtre);
246
    if ($fonc) {
247
      $arglist = compose_filtres_args($p, $filtre, ($fonc == '?' ? ':' : ','));
248
      if (function_exists($fonc))
249
	$code = "$fonc($code$arglist)";
250
      else if (strpos("x < > <= >= == === != !== <> ? ", " $fonc "))
251
	$code = "($code $fonc " . substr($arglist,1) . ')';
252
      else
253
	$code = "erreur_squelette('"
254
	  . texte_script(_T('zbug_erreur_filtre', array('filtre' => $fonc)))
255
	  ."','" . $p->id_boucle . "')";
256
    }
257
  }
258
  return $code;
259
}
260
 
261
function compose_filtres_args($p, $args, $sep)
262
{
263
	$arglist = "";
264
	foreach ($args as $arg) {
265
		$arglist .= $sep .
266
		  calculer_liste($arg, $p->descr, $p->boucles, $p->id_boucle);
267
	}
268
	return $arglist;
269
}
270
 
271
//
272
// Reserve les champs necessaires a la comparaison avec le contexte donne par
273
// la boucle parente ; attention en recursif il faut les reserver chez soi-meme
274
// ET chez sa maman
275
//
276
function calculer_argument_precedent($idb, $nom_champ, &$boucles) {
277
 
278
	// si recursif, forcer l'extraction du champ SQL mais ignorer le code
279
	if ($boucles[$idb]->externe)
280
		index_pile ($idb, $nom_champ, $boucles);
281
	// retourner $Pile[$SP] et pas $Pile[0] (bug recursion en 1ere boucle)
282
	$prec = $boucles[$idb]->id_parent;
283
	return (!$prec ? ('$Pile[$SP][\''.$nom_champ.'\']') :
284
		index_pile($prec, $nom_champ, $boucles));
285
}
286
 
287
function rindex_pile($p, $champ, $motif)
288
{
289
	$n = 0;
290
	$b = $p->id_boucle;
291
	$p->code = '';
292
	while ($b != '') {
293
	if ($s = $p->boucles[$b]->param) {
294
	  foreach($s as $v) {
295
		if (strpos($v[1][0]->texte,$motif) !== false) {
296
		  $p->code = '$Pile[$SP' . (($n==0) ? "" : "-$n") .
297
			"]['$champ']";
298
		  $b = '';
299
		  break;
300
		}
301
	  }
302
	}
303
	$n++;
304
	$b = $p->boucles[$b]->id_parent;
305
	}
306
	if (!$p->code) {
307
		erreur_squelette(_T('zbug_champ_hors_motif',
308
			array('champ' => '#' . strtoupper($champ),
309
				'motif' => $motif)
310
		), $p->id_boucle);
311
	}
312
	$p->statut = 'php';
313
	return $p;
314
}
315
 
316
?>