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 |
// Definition des {criteres} d'une boucle
|
|
|
16 |
//
|
|
|
17 |
|
|
|
18 |
// Ce fichier ne sera execute qu'une fois
|
|
|
19 |
if (defined("_INC_CRITERES")) return;
|
|
|
20 |
define("_INC_CRITERES", "1");
|
|
|
21 |
|
|
|
22 |
|
|
|
23 |
// {racine}
|
|
|
24 |
// http://www.spip.net/@racine
|
|
|
25 |
function critere_racine_dist($idb, &$boucles, $crit) {
|
|
|
26 |
$not = $crit->not;
|
|
|
27 |
$boucle = &$boucles[$idb];
|
|
|
28 |
|
|
|
29 |
if ($not)
|
|
|
30 |
erreur_squelette(_T('zbug_info_erreur_squelette'), $param);
|
|
|
31 |
|
|
|
32 |
$boucle->where[] = $boucle->id_table.".id_parent='0'";
|
|
|
33 |
|
|
|
34 |
}
|
|
|
35 |
|
|
|
36 |
// {exclus}
|
|
|
37 |
// http://www.spip.net/@exclus
|
|
|
38 |
function critere_exclus_dist($idb, &$boucles, $crit) {
|
|
|
39 |
$param = $crit->op;
|
|
|
40 |
$not = $crit->not;
|
|
|
41 |
$boucle = &$boucles[$idb];
|
|
|
42 |
$id = $boucle->primary;
|
|
|
43 |
|
|
|
44 |
if ($not OR !$id)
|
|
|
45 |
erreur_squelette(_T('zbug_info_erreur_squelette'), $param);
|
|
|
46 |
|
|
|
47 |
$arg = calculer_argument_precedent($idb,$id, $boucles);
|
|
|
48 |
$boucle->where[] = $boucle->id_table . '.' . $id."!='\"." . $arg . ".\"'";
|
|
|
49 |
}
|
|
|
50 |
|
|
|
51 |
// {doublons} ou {unique}
|
|
|
52 |
// http://www.spip.net/@doublons
|
|
|
53 |
// attention: boucle->doublons designe une variable qu'on affecte
|
|
|
54 |
function critere_doublons_dist($idb, &$boucles, $crit) {
|
|
|
55 |
$boucle = &$boucles[$idb];
|
|
|
56 |
$boucle->where[] = '" .' .
|
|
|
57 |
"calcul_mysql_in('".$boucle->id_table . '.' . $boucle->primary .
|
|
|
58 |
"', " .
|
|
|
59 |
'"0".$doublons[' .
|
|
|
60 |
$boucle->doublons .
|
|
|
61 |
" = ('" .
|
|
|
62 |
$boucle->type_requete .
|
|
|
63 |
"' . " .
|
|
|
64 |
calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent) .
|
|
|
65 |
')], \'' .
|
|
|
66 |
($crit->not ? '' : 'NOT') .
|
|
|
67 |
"') . \"";
|
|
|
68 |
if ($crit->not) $boucle->doublons = "";
|
|
|
69 |
}
|
|
|
70 |
|
|
|
71 |
// {lang_select}
|
|
|
72 |
// http://www.spip.net/@lang_select
|
|
|
73 |
function critere_lang_select_dist($idb, &$boucles, $crit) {
|
|
|
74 |
if (!($param = $crit->param[1][0]->texte)) $param = 'oui';
|
|
|
75 |
if ($crit->not) $param = ($param=='oui') ? 'non' : 'oui';
|
|
|
76 |
$boucle = &$boucles[$idb];
|
|
|
77 |
$boucle->lang_select = $param;
|
|
|
78 |
}
|
|
|
79 |
|
|
|
80 |
// {debut_xxx}
|
|
|
81 |
// http://www.spip.net/@debut_
|
|
|
82 |
function critere_debut_dist($idb, &$boucles, $crit) {
|
|
|
83 |
$boucle = &$boucles[$idb];
|
|
|
84 |
$boucle->limit = 'intval($GLOBALS["debut' .
|
|
|
85 |
$crit->param[0][0]->texte .
|
|
|
86 |
'"]) . ",' .
|
|
|
87 |
$crit->param[1][0]->texte .
|
|
|
88 |
'"' ;
|
|
|
89 |
}
|
|
|
90 |
|
|
|
91 |
// {recherche}
|
|
|
92 |
// http://www.spip.net/@recherche
|
|
|
93 |
function critere_recherche_dist($idb, &$boucles, $crit) {
|
|
|
94 |
|
|
|
95 |
$boucle = &$boucles[$idb];
|
|
|
96 |
|
|
|
97 |
// Ne pas executer la requete en cas de hash vide
|
|
|
98 |
$boucle->hash = '
|
|
|
99 |
// RECHERCHE
|
|
|
100 |
list($rech_select, $rech_where) = prepare_recherche($GLOBALS["recherche"], "'.$boucle->primary.'", "'.$boucle->id_table.'");
|
|
|
101 |
if ($rech_where) ';
|
|
|
102 |
|
|
|
103 |
$boucle->select[]= $boucle->id_table . '.' . $boucle->primary; # pour postgres, neuneu ici
|
|
|
104 |
$boucle->select[]= '$rech_select as points';
|
|
|
105 |
|
|
|
106 |
// et la recherche trouve
|
|
|
107 |
$boucle->where[] = '$rech_where';
|
|
|
108 |
|
|
|
109 |
}
|
|
|
110 |
|
|
|
111 |
// {traduction}
|
|
|
112 |
// http://www.spip.net/@traduction
|
|
|
113 |
// (id_trad>0 AND id_trad=id_trad(precedent))
|
|
|
114 |
// OR id_article=id_article(precedent)
|
|
|
115 |
function critere_traduction_dist($idb, &$boucles, $crit) {
|
|
|
116 |
$boucle = &$boucles[$idb];
|
|
|
117 |
$boucle->where[] = "((".$boucle->id_table.".id_trad > 0 AND "
|
|
|
118 |
. $boucle->id_table.".id_trad ='\"."
|
|
|
119 |
. calculer_argument_precedent($idb, 'id_trad',
|
|
|
120 |
$boucles)
|
|
|
121 |
. ".\"')
|
|
|
122 |
OR
|
|
|
123 |
(" . $boucle->id_table.".".$boucle->primary." ='\"."
|
|
|
124 |
. calculer_argument_precedent($idb, $boucle->primary,
|
|
|
125 |
$boucles)
|
|
|
126 |
. ".\"'))";
|
|
|
127 |
}
|
|
|
128 |
|
|
|
129 |
// {origine_traduction}
|
|
|
130 |
// http://www.spip.net/@origine_traduction
|
|
|
131 |
function critere_origine_traduction_dist($idb, &$boucles, $crit) {
|
|
|
132 |
$boucle = &$boucles[$idb];
|
|
|
133 |
$boucle->where[] = $boucle->id_table.".id_trad = "
|
|
|
134 |
. $boucle->id_table . '.' . $boucle->primary;
|
|
|
135 |
}
|
|
|
136 |
|
|
|
137 |
|
|
|
138 |
// {meme_parent}
|
|
|
139 |
// http://www.spip.net/@meme_parent
|
|
|
140 |
function critere_meme_parent_dist($idb, &$boucles, $crit) {
|
|
|
141 |
$boucle = &$boucles[$idb];
|
|
|
142 |
if ($boucle->type_requete == 'rubriques') {
|
|
|
143 |
$boucle->where[] = $boucle->id_table.".id_parent='\"."
|
|
|
144 |
. calculer_argument_precedent($idb, 'id_parent',
|
|
|
145 |
$boucles)
|
|
|
146 |
. ".\"'";
|
|
|
147 |
} else if ($boucle->type_requete == 'forums') {
|
|
|
148 |
$boucle->where[] = $boucle->id_table.".id_parent='\"."
|
|
|
149 |
. calculer_argument_precedent($idb, 'id_parent',
|
|
|
150 |
$boucles)
|
|
|
151 |
. ".\"'";
|
|
|
152 |
$boucle->where[] = $boucle->id_table.".id_parent > 0";
|
|
|
153 |
$boucle->plat = true;
|
|
|
154 |
}
|
|
|
155 |
}
|
|
|
156 |
|
|
|
157 |
// {branche ?}
|
|
|
158 |
// http://www.spip.net/@branche
|
|
|
159 |
function critere_branche_dist($idb, &$boucles, $crit) {
|
|
|
160 |
$not = $crit->not;
|
|
|
161 |
$boucle = &$boucles[$idb];
|
|
|
162 |
$c = "calcul_mysql_in('".$boucle->id_table.".id_rubrique',
|
|
|
163 |
calcul_branche(" . calculer_argument_precedent($idb,
|
|
|
164 |
'id_rubrique', $boucles) . "), '')";
|
|
|
165 |
if (!$crit->cond)
|
|
|
166 |
$where = "\". $c .\"" ;
|
|
|
167 |
else
|
|
|
168 |
$where = "\".("
|
|
|
169 |
. calculer_argument_precedent($idb, 'id_rubrique',
|
|
|
170 |
$boucles)."? $c : 1).\"";
|
|
|
171 |
|
|
|
172 |
if ($not)
|
|
|
173 |
$boucle->where[] = "NOT($where)";
|
|
|
174 |
else
|
|
|
175 |
$boucle->where[] = $where;
|
|
|
176 |
}
|
|
|
177 |
|
|
|
178 |
// Tri : {par xxxx}
|
|
|
179 |
// http://www.spip.net/@par
|
|
|
180 |
function critere_par_dist($idb, &$boucles, $crit) {
|
|
|
181 |
critere_parinverse($idb, $boucles, $crit, '') ;
|
|
|
182 |
}
|
|
|
183 |
|
|
|
184 |
function critere_parinverse($idb, &$boucles, $crit, $sens) {
|
|
|
185 |
|
|
|
186 |
$boucle = &$boucles[$idb];
|
|
|
187 |
if ($crit->not) $sens = $sens ? "" : " . ' DESC'";
|
|
|
188 |
|
|
|
189 |
foreach ($crit->param as $tri) {
|
|
|
190 |
|
|
|
191 |
// tris specifies dynamiquement
|
|
|
192 |
if ($tri[0]->type != 'texte') {
|
|
|
193 |
$order =
|
|
|
194 |
calculer_liste($tri, array(), $boucles, $boucles[$idb]->id_parent);
|
|
|
195 |
$order =
|
|
|
196 |
"((\$x = preg_replace(\"/\\W/\",'',$order)) ? ('$boucle->id_table.' . \$x$sens) : '')";
|
|
|
197 |
}
|
|
|
198 |
else {
|
|
|
199 |
$par = array_shift($tri);
|
|
|
200 |
$par = $par->texte;
|
|
|
201 |
// par hasard
|
|
|
202 |
if ($par == 'hasard') {
|
|
|
203 |
// tester si cette version de MySQL accepte la commande RAND()
|
|
|
204 |
// sinon faire un gloubi-boulga maison avec de la mayonnaise.
|
|
|
205 |
if (spip_query("SELECT RAND()"))
|
|
|
206 |
$par = "RAND()";
|
|
|
207 |
else
|
|
|
208 |
$par = "MOD(".$boucle->id_table.'.'.$boucle->primary
|
|
|
209 |
." * UNIX_TIMESTAMP(),32767) & UNIX_TIMESTAMP()";
|
|
|
210 |
$boucle->select[]= $par . " AS alea";
|
|
|
211 |
$order = "'alea'";
|
|
|
212 |
}
|
|
|
213 |
|
|
|
214 |
// par titre_mot
|
|
|
215 |
else if ($par == 'titre_mot') {
|
|
|
216 |
$order= "'mots.titre'";
|
|
|
217 |
}
|
|
|
218 |
|
|
|
219 |
// par type_mot
|
|
|
220 |
else if ($par == 'type_mot'){
|
|
|
221 |
$order= "'mots.type'";
|
|
|
222 |
}
|
|
|
223 |
// par num champ(, suite)
|
|
|
224 |
else if (ereg("^num[[:space:]]*(.*)$",$par, $m)) {
|
|
|
225 |
$texte = '0+' . $boucle->id_table . '.' . trim($m[1]);
|
|
|
226 |
$suite = calculer_liste($tri, array(), $boucles, $boucle->id_parent);
|
|
|
227 |
if ($suite !== "''")
|
|
|
228 |
$texte = "\" . ((\$x = $suite) ? ('$texte' . \$x) : '0')" . " . \"";
|
|
|
229 |
$as = 'num' .($boucle->order ? count($boucle->order) : "");
|
|
|
230 |
$boucle->select[] = $texte . " AS $as";
|
|
|
231 |
$order = "'$as'";
|
|
|
232 |
}
|
|
|
233 |
// par champ. Verifier qu'ils sont presents.
|
|
|
234 |
elseif (ereg("^[a-z][a-z0-9_]*$", $par)) {
|
|
|
235 |
if ($par == 'date')
|
|
|
236 |
$order = "'".$boucle->id_table.".".
|
|
|
237 |
$GLOBALS['table_date'][$boucle->type_requete]
|
|
|
238 |
."'";
|
|
|
239 |
else {
|
|
|
240 |
global $table_des_tables, $tables_des_serveurs_sql;
|
|
|
241 |
$r = $boucle->type_requete;
|
|
|
242 |
$s = $boucles[$idb]->sql_serveur;
|
|
|
243 |
if (!$s) $s = 'localhost';
|
|
|
244 |
$t = $table_des_tables[$r];
|
|
|
245 |
// pour les tables non Spip
|
|
|
246 |
if (!$t) $t = $r; else $t = "spip_$t";
|
|
|
247 |
$desc = $tables_des_serveurs_sql[$s][$t];
|
|
|
248 |
if ($desc['field'][$par])
|
|
|
249 |
$order = "'".$boucle->id_table.".".$par."'";
|
|
|
250 |
else {
|
|
|
251 |
// tri sur les champs synthetises (cf points)
|
|
|
252 |
$order = "'".$par."'";
|
|
|
253 |
}
|
|
|
254 |
}
|
|
|
255 |
} else
|
|
|
256 |
erreur_squelette(_T('zbug_info_erreur_squelette'), "{par $par} BOUCLE$idb");
|
|
|
257 |
}
|
|
|
258 |
|
|
|
259 |
if ($order)
|
|
|
260 |
$boucle->order[] = $order . (($order[0]=="'") ? $sens : "");
|
|
|
261 |
}
|
|
|
262 |
}
|
|
|
263 |
|
|
|
264 |
|
|
|
265 |
// {inverse}
|
|
|
266 |
// http://www.spip.net/@inverse
|
|
|
267 |
// obsolete. utiliser {!par ...}
|
|
|
268 |
function critere_inverse_dist($idb, &$boucles, $crit) {
|
|
|
269 |
|
|
|
270 |
$boucle = &$boucles[$idb];
|
|
|
271 |
// Classement par ordre inverse
|
|
|
272 |
|
|
|
273 |
if ($crit->not || $crit->param)
|
|
|
274 |
critere_parinverse($idb, $boucles, $crit, " . ' DESC'");
|
|
|
275 |
else
|
|
|
276 |
{
|
|
|
277 |
$n = count($boucle->order);
|
|
|
278 |
if ($n)
|
|
|
279 |
$boucle->order[$n-1] .= " . ' DESC'";
|
|
|
280 |
else
|
|
|
281 |
erreur_squelette(_T('zbug_info_erreur_squelette'), "{inverse ?} BOUCLE$idb");
|
|
|
282 |
}
|
|
|
283 |
}
|
|
|
284 |
|
|
|
285 |
function critere_agenda($idb, &$boucles, $crit)
|
|
|
286 |
{
|
|
|
287 |
$params = $crit->param;
|
|
|
288 |
|
|
|
289 |
if (count($params) < 1)
|
|
|
290 |
erreur_squelette(_T('zbug_info_erreur_squelette'),
|
|
|
291 |
"{agenda ?} BOUCLE$idb");
|
|
|
292 |
|
|
|
293 |
$parent = $boucles[$idb]->id_parent;
|
|
|
294 |
|
|
|
295 |
// les valeur $date et $type doivent etre connus à la compilation
|
|
|
296 |
// autrement dit ne pas être des champs
|
|
|
297 |
|
|
|
298 |
$date = array_shift($params);
|
|
|
299 |
$date = $date[0]->texte;
|
|
|
300 |
|
|
|
301 |
$type = array_shift($params);
|
|
|
302 |
$type = $type[0]->texte;
|
|
|
303 |
|
|
|
304 |
$annee = $params ? array_shift($params) : "";
|
|
|
305 |
$annee = "\n" . 'sprintf("%04d", ($x = ' .
|
|
|
306 |
calculer_liste($annee, array(), $boucles, $parent) .
|
|
|
307 |
') ? $x : date("Y"))';
|
|
|
308 |
|
|
|
309 |
$mois = $params ? array_shift($params) : "";
|
|
|
310 |
$mois = "\n" . 'sprintf("%02d", ($x = ' .
|
|
|
311 |
calculer_liste($mois, array(), $boucles, $parent) .
|
|
|
312 |
') ? $x : date("m"))';
|
|
|
313 |
|
|
|
314 |
$jour = $params ? array_shift($params) : "";
|
|
|
315 |
$jour = "\n" . 'sprintf("%02d", ($x = ' .
|
|
|
316 |
calculer_liste($jour, array(), $boucles, $parent) .
|
|
|
317 |
') ? $x : date("d"))';
|
|
|
318 |
|
|
|
319 |
$annee2 = $params ? array_shift($params) : "";
|
|
|
320 |
$annee2 = "\n" . 'sprintf("%04d", ($x = ' .
|
|
|
321 |
calculer_liste($annee2, array(), $boucles, $parent) .
|
|
|
322 |
') ? $x : date("Y"))';
|
|
|
323 |
|
|
|
324 |
$mois2 = $params ? array_shift($params) : "";
|
|
|
325 |
$mois2 = "\n" . 'sprintf("%02d", ($x = ' .
|
|
|
326 |
calculer_liste($mois2, array(), $boucles, $parent) .
|
|
|
327 |
') ? $x : date("m"))';
|
|
|
328 |
|
|
|
329 |
$jour2 = $params ? array_shift($params) : "";
|
|
|
330 |
$jour2 = "\n" . 'sprintf("%02d", ($x = ' .
|
|
|
331 |
calculer_liste($jour2, array(), $boucles, $parent) .
|
|
|
332 |
') ? $x : date("d"))';
|
|
|
333 |
|
|
|
334 |
$boucle = &$boucles[$idb];
|
|
|
335 |
$date = $boucle->id_table . ".$date";
|
|
|
336 |
if ($type == 'jour')
|
|
|
337 |
$boucle->where[] = "DATE_FORMAT($date, '%Y%m%d') = '\" . $annee . $mois . $jour .\"'";
|
|
|
338 |
elseif ($type == 'mois')
|
|
|
339 |
$boucle->where[] = "DATE_FORMAT($date, '%Y%m') = '\" . $annee . $mois .\"'";
|
|
|
340 |
elseif ($type == 'semaine')
|
|
|
341 |
$boucle->where[] =
|
|
|
342 |
"DATE_FORMAT($date, '%Y%m%d') >= '\" .
|
|
|
343 |
date_debut_semaine($annee, $mois, $jour) . \"' AND
|
|
|
344 |
DATE_FORMAT($date, '%Y%m%d') <= '\" .
|
|
|
345 |
date_fin_semaine($annee, $mois, $jour) . \"'";
|
|
|
346 |
elseif (count($crit->param) > 2)
|
|
|
347 |
$boucle->where[] =
|
|
|
348 |
"DATE_FORMAT($date, '%Y%m%d') >= '\" . $annee . $mois . $jour .\"' AND
|
|
|
349 |
DATE_FORMAT($date, '%Y%m%d') <= '\" . $annee2 . $mois2 . $jour2 .\"'";
|
|
|
350 |
// sinon on prend tout
|
|
|
351 |
}
|
|
|
352 |
|
|
|
353 |
|
|
|
354 |
|
|
|
355 |
function calculer_critere_parties($idb, &$boucles, $crit) {
|
|
|
356 |
$boucle = &$boucles[$idb];
|
|
|
357 |
$a1 = $crit->param[0];
|
|
|
358 |
$a2 = $crit->param[1];
|
|
|
359 |
$op = $crit->op;
|
|
|
360 |
list($a11,$a12) = calculer_critere_parties_aux($idb, $boucles, $a1);
|
|
|
361 |
list($a21,$a22) = calculer_critere_parties_aux($idb, $boucles, $a2);
|
|
|
362 |
if (($op== ',')&&(is_numeric($a11) && (is_numeric($a21))))
|
|
|
363 |
$boucle->limit = $a11 .',' . $a21;
|
|
|
364 |
else {
|
|
|
365 |
$boucle->partie = ($a11 != 'n') ? $a11 : $a12;
|
|
|
366 |
$boucle->total_parties = ($a21 != 'n') ? $a21 : $a22;
|
|
|
367 |
$boucle->mode_partie = (($op == '/') ? '/' :
|
|
|
368 |
(($a11=='n') ? '-' : '+').(($a21=='n') ? '-' : '+'));
|
|
|
369 |
}
|
|
|
370 |
}
|
|
|
371 |
|
|
|
372 |
function calculer_critere_parties_aux($idb, &$boucles, $param) {
|
|
|
373 |
if ($param[0]->type != 'texte')
|
|
|
374 |
{
|
|
|
375 |
$a1 = calculer_liste(array($param[0]), array(), $boucles[$idb]->id_parent, $boucles);
|
|
|
376 |
ereg('^ *(-([0-9]+))? *$', $param[1]->texte, $m);
|
|
|
377 |
return array("intval($a1)", ($m[2] ? $m[2] : 0));
|
|
|
378 |
} else {
|
|
|
379 |
ereg('^ *(([0-9]+)|n) *(- *([0-9]+)? *)?$', $param[0]->texte, $m);
|
|
|
380 |
$a1 = $m[1];
|
|
|
381 |
if (!$m[3])
|
|
|
382 |
return array($a1, 0);
|
|
|
383 |
elseif ($m[4])
|
|
|
384 |
return array($a1, $m[4]);
|
|
|
385 |
else return array($a1,
|
|
|
386 |
calculer_liste(array($param[1]), array(), $boucles[$idb]->id_parent, $boucles));
|
|
|
387 |
}
|
|
|
388 |
}
|
|
|
389 |
|
|
|
390 |
//
|
|
|
391 |
// La fonction d'aiguillage sur le nom du critere
|
|
|
392 |
//
|
|
|
393 |
|
|
|
394 |
function calculer_criteres ($idb, &$boucles) {
|
|
|
395 |
|
|
|
396 |
foreach($boucles[$idb]->criteres as $crit) {
|
|
|
397 |
$critere = $crit->op;
|
|
|
398 |
|
|
|
399 |
// critere personnalise ?
|
|
|
400 |
$f = "critere_".$critere;
|
|
|
401 |
if (!function_exists($f))
|
|
|
402 |
$f .= '_dist';
|
|
|
403 |
|
|
|
404 |
// fonction critere standard ?
|
|
|
405 |
if (!function_exists($f)) {
|
|
|
406 |
// double cas particulier repere a l'analyse lexicale
|
|
|
407 |
if (($critere == ",") OR ($critere == '/'))
|
|
|
408 |
$f = 'calculer_critere_parties';
|
|
|
409 |
else $f = 'calculer_critere_DEFAUT';
|
|
|
410 |
}
|
|
|
411 |
// Applique le critere
|
|
|
412 |
$res = $f($idb, $boucles, $crit);
|
|
|
413 |
|
|
|
414 |
// Gestion d'erreur
|
|
|
415 |
if (is_array($res)) erreur_squelette($res);
|
|
|
416 |
}
|
|
|
417 |
}
|
|
|
418 |
|
|
|
419 |
# Criteres de comparaison
|
|
|
420 |
|
|
|
421 |
function calculer_critere_DEFAUT($idb, &$boucles, $crit) {
|
|
|
422 |
|
|
|
423 |
global $table_date, $table_des_tables;
|
|
|
424 |
global $tables_relations;
|
|
|
425 |
|
|
|
426 |
$boucle = &$boucles[$idb];
|
|
|
427 |
$type = $boucle->type_requete;
|
|
|
428 |
$col_table = $id_table = $boucle->id_table;
|
|
|
429 |
$primary = $boucle->primary;
|
|
|
430 |
$id_field = $id_table . '.' . $primary;
|
|
|
431 |
$fct = '';
|
|
|
432 |
|
|
|
433 |
// cas d'une valeur comparee a elle-meme ou son referent
|
|
|
434 |
if (count($crit->param) ==0)
|
|
|
435 |
{ $op = '=';
|
|
|
436 |
$col = $crit->op;
|
|
|
437 |
$val = $crit->op;
|
|
|
438 |
// Cas special {lang} : aller chercher $GLOBALS['spip_lang']
|
|
|
439 |
if ($val == 'lang')
|
|
|
440 |
$val = array('$GLOBALS[\'spip_lang\']');
|
|
|
441 |
else {
|
|
|
442 |
// Si id_parent, comparer l'id_parent avec l'id_objet
|
|
|
443 |
// de la boucle superieure.... faudrait verifier qu'il existe
|
|
|
444 |
// pour eviter l'erreur SQL
|
|
|
445 |
if ($val == 'id_parent')
|
|
|
446 |
$val = $primary;
|
|
|
447 |
// Si id_enfant, comparer l'id_objet avec l'id_parent
|
|
|
448 |
// de la boucle superieure
|
|
|
449 |
else if ($val == 'id_enfant')
|
|
|
450 |
$val = 'id_parent';
|
|
|
451 |
$val = array("addslashes(" .calculer_argument_precedent($idb, $val, $boucles) .")");
|
|
|
452 |
}
|
|
|
453 |
}
|
|
|
454 |
else
|
|
|
455 |
{
|
|
|
456 |
// comparaison explicite
|
|
|
457 |
// le phraseur impose que le premier param soit du texte
|
|
|
458 |
$params = $crit->param;
|
|
|
459 |
$op = $crit->op;
|
|
|
460 |
|
|
|
461 |
$col = array_shift($params);
|
|
|
462 |
$col = $col[0]->texte;
|
|
|
463 |
// fonction SQL ?
|
|
|
464 |
if (ereg("([A-Za-z_]+)\(([a-z_]+)\)", $col,$match3)) {
|
|
|
465 |
$col = $match3[2];
|
|
|
466 |
$fct = $match3[1];
|
|
|
467 |
}
|
|
|
468 |
|
|
|
469 |
$val = array();
|
|
|
470 |
foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
|
|
|
471 |
$val[] = "addslashes(" .
|
|
|
472 |
calculer_liste($p, array(), $boucles, $boucles[$idb]->id_parent) .
|
|
|
473 |
")";
|
|
|
474 |
}
|
|
|
475 |
}
|
|
|
476 |
|
|
|
477 |
// cas special: statut=
|
|
|
478 |
// si on l'invoque dans une boucle il faut interdire
|
|
|
479 |
// a la boucle de mettre ses propres criteres de statut
|
|
|
480 |
// http://www.spip.net/@statut (a documenter)
|
|
|
481 |
if ($col == 'statut')
|
|
|
482 |
$boucle->where['statut'] = '1';
|
|
|
483 |
|
|
|
484 |
// reperer les champs n'appartenant pas a la table de la boucle
|
|
|
485 |
|
|
|
486 |
if ($ext_table = $tables_relations[$type][$col])
|
|
|
487 |
$col_table = $ext_table .
|
|
|
488 |
calculer_critere_externe($boucle, $id_field, $ext_table, $type, $col);
|
|
|
489 |
// Cas particulier pour les raccourcis 'type_mot' et 'titre_mot'
|
|
|
490 |
elseif ($type != 'mots' AND $table_des_tables[$type]
|
|
|
491 |
AND ($col == 'type_mot' OR $col == 'titre_mot'
|
|
|
492 |
OR $col == 'id_groupe')) {
|
|
|
493 |
if ($type == 'forums')
|
|
|
494 |
$lien = "mots_forum";
|
|
|
495 |
else if ($type == 'syndication')
|
|
|
496 |
$lien = "mots_syndic";
|
|
|
497 |
else
|
|
|
498 |
$lien = "mots_$type";
|
|
|
499 |
|
|
|
500 |
// jointure nouvelle a chaque comparaison
|
|
|
501 |
$num_lien = calculer_critere_externe($boucle, $id_field, $lien, $type, $col);
|
|
|
502 |
// jointure pour lier la table principale et la nouvelle
|
|
|
503 |
$boucle->from[] = "spip_mots AS l_mots$num_lien";
|
|
|
504 |
$boucle->where[] = "$lien$num_lien.id_mot=l_mots$num_lien.id_mot";
|
|
|
505 |
$col_table = "l_mots$num_lien";
|
|
|
506 |
|
|
|
507 |
if ($col == 'type_mot')
|
|
|
508 |
$col = 'type';
|
|
|
509 |
else if ($col == 'titre_mot')
|
|
|
510 |
$col = 'titre';
|
|
|
511 |
}
|
|
|
512 |
|
|
|
513 |
// Cas particulier : selection des documents selon l'extension
|
|
|
514 |
if ($type == 'documents' AND $col == 'extension')
|
|
|
515 |
$col_table = 'types_documents';
|
|
|
516 |
// HACK : selection des documents selon mode 'image'
|
|
|
517 |
// (a creer en dur dans la base)
|
|
|
518 |
else if ($type == 'documents' AND $col == 'mode' AND $val[0] == "'image'")
|
|
|
519 |
$val[0] = "'vignette'";
|
|
|
520 |
// Cas particulier : lier les articles syndiques
|
|
|
521 |
// au site correspondant
|
|
|
522 |
else if ($type == 'syndic_articles' AND
|
|
|
523 |
!ereg("^(id_syndic_article|titre|url|date|descriptif|lesauteurs|id_document)$",$col))
|
|
|
524 |
$col_table = 'syndic';
|
|
|
525 |
|
|
|
526 |
// Cas particulier : id_enfant => utiliser la colonne id_objet
|
|
|
527 |
if ($col == 'id_enfant')
|
|
|
528 |
$col = $primary;
|
|
|
529 |
// Cas particulier : id_secteur = id_rubrique pour certaines tables
|
|
|
530 |
|
|
|
531 |
if (($type == 'breves' OR $type == 'forums') AND $col == 'id_secteur')
|
|
|
532 |
$col = 'id_rubrique';
|
|
|
533 |
|
|
|
534 |
// Cas particulier : expressions de date
|
|
|
535 |
if (ereg("^(date|mois|annee|heure|age|age_relatif|jour_relatif|mois_relatif|annee_relatif)(_redac)?$", $col, $regs)) {
|
|
|
536 |
$col = $regs[1];
|
|
|
537 |
if ($regs[2]) {
|
|
|
538 |
$date_orig = $id_table . ".date_redac";
|
|
|
539 |
$date_compare = '\'" . normaliser_date(' .
|
|
|
540 |
calculer_argument_precedent($idb, 'date_redac', $boucles) .
|
|
|
541 |
') . "\'';
|
|
|
542 |
}
|
|
|
543 |
else {
|
|
|
544 |
$date_orig = "$id_table." . $table_date[$type];
|
|
|
545 |
$date_compare = '\'" . normaliser_date(' .
|
|
|
546 |
calculer_argument_precedent($idb, 'date', $boucles) .
|
|
|
547 |
') . "\'';
|
|
|
548 |
}
|
|
|
549 |
|
|
|
550 |
if ($col == 'date') {
|
|
|
551 |
$col = $date_orig;
|
|
|
552 |
$col_table = '';
|
|
|
553 |
}
|
|
|
554 |
else if ($col == 'mois') {
|
|
|
555 |
$col = "MONTH($date_orig)";
|
|
|
556 |
$col_table = '';
|
|
|
557 |
}
|
|
|
558 |
else if ($col == 'annee') {
|
|
|
559 |
$col = "YEAR($date_orig)";
|
|
|
560 |
$col_table = '';
|
|
|
561 |
}
|
|
|
562 |
else if ($col == 'heure') {
|
|
|
563 |
$col = "DATE_FORMAT($date_orig, '%H:%i')";
|
|
|
564 |
$col_table = '';
|
|
|
565 |
}
|
|
|
566 |
else if ($col == 'age') {
|
|
|
567 |
$col = calculer_param_date("now()", $date_orig);
|
|
|
568 |
$col_table = '';
|
|
|
569 |
}
|
|
|
570 |
else if ($col == 'age_relatif') {
|
|
|
571 |
$col = calculer_param_date($date_compare, $date_orig);
|
|
|
572 |
$col_table = '';
|
|
|
573 |
}
|
|
|
574 |
else if ($col == 'jour_relatif') {
|
|
|
575 |
$col = "LEAST(TO_DAYS(" .$date_compare . ")-TO_DAYS(" .
|
|
|
576 |
$date_orig . "), DAYOFMONTH(" . $date_compare .
|
|
|
577 |
")-DAYOFMONTH(" . $date_orig . ")+30.4368*(MONTH(" .
|
|
|
578 |
$date_compare . ")-MONTH(" . $date_orig .
|
|
|
579 |
"))+365.2422*(YEAR(" . $date_compare . ")-YEAR(" .
|
|
|
580 |
$date_orig . ")))";
|
|
|
581 |
$col_table = '';
|
|
|
582 |
}
|
|
|
583 |
else if ($col == 'mois_relatif') {
|
|
|
584 |
$col = "MONTH(" . $date_compare . ")-MONTH(" .
|
|
|
585 |
$date_orig . ")+12*(YEAR(" . $date_compare .
|
|
|
586 |
")-YEAR(" . $date_orig . "))";
|
|
|
587 |
$col_table = '';
|
|
|
588 |
}
|
|
|
589 |
else if ($col == 'annee_relatif') {
|
|
|
590 |
$col = "YEAR(" . $date_compare . ")-YEAR(" .
|
|
|
591 |
$date_orig . ")";
|
|
|
592 |
$col_table = '';
|
|
|
593 |
}
|
|
|
594 |
}
|
|
|
595 |
|
|
|
596 |
if ($type == 'forums' AND
|
|
|
597 |
($col == 'id_parent' OR $col == 'id_forum'))
|
|
|
598 |
$boucle->plat = true;
|
|
|
599 |
|
|
|
600 |
// Rajouter le nom de la table SQL devant le nom du champ
|
|
|
601 |
if ($col_table) {
|
|
|
602 |
if ($col[0] == "`")
|
|
|
603 |
$ct = "$col_table." . substr($col,1,-1);
|
|
|
604 |
else $ct = "$col_table.$col";
|
|
|
605 |
} else $ct = $col;
|
|
|
606 |
|
|
|
607 |
// fonction SQL
|
|
|
608 |
if ($fct) $ct = "$fct($ct)";
|
|
|
609 |
|
|
|
610 |
// if (($op != '=') || !calculer_critere_repete($boucle, $ct, $val[0])) # a revoir
|
|
|
611 |
if (strtoupper($op) == 'IN') {
|
|
|
612 |
|
|
|
613 |
$where = "$ct IN ('\" . " . join(" .\n\"','\" . ", $val) . " . \"')";
|
|
|
614 |
if ($crit->not) {
|
|
|
615 |
$where = "NOT ($where)";
|
|
|
616 |
} else {
|
|
|
617 |
$boucle->default_order = array('rang');
|
|
|
618 |
$boucle->select[]= "FIND_IN_SET($ct, '\" . " .
|
|
|
619 |
join(" .\n\",\" . ", $val) . ' . "\') AS rang';
|
|
|
620 |
}
|
|
|
621 |
} else {
|
|
|
622 |
if ($op == '==') $op = 'REGEXP';
|
|
|
623 |
$where = "($ct $op '\" . " . $val[0] . ' . "\')';
|
|
|
624 |
if ($crit->not) $where = "NOT $where";
|
|
|
625 |
|
|
|
626 |
// operateur optionnel {lang?}
|
|
|
627 |
if ($crit->cond) {
|
|
|
628 |
$champ = calculer_argument_precedent($idb, $col, $boucles) ;
|
|
|
629 |
$where = "\".($champ ? \"$where\" : 1).\"";
|
|
|
630 |
}
|
|
|
631 |
}
|
|
|
632 |
$boucle->where[] = $where;
|
|
|
633 |
}
|
|
|
634 |
|
|
|
635 |
// compatibilite ancienne version
|
|
|
636 |
|
|
|
637 |
function calculer_vieux_in($params)
|
|
|
638 |
{
|
|
|
639 |
$deb = $params[0][0];
|
|
|
640 |
$k = count($params)-1;
|
|
|
641 |
$last = $params[$k];
|
|
|
642 |
$j = count($last)-1;
|
|
|
643 |
$last = $last[$j];
|
|
|
644 |
$n = strlen($last->texte);
|
|
|
645 |
// compatibilité ancienne version
|
|
|
646 |
|
|
|
647 |
if (!(($deb->texte[0] == '(') && ($last->texte[$n-1] == ')')))
|
|
|
648 |
return $params;
|
|
|
649 |
$params[0][0]->texte = substr($deb->texte,1);
|
|
|
650 |
// attention, on peut avoir k=0,j=0 ==> recalculer
|
|
|
651 |
$last = $params[$k][$j];
|
|
|
652 |
$n = strlen($last->texte);
|
|
|
653 |
$params[$k][$j]->texte = substr($last->texte,0,$n-1);
|
|
|
654 |
$newp = array();
|
|
|
655 |
foreach($params as $v) {
|
|
|
656 |
if ($v[0]->type != 'texte')
|
|
|
657 |
$newp[] = $v;
|
|
|
658 |
else {
|
|
|
659 |
foreach(split(',', $v[0]->texte) as $x) {
|
|
|
660 |
$t = new Texte;
|
|
|
661 |
$t->texte = $x;
|
|
|
662 |
$newp[] = array($t);
|
|
|
663 |
}
|
|
|
664 |
}
|
|
|
665 |
}
|
|
|
666 |
return $newp;
|
|
|
667 |
}
|
|
|
668 |
|
|
|
669 |
// fonction provisoirement inutilisee
|
|
|
670 |
// reperer des repetitions comme {id_mot=1}{id_mot=2}
|
|
|
671 |
// pour creer une clause HAVING
|
|
|
672 |
/*
|
|
|
673 |
function calculer_critere_repete(&$boucle, $col, $val)
|
|
|
674 |
{
|
|
|
675 |
foreach ($boucle->where as $k => $v) {
|
|
|
676 |
if (ereg(" *$col *(=|IN) *\(?'(.*)(\".*)[')]$",$v, $m)) {
|
|
|
677 |
$boucle->where[$k] = "$col IN ('$m[2] \"','\" . $val . $m[3])";
|
|
|
678 |
// esperons que c'est le meme !
|
|
|
679 |
$boucle->having++;
|
|
|
680 |
return true;}
|
|
|
681 |
}
|
|
|
682 |
return false;
|
|
|
683 |
}
|
|
|
684 |
*/
|
|
|
685 |
// traitement des relations externes par DES jointures.
|
|
|
686 |
|
|
|
687 |
function calculer_critere_externe(&$boucle, $id_field, $lien, $type, $col) {
|
|
|
688 |
|
|
|
689 |
global $tables_relations_keys;
|
|
|
690 |
static $num;
|
|
|
691 |
|
|
|
692 |
$num++;
|
|
|
693 |
$ref = $tables_relations_keys[$type][$col];
|
|
|
694 |
$boucle->lien = true;
|
|
|
695 |
$boucle->from[] = "spip_$lien AS $lien$num";
|
|
|
696 |
$boucle->where[] = "$id_field=$lien$num." .
|
|
|
697 |
($ref ? $ref : $boucle->primary);
|
|
|
698 |
$boucle->group = $id_field;
|
|
|
699 |
// postgres exige que le champ pour GROUP soit dans le SELECT
|
|
|
700 |
$boucle->select[] = $id_field;
|
|
|
701 |
return $num;
|
|
|
702 |
}
|
|
|
703 |
|
|
|
704 |
function calculer_param_date($date_compare, $date_orig) {
|
|
|
705 |
if (ereg("'\" *\.(.*)\. *\"'", $date_compare, $r)) {
|
|
|
706 |
$init = "'\" . (\$x = $r[1]) . \"'";
|
|
|
707 |
$date_compare = '\'$x\'';
|
|
|
708 |
}
|
|
|
709 |
else
|
|
|
710 |
$init = $date_compare;
|
|
|
711 |
|
|
|
712 |
return
|
|
|
713 |
"LEAST((UNIX_TIMESTAMP(" .
|
|
|
714 |
$init .
|
|
|
715 |
")-UNIX_TIMESTAMP(" .
|
|
|
716 |
$date_orig .
|
|
|
717 |
"))/86400,\n\tTO_DAYS(" .
|
|
|
718 |
$date_compare .
|
|
|
719 |
")-TO_DAYS(" .
|
|
|
720 |
$date_orig .
|
|
|
721 |
"),\n\tDAYOFMONTH(" .
|
|
|
722 |
$date_compare .
|
|
|
723 |
")-DAYOFMONTH(" .
|
|
|
724 |
$date_orig .
|
|
|
725 |
")+30.4368*(MONTH(" .
|
|
|
726 |
$date_compare .
|
|
|
727 |
")-MONTH(" .
|
|
|
728 |
$date_orig .
|
|
|
729 |
"))+365.2422*(YEAR(" .
|
|
|
730 |
$date_compare .
|
|
|
731 |
")-YEAR(" .
|
|
|
732 |
$date_orig .
|
|
|
733 |
")))";
|
|
|
734 |
}
|
|
|
735 |
|
|
|
736 |
?>
|