diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php index 65eaad3cec97e19c6aa88caaa99e2ca46f9af1ec..4abbbabfda516f54a9648d62b9c1ca46df413561 100644 --- a/ecrire/public/compiler.php +++ b/ecrire/public/compiler.php @@ -255,6 +255,7 @@ function calculer_requete_sql(&$boucle) $order = array(); return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '') + . $boucle->in . $boucle->hash . "\n\n // REQUETE \$result = spip_optim_select(\n\t\tarray(\"" . diff --git a/ecrire/public/criteres.php b/ecrire/public/criteres.php index ba951001de0f6578e363d1bf3395a2b050266166..6df5d2636e770f4d3a9e2c9efd7dfa7df0570692 100644 --- a/ecrire/public/criteres.php +++ b/ecrire/public/criteres.php @@ -440,7 +440,6 @@ function calculer_criteres ($idb, &$boucles) { foreach($boucles[$idb]->criteres as $crit) { $critere = $crit->op; - // critere personnalise ? $f = "critere_".$critere; if (!function_exists($f)) @@ -461,54 +460,44 @@ function calculer_criteres ($idb, &$boucles) { } } -# Criteres de comparaison - -function calculer_critere_DEFAUT($idb, &$boucles, $crit) +function critere_IN_dist ($idb, &$boucles, $crit) { - list($fct, $col, $op, $val, $table, $args_sql) = - calculer_critere_infixe($idb, $boucles, $crit); - - // ajout pour le cas special d'une condition sur le champ statut: - // il faut alors interdire a la fonction de boucle - // de mettre ses propres criteres de statut - // http://www.spip.net/@statut (a documenter) - - if ($col == 'statut') $boucles[$idb]->statut = true; - - // ajout pour le cas spécial des forums - // il faut alors interdire a la fonction de boucle sur forum - // de selectionner uniquement les forums sans pere - - elseif ($boucles[$idb]->type_requete == 'forums' AND - ($col == 'id_parent' OR $col == 'id_forum')) - $boucles[$idb]->plat = true; + static $cpt = 0; + list($col, $op, $val)= calculer_critere_infixe($idb, $boucles, $crit); + + $var = '$in' . $cpt++; + $x= "\n\t$var = array();"; + foreach ($val as $k => $v) { + if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) { + // optimiser le traitement des constantes + if (is_numeric($r[2])) + $x .= "\n\t$var" . "[]= $r[2];"; + else + $x .= "\n\t$var" . "[]= '".addslashes($r[2])."';"; + } else { + // Pour permettre de passer des tableaux de valeurs + // on repere l'utilisation brute de #ENV**{X}, + // c'est-a-dire sa traduction en ($PILE[0][X]). + // et on deballe mais en rajoutant l'anti XSS + $t = preg_match(",^(\n//.*\n)?\\\$Pile.0,", $v) ? + "array_map('addslashes', $v)" : $v; + $x .= "\n\tif (!(is_array($v)))\n\t\t$var" ."[]= addslashes($v);\n\telse $var = array_merge($var, $t);"; + } + } - // inserer le nom de la table SQL devant le nom du champ - if ($table) { - if ($col[0] == "`") - $ct = "$table." . substr($col,1,-1); - else $ct = "$table.$col"; - } else $ct = $col; + $boucles[$idb]->in .= $x; - // inserer la fonction SQL - if ($fct) $ct = "$fct($ct$args_sql)"; + $where = array("'IN'", "\"$col\"", "('(\'' . join(\"','\",$var) . '\')')"); // inserer la negation (cf !...) - if (strtoupper($op) == 'IN') { - - $kval = "'(\'' . " . join(" .\n\"','\" . ", $val) . " . '\')'"; - $where = array("'IN'", "\"$ct\"", $kval); - if ($crit->not) { + if ($crit->not) { $where = array("'NOT'", $where); } else { $boucles[$idb]->default_order[] = "'cpt'"; - $boucles[$idb]->select[]= "FIND_IN_SET($ct, '\" ." . - join(" .','.", $val) . " .\"') AS cpt"; + $boucles[$idb]->select[]= "FIND_IN_SET($col, '\" . + join(',', $var) .\"') AS cpt"; } - } else { - $where = array("'$op'", "'$ct'", $val[0]); - if ($crit->not) $where = array("'NOT'", $where); - } + // inserer la condition (cf {lang?}) et c'est fini $boucles[$idb]->where[]= (!$crit->cond ? $where : @@ -518,13 +507,35 @@ function calculer_critere_DEFAUT($idb, &$boucles, $crit) "''")); } + +# Criteres de comparaison + +function calculer_critere_DEFAUT($idb, &$boucles, $crit) +{ + list($col, $op, $val)= calculer_critere_infixe($idb, $boucles, $crit); + + $where = array("'$op'", "'$col'", $val[0]); + + // inserer la negation (cf !...) + + if ($crit->not) $where = array("'NOT'", $where); + + // inserer la condition (cf {lang?}) + + $boucles[$idb]->where[]= (!$crit->cond ? $where : + array("'?'", + calculer_argument_precedent($idb, $col, $boucles), + $where, + "''")); +} + function calculer_critere_infixe($idb, &$boucles, $crit) { global $table_des_tables, $tables_principales, $table_date; global $exceptions_des_jointures; $boucle = &$boucles[$idb]; $type = $boucle->type_requete; - $col_table = $boucle->id_table; + $table = $boucle->id_table; list($fct, $col, $op, $val, $args_sql) = calculer_critere_infixe_ops($idb, $boucles, $crit); @@ -541,7 +552,7 @@ function calculer_critere_infixe($idb, &$boucles, $crit) { else if ($table_date[$type] AND preg_match(",^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z]+)?$,", $col, $regs)) { - list($col, $col_table) = + list($col, $table) = calculer_critere_infixe_date($idb, $boucles, $regs); } @@ -557,10 +568,35 @@ function calculer_critere_infixe($idb, &$boucles, $crit) { if ($exceptions_des_jointures[$col]) // on ignore la table, quel luxe! list($t, $col) = $exceptions_des_jointures[$col]; - $col_table = calculer_critere_externe_init($boucle, $col, $desc, $crit); + $table = calculer_critere_externe_init($boucle, $col, $desc, $crit); } } - return array($fct, $col, $op, $val, $col_table, $args_sql); + // ajout pour le cas special d'une condition sur le champ statut: + // il faut alors interdire a la fonction de boucle + // de mettre ses propres criteres de statut + // http://www.spip.net/@statut (a documenter) + + if ($col == 'statut') $boucles[$idb]->statut = true; + + // ajout pour le cas spécial des forums + // il faut alors interdire a la fonction de boucle sur forum + // de selectionner uniquement les forums sans pere + + elseif ($boucles[$idb]->type_requete == 'forums' AND + ($col == 'id_parent' OR $col == 'id_forum')) + $boucles[$idb]->plat = true; + + // inserer le nom de la table SQL devant le nom du champ + if ($table) { + if ($col[0] == "`") + $col = "$table." . substr($col,1,-1); + else $col = "$table.$col"; + } + + // inserer la fonction SQL + if ($fct) $col = "$fct($col$args_sql)"; + + return array($col, $op, $val); } // Champ hors table, ca ne peut etre qu'une jointure. diff --git a/ecrire/public/debug.php b/ecrire/public/debug.php index 57fe986a3f520b5462737f4a6219f39e967e2d87..45b759209c8bfb453b539838ec8c8643f7e906ab 100644 --- a/ecrire/public/debug.php +++ b/ecrire/public/debug.php @@ -337,7 +337,7 @@ function debug_dumpfile ($texte, $fonc, $type) { include_spip('inc/filtres'); http_no_cache(); lang_select($auteur_session['lang']); - $self = self(); + $self = str_replace("\\'", ''', self()); $self .= ((strpos($self, '?') !== false) ? '&' : '?') . 'var_mode=debug'; echo _DOCTYPE_ECRIRE, diff --git a/ecrire/public/interfaces.php b/ecrire/public/interfaces.php index 1dff6a96cf687cfed32b70c507bda19291b3687c..91b77923aa319ccb44fe1141ceb80337ab434d3d 100644 --- a/ecrire/public/interfaces.php +++ b/ecrire/public/interfaces.php @@ -64,6 +64,7 @@ class Boucle { var $default_order = array(); var $date = 'date' ; var $hash = "" ; + var $in = "" ; var $lien = false; var $sous_requete = false; var $hierarchie = '';