diff --git a/ecrire/inc_version.php3 b/ecrire/inc_version.php3 index 00c51735653476625c6f46e3bebe32a629521e5f..f70f0f2030431c4ec433dc629ce48a497342d487 100644 --- a/ecrire/inc_version.php3 +++ b/ecrire/inc_version.php3 @@ -412,7 +412,7 @@ define_once('_AUTH_USER_FILE', '.htpasswd'); $spip_version = 1.816; // version de spip -$spip_version_affichee = "1.8.1 CVS"; +$spip_version_affichee = "1.8.2 CVS alpha"; // version de spip / tag cvs if (ereg('Name: v(.*) ','$Name$', $regs)) $spip_version_affichee = $regs[1]; diff --git a/inc-balises.php3 b/inc-balises.php3 index bab720047465c073fb739e647ed6ff11c3389caa..d0854c826b70621686bb9b4343f086dac63b0bfd 100644 --- a/inc-balises.php3 +++ b/inc-balises.php3 @@ -372,7 +372,7 @@ function balise_EXPOSER_dist($p) { $on = addslashes($regs[1]); $off = addslashes($regs[3]); // autres filtres - array_shift($p->args); + array_shift($p->param); } @@ -393,7 +393,7 @@ function balise_EMBED_DOCUMENT_dist($p) { $p->code = "calcule_embed_document(intval($_id_document), " . argumenter_balise($p->fonctions, "|") . ", \$doublons, '" . $p->descr['documents'] . "')"; - $p->args = array(); + $p->param = array(); $p->statut = 'html'; return $p; } @@ -544,7 +544,7 @@ function calculer_balise_logo ($p) { foreach($p->fonctions as $couple) { // eliminer les faux filtres if (!$flag_stop) { - array_shift($p->args); + array_shift($p->param); $nom = $couple[0]; if (ereg('^(left|right|center|top|bottom)$', $nom)) $align = $nom; @@ -635,7 +635,7 @@ function balise_EXTRA_dist ($p) { // Gerer la notation [(#EXTRA|isbn)] if ($p->fonctions) { - $p->args = array(); + $p->param = array(); include_ecrire("inc_extra.php3"); list ($key, $champ_extra) = each($p->fonctions); // le premier filtre $type_extra = $p->type_requete; @@ -699,11 +699,11 @@ function balise_PARAMETRES_FORUM_dist($p) { // Syntaxe [(#PARAMETRES_FORUM{#SELF})] pour fixer le retour du forum # note : ce bloc qui sert a recuperer des arguments calcules pourrait # porter un nom et faire partie de l'API. - if ($filtres = $p->args) { + if ($filtres = $p->param) { $retour = array_shift($filtres); if (!array_shift($retour)) { $p->fonctions = $a; - array_shift( $p->args ); + array_shift( $p->param ); $retour = calculer_liste($retour[0], $p->descr, $p->boucles, @@ -761,11 +761,11 @@ function balise_SELF_dist($p) { // function balise_ENV_dist($p) { - if ($a = $p->args) { + if ($a = $p->param) { $sinon = array_shift($a); if (!array_shift($sinon)) { $p->fonctions = $a; - array_shift( $p->args ); + array_shift( $p->param ); $nom = array_shift($sinon); $nom = ($nom[0]->type=='texte') ? $nom[0]->texte : ""; } diff --git a/inc-compilo-api.php3 b/inc-compilo-api.php3 index 6c958acdf3fe62f5b7c83d448274beb0fde48e91..9025e09a711960d8fd2c541a691840a012d0c24d 100644 --- a/inc-compilo-api.php3 +++ b/inc-compilo-api.php3 @@ -21,12 +21,13 @@ define("_INC_COMPILO_API", "1"); class Texte { var $type = 'texte'; var $texte; + var $avant, $apres = ""; // s'il y avait des guillemets autour } class Inclure { var $type = 'include'; var $texte; - var $args = array(); // valeurs des params + var $param = array(); // valeurs des params var $avant, $apres; // inutilises mais generiques } @@ -73,10 +74,9 @@ class Boucle { // sous-noeud du precedent class Critere { - var $operateur; - var $arg1; - var $arg2; + var $op; var $not; + var $param; } class Champ { @@ -85,7 +85,7 @@ class Champ { var $nom_boucle= ''; // seulement si boucle explicite var $avant, $apres; // tableaux d'objets var $etoile; - var $filtres = array(); // filtre explicites + var $param = array(); // filtre explicites var $fonctions = array(); // source des filtres (compatibilite) // champs pour la production de code var $id_boucle; @@ -106,8 +106,8 @@ class Idiome { var $type = 'idiome'; var $nom_champ = ""; // la chaine a traduire var $module = ""; // son module de definition - var $filtres = array(); // les filtres a appliquer au resultat - var $fonctions = array(); // source des filtres + var $param = array(); // les filtres a appliquer au resultat + var $fonctions = array(); // source des filtres (compatibilite) var $avant, $apres; // inutilises mais faut = ci-dessus // champs pour la production de code, cf ci-dessus var $id_boucle; diff --git a/inc-compilo-index.php3 b/inc-compilo-index.php3 index 0b82016f4653fd905587b795ccbb59a070dfddbf..811adc3d06c296991cee8d92fdc17ecc9a82cd4c 100644 --- a/inc-compilo-index.php3 +++ b/inc-compilo-index.php3 @@ -192,11 +192,11 @@ function calculer_balise($nom, $p) { function calculer_balise_dynamique($p, $nom, $l) { balise_distante_interdite($p); $param = ""; - if ($a = $p->args) { + if ($a = $p->param) { $c = array_shift($a); if (!array_shift($c)) { $p->fonctions = $a; - array_shift( $p->args ); + array_shift( $p->param ); $param = compose_filtres_args($p, $c, ','); } } @@ -205,11 +205,11 @@ function calculer_balise_dynamique($p, $nom, $l) { . $collecte . ($collecte ? $param : substr($param,1)) # virer la virgule . "),\n\tarray(" - . argumenter_balise($p->args, "', '") + . argumenter_balise($p->param, "', '") . "), \$GLOBALS['spip_lang'])"; $p->statut = 'php'; $p->fonctions = array(); - $p->args = array(); + $p->param = array(); // Cas particulier de #FORMULAIRE_FORUM : inserer l'invalideur if ($nom == 'FORMULAIRE_FORUM') @@ -218,15 +218,6 @@ function calculer_balise_dynamique($p, $nom, $l) { return $p; } -function param_balise(&$p) { - if (!($a=$p->fonctions)) return ""; - $c = array_shift($a); - if ($c[0]) return ""; - $p->fonctions = $a; - array_shift( $p->args ); - return $c[1]; -} - // construire un tableau des valeurs interessant un formulaire function collecter_balise_dynamique($l, $p) { @@ -253,7 +244,7 @@ function applique_filtres($p) { // processeurs standards (cf inc-balises.php3) $code = ($p->etoile ? $p->code : champs_traitements($p)); // Appliquer les filtres perso - if ($p->args) $code = compose_filtres($p, $code); + if ($p->param) $code = compose_filtres($p, $code); // post-traitement securite if ($p->statut == 'html') $code = "interdire_scripts($code)"; return $code; @@ -261,7 +252,7 @@ function applique_filtres($p) { function compose_filtres($p, $code) { - foreach($p->args as $filtre) { + foreach($p->param as $filtre) { $fonc = array_shift($filtre); if ($fonc) { $arglist = compose_filtres_args($p, $filtre, ($fonc == '?' ? ':' : ',')); diff --git a/inc-compilo.php3 b/inc-compilo.php3 index bbbb3e7a0964489e62b211f4ad7fd2c4180c9edc..f1496d2d700d4c60135a6f5c15e7ec1aa2840b0c 100644 --- a/inc-compilo.php3 +++ b/inc-compilo.php3 @@ -58,7 +58,7 @@ function calculer_inclure($struct, $descr, &$boucles, $id_boucle, $niv) { } $l = array(); - foreach($struct->args as $val) { + foreach($struct->param as $val) { $var = array_shift($val); $l[] = "\'$var\' => \'' . addslashes(" . ($val ? calculer_liste($val[0], $descr, $boucles, $id_boucle, $niv) : @@ -513,27 +513,21 @@ function calculer_squelette($squelette, $nom, $gram, $sourcefile) { if ($boucles) { // une boucle documents est conditionnee par tout le reste! - // une boucle avec critere de recheche conditionne tout le reste! - // (a cause du cas #nom_de_boucle:URL_*) - // - foreach($boucles as $idb => $boucle) - { - if ($boucle->param && is_array($boucle->param)) { + foreach($boucles as $idb => $boucle) { + if ($boucle->param) { if (($boucle->type_requete == 'documents') && - in_array('doublons',$boucle->param)) + $boucle->doublons) { $descr['documents'] = true; break; } - if (in_array('recherche',$boucle->param)) - $boucles[$idb]->hash = true; } } // Commencer par reperer les boucles appelees explicitement // car elles indexent les arguments de maniere derogatoire foreach($boucles as $id => $boucle) { if ($boucle->type_requete == 'boucle') { - $rec = &$boucles[$boucle->param]; + $rec = &$boucles[$boucle->param[0]]; if (!$rec) { return array(_T('zbug_info_erreur_squelette'), - ($boucle->param + ($boucle->param[0] . ' '. _T('zbug_boucle_recursive_undef'))); } else { $rec->externe = $id; @@ -602,8 +596,9 @@ function calculer_squelette($squelette, $nom, $gram, $sourcefile) { // Reproduire la boucle en commentaire $pretty = "BOUCLE$id(".strtoupper($boucle->type_requete).")"; - if ($boucle->param && is_array($boucle->param)) - $pretty .= " {".join("} {", $boucle->param)."}"; + // anachronique. A refaire. + /* if ($boucle->param && is_array($boucle->param)) + $pretty .= " {".join("} {", $boucle->param)."}";*/ // sans oublier les parametres traites en amont if ($boucle->separateur) foreach($boucle->separateur as $v) diff --git a/inc-criteres.php3 b/inc-criteres.php3 index 85a4b53a698508e5bf72df6e05b8fc91b31732ea..c953443fbe0ecb21dc2deb3da110ef8cd7b7dd06 100644 --- a/inc-criteres.php3 +++ b/inc-criteres.php3 @@ -22,10 +22,11 @@ define("_INC_CRITERES", "1"); // {racine} // http://www.spip.net/@racine -function critere_racine_dist($idb, &$boucles, $param, $not) { +function critere_racine_dist($idb, &$boucles, $crit) { + $not = $crit->not; $boucle = &$boucles[$idb]; - if ($param != 'racine' OR $not) + if ($not) erreur_squelette(_T('zbug_info_erreur_squelette'), $param); $boucle->where[] = $boucle->id_table.".id_parent='0'"; @@ -34,28 +35,24 @@ function critere_racine_dist($idb, &$boucles, $param, $not) { // {exclus} // http://www.spip.net/@exclus -function critere_exclus_dist($idb, &$boucles, $param, $not) { +function critere_exclus_dist($idb, &$boucles, $crit) { + $param = $crit->op; + $not = $crit->not; $boucle = &$boucles[$idb]; $id = $boucle->primary; - if ($param != 'exclus' OR $not OR !$id) + if ($not OR !$id) erreur_squelette(_T('zbug_info_erreur_squelette'), $param); $arg = calculer_argument_precedent($idb,$id, $boucles); $boucle->where[] = $boucle->id_table . '.' . $id."!='\"." . $arg . ".\"'"; - } // {doublons} ou {unique} // http://www.spip.net/@doublons -function critere_doublons_dist($idb, &$boucles, $param, $not) { +function critere_doublons_dist($idb, &$boucles, $crit) { $boucle = &$boucles[$idb]; - - if (!preg_match("/(doublons|unique)[[:space:]]*([a-z_0-9]*)/i", - $param, $match)) - erreur_squelette(_T('zbug_info_erreur_squelette'), $param); - - $boucle->doublons = $boucle->type_requete . $match[2]; + $boucle->doublons = $boucle->type_requete . $crit->param[0][0]->texte; $boucle->where[] = '" .' . "calcul_mysql_in('".$boucle->id_table . '.' . $boucle->primary."', " .'"0".$doublons[\''.$boucle->doublons."'], 'NOT') . \""; @@ -63,33 +60,28 @@ function critere_doublons_dist($idb, &$boucles, $param, $not) { // {lang_select} // http://www.spip.net/@lang_select -function critere_lang_select_dist($idb, &$boucles, $param, $not) { +function critere_lang_select_dist($idb, &$boucles, $crit) { + if (!($param = $crit->param[1][0]->texte)) $param = 'oui'; + if ($crit->not) $param = ($param=='oui')?'non':'oui'; $boucle = &$boucles[$idb]; - if (preg_match('/lang_select(=(oui|non))?$/i', $param, $match)) { - if (!$lang_select = $match[2]) - $lang_select = 'oui'; - if ($not) - $lang_select = ($lang_select=='oui')?'non':'oui'; - $boucle->lang_select = $lang_select; - } - else erreur_squelette(_T('zbug_info_erreur_squelette'), $param); + $boucle->lang_select = $param; } // {debut_xxx} // http://www.spip.net/@debut_ -function critere_debut_dist($idb, &$boucles, $param, $not) { +function critere_debut_dist($idb, &$boucles, $crit) { $boucle = &$boucles[$idb]; - if (ereg('^debut([-_a-zA-Z0-9]+),([0-9]*)$', $param, $match)) { - $debut_lim = "debut".$match[1]; - $boucle->limit = - 'intval($GLOBALS["'.$debut_lim.'"]).",'.$match[2] .'"' ; - } - else erreur_squelette(_T('zbug_info_erreur_squelette'), $param); + $boucle->limit = 'intval($GLOBALS["debut' . + $crit->param[0][0]->texte . + '"]) . ",' . + $crit->param[1][0]->texte . + '"' ; } // {recherche} // http://www.spip.net/@recherche -function critere_recherche_dist($idb, &$boucles, $param, $not) { +function critere_recherche_dist($idb, &$boucles, $crit) { + $boucle = &$boucles[$idb]; $table = $boucle->id_table; #articles @@ -108,10 +100,13 @@ function critere_recherche_dist($idb, &$boucles, $param, $not) { // {inverse} // http://www.spip.net/@inverse -function critere_inverse_dist($idb, &$boucles, $param, $not) { +function critere_inverse_dist($idb, &$boucles, $crit) { + $param = $crit->op; + $not = $crit->not; $boucle = &$boucles[$idb]; // Classement par ordre inverse - if ($param == 'inverse' AND !$not) { + + if (!$not) { if ($boucle->order) $boucle->order .= ".' DESC'"; else @@ -125,10 +120,9 @@ function critere_inverse_dist($idb, &$boucles, $param, $not) { // http://www.spip.net/@traduction // (id_trad>0 AND id_trad=id_trad(precedent)) // OR id_article=id_article(precedent) -function critere_traduction_dist($idb, &$boucles, $param, $not) { +function critere_traduction_dist($idb, &$boucles, $crit) { $boucle = &$boucles[$idb]; - if ($param == 'traduction') { - $boucle->where[] = "((".$boucle->id_table.".id_trad > 0 AND " + $boucle->where[] = "((".$boucle->id_table.".id_trad > 0 AND " . $boucle->id_table.".id_trad ='\"." . calculer_argument_precedent($idb, 'id_trad', $boucles) @@ -138,30 +132,22 @@ function critere_traduction_dist($idb, &$boucles, $param, $not) { . calculer_argument_precedent($idb, $boucle->primary, $boucles) . ".\"'))"; - } else - erreur_squelette(_T('zbug_info_erreur_squelette'), $param); } // {origine_traduction} // http://www.spip.net/@origine_traduction -function critere_origine_traduction_dist($idb, &$boucles, $param, $not) { +function critere_origine_traduction_dist($idb, &$boucles, $crit) { $boucle = &$boucles[$idb]; - if ($param == 'origine_traduction') - $boucle->where[] = $boucle->id_table.".id_trad = " - . $boucle->id_table . '.' . $boucle->primary; - else - erreur_squelette(_T('zbug_info_erreur_squelette'), $param); + $boucle->where[] = $boucle->id_table.".id_trad = " + . $boucle->id_table . '.' . $boucle->primary; } // {meme_parent} // http://www.spip.net/@meme_parent -function critere_meme_parent_dist($idb, &$boucles, $param, $not) { +function critere_meme_parent_dist($idb, &$boucles, $crit) { $boucle = &$boucles[$idb]; - if ($param != 'meme_parent') - erreur_squelette(_T('zbug_info_erreur_squelette'), $param); - else { - if ($boucle->type_requete == 'rubriques') { + if ($boucle->type_requete == 'rubriques') { $boucle->where[] = $boucle->id_table.".id_parent='\"." . calculer_argument_precedent($idb, 'id_parent', $boucles) @@ -173,49 +159,48 @@ function critere_meme_parent_dist($idb, &$boucles, $param, $not) { . ".\"'"; $boucle->where[] = $boucle->id_table.".id_parent > 0"; $boucle->plat = true; - } else - erreur_squelette(_T('zbug_erreur_meme_parent'), "BOUCLE" . $idb); } } // {branche ?} // http://www.spip.net/@branche -function critere_branche_dist($idb, &$boucles, $param, $not) { +function critere_branche_dist($idb, &$boucles, $crit) { + $not = $crit->not; $boucle = &$boucles[$idb]; - if (preg_match('/branche[[:space:]]*([?])?$/i', $param, $regs)) { - $c = "calcul_mysql_in('".$boucle->id_table.".id_rubrique', + $c = "calcul_mysql_in('".$boucle->id_table.".id_rubrique', calcul_branche(" . calculer_argument_precedent($idb, 'id_rubrique', $boucles) . "), '')"; - if (!$regs[1]) + if (!$crit->cond) $where = "\". $c .\"" ; - else + else $where = "\".(" . calculer_argument_precedent($idb, 'id_rubrique', $boucles)."? $c : 1).\""; - if ($not) + if ($not) $boucle->where[] = "NOT($where)"; - else + else $boucle->where[] = $where; - } else - erreur_squelette(_T('zbug_info_erreur_squelette'), $param); } // Tri : {par xxxx} // http://www.spip.net/@par -function critere_par_dist($idb, &$boucles, $param, $not) { +function critere_par_dist($idb, &$boucles, $crit) { + + $not = $crit->not; $boucle = &$boucles[$idb]; if ($not) erreur_squelette(_T('zbug_info_erreur_squelette'), $param); - $param = ltrim(substr($param,3)); + $params = $crit->param; - while ($param) { - - preg_match('/(([^{,]*[{][^}]*[}])|([^,]*))[[:space:]]*,?[[:space:]]*(.*)/ims', - $param, $regs); - $param = $regs[4]; - $tri = $regs[1]; + foreach ($params as $tri) { + // tris specifies dynamiquement + if ($tri[0]->type != 'texte') + $order = calculer_liste($tri, array(), $boucles, $idb); + else { + // on considere que {par col#ENV{num}} est imposible + $tri = $tri[0]->texte; // par hasard if ($tri == 'hasard') { // tester si cette version de MySQL accepte la commande RAND() @@ -244,12 +229,13 @@ function critere_par_dist($idb, &$boucles, $param, $not) { $order = "'num'"; } // par champ. Verifier qu'ils sont presents. - else if (ereg("^[a-z][a-z0-9]*$", $tri)) { - if ($tri == 'date') - $order = "'".$boucle->id_table.".". - $GLOBALS['table_date'][$boucle->type_requete] - ."'"; - else { + else + if (ereg("^[a-z][a-z0-9_]*$", $tri)) { + if ($tri == 'date') + $order = "'".$boucle->id_table.".". + $GLOBALS['table_date'][$boucle->type_requete] + ."'"; + else { global $table_des_tables, $tables_des_serveurs_sql; $r = $boucle->type_requete; $s = $boucles[$idb]->sql_serveur; @@ -266,39 +252,24 @@ function critere_par_dist($idb, &$boucles, $param, $not) { } } } - // tris specifies par l'URL ? - else { - $order = simplifie_param_dynamique($tri, $boucles, $idb); - if ($order == $tri) $order = "'" . $order . "'"; - } + } // au final, gestion des tris multiples if ($order) { if ($boucle->order) $boucle->order .= '.",".'; $boucle->order .= $order; } - } -} - -// Le critere {statut=...} -// particularite : si on l'invoque dans une boucle il faut interdire -// a la boucle de mettre ses propres criteres de statut -// http://www.spip.net/@statut (a documenter) -function critere_statut_dist($idb, &$boucles, $param, $not) { - // interdire a function boucle_BOUCLE() de regler le statut - $boucle = &$boucles[$idb]; - $boucle->where['statut'] = '1'; - - return calculer_critere_DEFAUT($idb, $boucles, $param, $not); + } } -function calculer_critere_parties($idb, &$boucles, $param, $not, $match) { +function calculer_critere_parties($idb, &$boucles, $crit) { $boucle = &$boucles[$idb]; - list(,$a1,$op,$a2) = $match; + $a1 = $crit->param[0]; + $a2 = $crit->param[1]; + $op = $crit->op; list($a11,$a12) = calculer_critere_parties_aux($idb, $boucles, $a1); list($a21,$a22) = calculer_critere_parties_aux($idb, $boucles, $a2); - if (($op== ',')&&(is_numeric($a11) && (is_numeric($a21)))) - $boucle->limit = $a11 .',' . $a21; + $boucle->limit = $a11 .',' . $a21; else { $boucle->partie = ($a11 != 'n') ? $a11 : $a12; $boucle->total_parties = ($a21 != 'n') ? $a21 : $a22; @@ -308,27 +279,25 @@ function calculer_critere_parties($idb, &$boucles, $param, $not, $match) { } function calculer_critere_parties_aux($idb, &$boucles, $param) { - ereg('^(([0-9]+)|n|(#.*))(-([0-9]+))?$', $param, $m); - if ($m[1] == 'n') - $a = 'n'; - else { - $a = simplifie_param_dynamique($m[1], $boucles, $idb); + if ($param[0]->type == 'texte') + { + ereg('^(([0-9]+)|n)(-([0-9]+))?$', $param[0]->texte, $m); + return array($m[1], ($m[4] ? $m[4] : 0)); + } else { + $a1 = calculer_liste(array($param[0]), array(), $idb, $boucles); + ereg('^ *(-([0-9]+))?$', $param[1]->texte, $m); + return array("intval($a1)", ($m[2] ? $m[2] : 0)); } - return array($a, ($m[5] ? $m[5] : 0)); } // -// La fonction d'aiguillage sur le nom du criteres +// La fonction d'aiguillage sur le nom du critere // function calculer_criteres ($idb, &$boucles) { - foreach($boucles[$idb]->param as $param) { - // Analyse du critere - preg_match("/^([!]?)[[:space:]]*(debut|([a-z_]+))/ism", - $param, $match); - $critere = $match[2]; - $not = ($match[1] == '!'); + foreach($boucles[$idb]->criteres as $crit) { + $critere = $crit->op; // critere personnalise ? $f = "critere_".$critere; @@ -336,235 +305,239 @@ function calculer_criteres ($idb, &$boucles) { $f .= '_dist'; // fonction critere standard ? - if (!function_exists($f)) - $f = 'calculer_critere_DEFAUT'; - + if (!function_exists($f)) { + // double cas particulier repere a l'analyse lexicale + if (($critere == ",") OR ($critere == '/')) + $f = 'calculer_critere_parties'; + else $f = 'calculer_critere_DEFAUT'; + } // Applique le critere - $res = $f($idb, $boucles, $param, $not); + $res = $f($idb, $boucles, $crit); - // gestion d'erreur + // Gestion d'erreur if (is_array($res)) erreur_squelette($res); } } # Criteres numeriques et de comparaison -function calculer_critere_DEFAUT($idb, &$boucles, $param, $not) { +function calculer_critere_DEFAUT($idb, &$boucles, $crit) { + global $table_date, $tables_des_serveurs_sql; $boucle = &$boucles[$idb]; $type = $boucle->type_requete; - $id_table = $boucle->id_table; + $col_table = $id_table = $boucle->id_table; $primary = $boucle->primary; $id_field = $id_table . '.' . $primary; + $fct = ''; + + // cas d'une valeur comparee a elle-meme ou son referent + if (count($crit->param) ==0) + { $op = '='; + $col = $crit->op; + $val = $crit->op; + + // Cas special {lang} : aller chercher $GLOBALS['spip_lang'] + if ($val == 'lang') + $val = '".$GLOBALS[\'spip_lang\']."'; + else { + // Si id_parent, comparer l'id_parent avec l'id_objet + // de la boucle superieure.... faudrait verifier qu'il existe + // pour eviter l'erreur SQL + if ($val == 'id_parent') + $val = $primary; + // Si id_enfant, comparer l'id_objet avec l'id_parent + // de la boucle superieure + else if ($val == 'id_enfant') + $val = 'id_parent'; + $val = array("addslashes(" .calculer_argument_precedent($idb, $val, $boucles) .")"); + } + } + else + { + // comparaison explicite + // le phraseur impose que le premier param soit du texte + $params = $crit->param; + $col = array_shift($params); + $col = $col[0]->texte; + $op = $crit->op; + + // fonction SQL ? + if (ereg("([a-z_]+)\(([a-z_]+)\)", $col,$match3)) { + $col = $match3[2]; + $fct = $match3[1]; + } + + $val = array(); + foreach ($params as $param) + $val[] = calculer_liste($param, array(), $boucles, $idb); + spip_log("vol0: $val[0]"); + } - if (ereg('^([0-9a-zA-Z#_}{-]+)([,/])([0-9a-zA-Z#_}{-]+)$', $param, $match)) - calculer_critere_parties($idb, $boucles, $param, $not, $match); - - // Restriction de valeurs (implicite ou explicite) - else if (eregi('^(`?[a-z_]+\(?[a-z_]*\)?`?) *(\??)((!?)(<=?|>=?|==?|IN) *"?([^<>=!"]*))?"?$', $param, $match)) { - $op = $match[5] ? $match[5] : '='; - - // Variable comparee - $col = $match[1]; - // fonction SQL - $fct = ''; - if (ereg("([a-z_]+)\(([a-z_]+)\)", $col,$match3)) { - $col = $match3[2]; - $fct = $match3[1]; - } - $col_table = $id_table; - // Valeur de comparaison - if ($match[3]) { - if (strtoupper($op) != 'IN') { - $val = calculer_param_dynamique($match[6], $boucles, $boucles[$idb]->id_parent); - // gestion d'erreur - if (is_array($val)) erreur_squelette($val); - } - else { - // traitement special des valeurs textuelles - $val = calculer_params_dynamiques($match[6], $boucles, $idb); - } - } - - else { - $val = $match[1]; - - // Cas special {lang} : aller chercher $GLOBALS['spip_lang'] - if ($val == 'lang') - $val = '".$GLOBALS[\'spip_lang\']."'; - else { - // Si id_parent, comparer l'id_parent avec l'id_objet - // de la boucle superieure - if ($val == 'id_parent') - $val = $primary; - // Si id_enfant, comparer l'id_objet avec l'id_parent - // de la boucle superieure - else if ($val == 'id_enfant') - $val = 'id_parent'; - $val = calculer_argument_precedent($idb, $val, $boucles) ; - if (ereg('^\$',$val)) - $val = '" . addslashes(' . $val . ') . "'; - else - $val = addslashes($val); - } - - } + // cas special: statut= + // si on l'invoque dans une boucle il faut interdire + // a la boucle de mettre ses propres criteres de statut + // http://www.spip.net/@statut (a documenter) + if ($col == 'statut') + $result->where['statut'] = '1'; - if ($s = calculer_critere_externe($boucle, $id_field,$col, $type)) { - $col_table = $s; - } + if ($s = calculer_critere_externe($boucle, $id_field,$col, $type)) + $col_table = $s; - // Cas particulier pour les raccourcis 'type_mot' et 'titre_mot' - else if ($type != 'mots' + // Cas particulier pour les raccourcis 'type_mot' et 'titre_mot' + else if ($type != 'mots' AND ($col == 'type_mot' OR $col == 'titre_mot' OR $col == 'id_groupe')) { - if ($type == 'forums') - $col_lien = "forum"; - else if ($type == 'syndication') - $col_lien = "syndic"; - else - $col_lien = $type; - $boucle->from[] = "spip_mots_$col_lien AS lien_mot"; - $boucle->from[] = 'spip_mots AS mots'; - $boucle->where[] = "$id_field=lien_mot." . $primary; - $boucle->where[] = 'lien_mot.id_mot=mots.id_mot'; - $boucle->group = $id_field; - $boucle->select[] = $id_field; # pour postgres, neuneu ici - $col_table = 'mots'; - - $boucle->lien = true; - if ($col == 'type_mot') - $col = 'type'; - else if ($col == 'titre_mot') - $col = 'titre'; - else if ($col == 'id_groupe') - $col = 'id_groupe'; - } + if ($type == 'forums') + $col_lien = "forum"; + else if ($type == 'syndication') + $col_lien = "syndic"; + else + $col_lien = $type; + $boucle->from[] = "spip_mots_$col_lien AS lien_mot"; + $boucle->from[] = 'spip_mots AS mots'; + $boucle->where[] = "$id_field=lien_mot." . $primary; + $boucle->where[] = 'lien_mot.id_mot=mots.id_mot'; + $boucle->group = $id_field; + $boucle->select[] = $id_field; # pour postgres, neuneu ici + $col_table = 'mots'; + + $boucle->lien = true; + if ($col == 'type_mot') + $col = 'type'; + else if ($col == 'titre_mot') + $col = 'titre'; + else if ($col == 'id_groupe') + $col = 'id_groupe'; + } - // Cas particulier : selection des documents selon l'extension - if ($type == 'documents' AND $col == 'extension') - $col_table = 'types_documents'; - // HACK : selection des documents selon mode 'image' - // (a creer en dur dans la base) - else if ($type == 'documents' AND $col == 'mode' - AND $val == 'image') - $val = 'vignette'; - // Cas particulier : lier les articles syndiques - // au site correspondant - else if ($type == 'syndic_articles' AND - !ereg("^(id_syndic_article|titre|url|date|descriptif|lesauteurs|id_document)$",$col)) - $col_table = 'syndic'; - - // Cas particulier : id_enfant => utiliser la colonne id_objet - if ($col == 'id_enfant') - $col = $primary; - // Cas particulier : id_secteur = id_rubrique pour certaines tables - if (($type == 'breves' OR $type == 'forums') AND $col == 'id_secteur') - $col = 'id_rubrique'; - - // Cas particulier : expressions de date - if (ereg("^(date|mois|annee|heure|age|age_relatif|jour_relatif|mois_relatif|annee_relatif)(_redac)?$", $col, $regs)) { - $col = $regs[1]; - if ($regs[2]) { - $date_orig = $id_table . ".date_redac"; - $date_compare = '\'" . normaliser_date(' . - calculer_argument_precedent($idb, 'date_redac', $boucles) . - ') . "\''; - } - else { - $date_orig = "$id_table." . $table_date[$type]; - $date_compare = '\'" . normaliser_date(' . - calculer_argument_precedent($idb, 'date', $boucles) . - ') . "\''; - } - - if ($col == 'date') { - $col = $date_orig; - $col_table = ''; - } - else if ($col == 'mois') { - $col = "MONTH($date_orig)"; - $col_table = ''; - } - else if ($col == 'annee') { - $col = "YEAR($date_orig)"; - $col_table = ''; - } - else if ($col == 'heure') { - $col = "DATE_FORMAT($date_orig, '%H:%i')"; - $col_table = ''; - } - else if ($col == 'age') { - $col = calculer_param_date("now()", $date_orig); - $col_table = ''; - } - else if ($col == 'age_relatif') { - $col = calculer_param_date($date_compare, $date_orig); - $col_table = ''; - } - else if ($col == 'jour_relatif') { - $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 . ")))"; - $col_table = ''; - } - else if ($col == 'mois_relatif') { - $col = "MONTH(" . $date_compare . ")-MONTH(" . - $date_orig . ")+12*(YEAR(" . $date_compare . - ")-YEAR(" . $date_orig . "))"; - $col_table = ''; - } - else if ($col == 'annee_relatif') { - $col = "YEAR(" . $date_compare . ")-YEAR(" . - $date_orig . ")"; - $col_table = ''; - } - } + // Cas particulier : selection des documents selon l'extension + if ($type == 'documents' AND $col == 'extension') + $col_table = 'types_documents'; + // HACK : selection des documents selon mode 'image' + // (a creer en dur dans la base) + else if ($type == 'documents' AND $col == 'mode' AND $val[0] == "'image'") + $val[0] = "'vignette'"; + // Cas particulier : lier les articles syndiques + // au site correspondant + else if ($type == 'syndic_articles' AND + !ereg("^(id_syndic_article|titre|url|date|descriptif|lesauteurs|id_document)$",$col)) + $col_table = 'syndic'; + + // Cas particulier : id_enfant => utiliser la colonne id_objet + if ($col == 'id_enfant') + $col = $primary; + // Cas particulier : id_secteur = id_rubrique pour certaines tables + if (($type == 'breves' OR $type == 'forums') AND $col == 'id_secteur') + $col = 'id_rubrique'; + + // Cas particulier : expressions de date + if (ereg("^(date|mois|annee|heure|age|age_relatif|jour_relatif|mois_relatif|annee_relatif)(_redac)?$", $col, $regs)) { + $col = $regs[1]; + if ($regs[2]) { + $date_orig = $id_table . ".date_redac"; + $date_compare = '\'" . normaliser_date(' . + calculer_argument_precedent($idb, 'date_redac', $boucles) . + ') . "\''; + } + else { + $date_orig = "$id_table." . $table_date[$type]; + $date_compare = '\'" . normaliser_date(' . + calculer_argument_precedent($idb, 'date', $boucles) . + ') . "\''; + } - if ($type == 'forums' AND - ($col == 'id_parent' OR $col == 'id_forum')) - $boucle->plat = true; + if ($col == 'date') { + $col = $date_orig; + $col_table = ''; + } + else if ($col == 'mois') { + $col = "MONTH($date_orig)"; + $col_table = ''; + } + else if ($col == 'annee') { + $col = "YEAR($date_orig)"; + $col_table = ''; + } + else if ($col == 'heure') { + $col = "DATE_FORMAT($date_orig, '%H:%i')"; + $col_table = ''; + } + else if ($col == 'age') { + $col = calculer_param_date("now()", $date_orig); + $col_table = ''; + } + else if ($col == 'age_relatif') { + $col = calculer_param_date($date_compare, $date_orig); + $col_table = ''; + } + else if ($col == 'jour_relatif') { + $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 . ")))"; + $col_table = ''; + } + else if ($col == 'mois_relatif') { + $col = "MONTH(" . $date_compare . ")-MONTH(" . + $date_orig . ")+12*(YEAR(" . $date_compare . + ")-YEAR(" . $date_orig . "))"; + $col_table = ''; + } + else if ($col == 'annee_relatif') { + $col = "YEAR(" . $date_compare . ")-YEAR(" . + $date_orig . ")"; + $col_table = ''; + } + } - // Operateur de comparaison - if ($col_table) { - if ($col[0] == "`") - $col = "$col_table." . substr($col,1,-1); - else $col = "$col_table.$col"; - } + if ($type == 'forums' AND + ($col == 'id_parent' OR $col == 'id_forum')) + $boucle->plat = true; - if (strtoupper($op) == 'IN') { - // traitement special des valeurs textuelles - $where = "$col IN ($val)"; - if ($match[4] == '!') { - $where = "NOT ($where)"; - } else { - $boucle->default_order = 'rang'; - $boucle->select[] = - "FIND_IN_SET($col, \\\"$val\\\") AS rang"; - } - } else { - if ($op == '==') $op = 'REGEXP'; - if ($fct) $col = "$fct($col)"; - if ($match[4] == '!') - $where = "NOT ($col $op '$val')"; - else - $where = "($col $op '$val')"; - - // operateur optionnel {lang?} - if ($match[2]) { - $champ = calculer_argument_precedent($idb, $match[1], $boucles) ; - $where = "\".($champ ? \"$where\" : 1).\""; - } + // Operateur de comparaison + if ($col_table) { + if ($col[0] == "`") + $col = "$col_table." . substr($col,1,-1); + else $col = "$col_table.$col"; + } + spip_log("'$op'"); + if (strtoupper($op) == 'IN') { + // traitement special d'une suite de valeurs + foreach ($val as $k => $v) { + spip_log("IN '$v'"); + if (!ereg("^$", $v)) + // il manque le addslashes mais il faut d'abord eliminer la chaine + // vide qui vient + $val[$k] = "\n'\" . addslashes(" . ($v) . ") . \"'"; + } + $val = join(', ',$val); + if (!ereg("^ *\(.*) *$", $val)) $val = "($val)"; + $where = "$col IN $val"; + if ($crit->not) { + $where = "NOT ($where)"; + } else { + $boucle->default_order = 'rang'; + $boucle->select[] = + "FIND_IN_SET($col, \\\"$val\\\") AS rang"; + } + } else { + if ($op == '==') $op = 'REGEXP'; + if ($fct) $col = "$fct($col)"; + $where = "($col $op '\" . " . $val[0] . ' . "\')'; + if ($crit->not) $where = "NOT $where"; + + // operateur optionnel {lang?} + if ($crit->cond) { + $champ = calculer_argument_precedent($idb, $arg1, $boucles) ; + $where = "\".($champ ? \"$where\" : 1).\""; + } - } - $boucle->where[] = $where; - } // fin du if sur les restrictions de valeurs - else - erreur_squelette(_T('zbug_critere_inconnu', array('critere' => $param))); + } + $boucle->where[] = $where; } // traitement des relations externes par une jointure. @@ -588,7 +561,6 @@ function calculer_critere_externe(&$boucle, $id_field, $col, $type) return $col_table; } - function calculer_param_date($date_compare, $date_orig) { return "LEAST((UNIX_TIMESTAMP(" . @@ -614,72 +586,4 @@ function calculer_param_date($date_compare, $date_orig) { ")))"; } -// -// Calculer les parametres -// - -// $val = le parametre (exemple : #_boucle:TITRE -// $boucle = le tableau des boucles -// $idb = la boucle de reference : -// - dans le cas d'un inclure, la boucle courante -// - dans le cas d'un parametre de boucle, la boucle parente -function calculer_param_dynamique($val, &$boucles, $idb) { -# if (ereg('^ *\((.*)) *$', $val, $m)) $val = $m[1]; # si on veut (#...) - if (ereg(NOM_DE_CHAMP . "([{][^}]*[}])?", $val, $regs)) { -#spip_log(serialize($regs)." ($idb)"); - $champ = new Champ; - $champ->nom_boucle = $regs[2]; - $champ->nom_champ = $regs[3]; - $champ->etoile = $regs[4]; - $champ->id_boucle = $idb; - $champ->boucles = &$boucles; - phraser_args($regs[5], "", "", array(), $champ); - $champ = calculer_champ($champ); - return '" . addslashes(' . $champ . ') . "'; - - } else { - if ($val[0]== '%') { - spip_log($val . - " est obsolete; utiliser ENV{" . substr($val,1) . "}"); - return '" . addslashes($Pile[0][\''. substr($val,1) ."']) . \""; - } - else - return addslashes($val); - } -} - -/* -// une version acceptant les champs etendus serait en gros: -function calculer_param_dynamique($val, &$boucles, $idb) { - -return '" . addslashes(' . - calculer_liste(phraser_champs_etendus($val, array()), - array(), $boucles, $idb) - . ') . "'; -} -/* */ - -// -function calculer_params_dynamiques($liste, &$boucles, $idb) { - ereg("^ *\(?(.*[^)])\)? *$",$liste, $reg); - $res = array(); - foreach (split(" *, *", $reg[1]) as $v) { - $v = calculer_param_dynamique($v, $boucles, $boucles[$idb]->id_parent); - if (is_array($v)) erreur_squelette($v); - if (strpos('0123456789',$v[0]) !== false) - $res[] = $v; - else if ($v[0]=='"') - $res[] = "'" . $v . "'"; - else - $res[] = "'$v'"; - } - return join(',', $res); -} - -function simplifie_param_dynamique($val, &$boucles, $idb) -{ - $a = calculer_param_dynamique($val, $boucles, $boucles[$idb]->id_parent); - if (!ereg('" \. *(.*)\. "', $a, $m)) return $a; - return $m[1]; -} ?> diff --git a/inc-html-squel.php3 b/inc-html-squel.php3 index d4b742c489a1674aa3d2c83241be210ba66a016f..019d990efe22278f7ac4ae5050438cf8b97e17d9 100644 --- a/inc-html-squel.php3 +++ b/inc-html-squel.php3 @@ -23,16 +23,14 @@ define("_INC_HTML_SQUEL", "1"); define('NOM_DE_BOUCLE', "[0-9]+|[-_][-_.a-zA-Z0-9]*"); define('NOM_DE_CHAMP', "#((" . NOM_DE_BOUCLE . "):)?([A-Z_]+)(\*?)"); define('CHAMP_ETENDU', '\[([^]\[]*)\(' . NOM_DE_CHAMP . '([^[)]*\)[^]\[]*)\]'); -define('PARAM_DE_BOUCLE','[[:space:]]*[{][[:space:]]*([^}{]*([{][^}]*[}][^}]*)*)[[:space:]]*[}]'); +define('PARAM_DE_BOUCLE','[[:space:]]*[{][[:space:]]*([^{}]*([{][^[}]]*[}][^[}]]*)*)[[:space:]]*[}]'); define('TYPE_DE_BOUCLE', "[^)]*"); define('BALISE_DE_BOUCLE', "^<BOUCLE(" . NOM_DE_BOUCLE . ')[[:space:]]*\((' . TYPE_DE_BOUCLE . - ')\)((' . - PARAM_DE_BOUCLE . - ')*)[[:space:]]*>'); + ')\)'); define('PARAM_INCLURE','^[[:space:]]*[{][[:space:]]*([_0-9a-zA-Z]+)[[:space:]]*(=)?'); define('BALISE_INCLURE','<INCLU[DR]E[[:space:]]*\(([^)]*)\)'); define('DEBUT_DE_BOUCLE','/<B('.NOM_DE_BOUCLE.')>.*?<BOUCLE\1[^-_.a-zA-Z0-9]|<BOUCLE('.NOM_DE_BOUCLE.')/ms'); # preg @@ -47,7 +45,7 @@ function phraser_inclure($texte, $result) { $texte = substr($texte, $p+strlen($match[0])); // on assimile {var=val} a une liste de un argument sans fonction phraser_args($texte,">","",$result,$champ); - foreach ($champ->args as $k => $v) { + foreach ($champ->param as $k => $v) { $var = $v[1][0]; if ($var->type != 'texte') erreur_squelette(_T('zbug_parametres_inclus_incorrects'), @@ -55,16 +53,16 @@ function phraser_inclure($texte, $result) { else { ereg("^([^=]*)(=)?(.*)$", $var->texte,$m); if ($m[2]) { - $champ->args[$k][0] = $m[1]; + $champ->param[$k][0] = $m[1]; $val = $m[3]; if (ereg('^[\'"](.*)[\'"]$', $val, $m)) $val = $m[1]; - $champ->args[$k][1][0]->texte = $val; + $champ->param[$k][1][0]->texte = $val; } else - $champ->args[$k] = array($m[1]); + $champ->param[$k] = array($m[1]); } } - $texte = $champ->apres; + $texte = substr($champ->apres,1); $champ->apres = ""; $result[] = $champ; } @@ -84,7 +82,7 @@ function phraser_polyglotte($texte,$result) { $lang = ''; $bloc = $match[1]; $texte = substr($texte,$p+strlen($match[0])); - while (preg_match("/^[[:space:]]*([^[{]*)[[:space:]]*[{\[]([a-z_]+)[}\]](.*)$/si", $bloc, $regs)) { + while (preg_match("/^[[:space:]]*([^[{]*)[[:space:]]*[[{]([a-z_]+)[]}](.*)$/si", $bloc, $regs)) { $trad = $regs[1]; if ($trad OR $lang) $champ->traductions[$lang] = $trad; @@ -159,17 +157,24 @@ function phraser_champs_etendus($texte, $result) { // Analyse les filtres d'un champ etendu et affecte le resultat // renvoie la liste des lexemes d'origine augmentee // de ceux trouves dans les arguments des filtres (rare) +// sert aussi aux arguments des includes et aux criteres de boucles +// Tres chevelu function phraser_args($texte, $fin, $sep, $result, &$pointeur_champ) { $texte = ltrim($texte); - while (($texte!=="") && $texte[0] != $fin) { + while (($texte!=="") && strpos($fin, $texte[0]) === false) { ereg("^(\|?[^{)|]*)(.*)$", $texte, $match); $suite = ltrim($match[2]); $fonc = $match[1]; if ($fonc[0] == "|") $fonc = substr($fonc,1); $res = array(trim($fonc)); $args = $suite; - if ($suite[0] == '{') { + if ($suite[0] != '{') + { if (!$match[1]) { + erreur_squelette(_T('zbug_info_erreur_squelette'), $texte); + break; + } + } else { $args = ltrim(substr($suite,1)); $collecte = array(); while ($args && $args[0] != '}') { @@ -177,48 +182,74 @@ function phraser_args($texte, $fin, $sep, $result, &$pointeur_champ) { ereg ('^(")([^"]*)(")(.*)$', $args, $regs); else if ($args[0] == "'") ereg ("^(')([^']*)(')(.*)$", $args, $regs); - else - ereg("^( *)([^,}{]*([{][^}{]*[}][^,}{]*)*[^,}]*)([,}$fin].*)$", $args, $regs); + else { + ereg("^( *)([^,}]*)([,}$fin].*)$", $args, $regs); + if (!strlen($regs[2])) + { + erreur_squelette(_T('zbug_info_erreur_squelette'), $args); + $args = ''; + exit; + } + } - $args = ltrim($regs[count($regs)-1]); $arg = $regs[2]; - if (trim($regs[1])) { // valeur = ", ', ou vide + if (trim($regs[1])) { $champ = new Texte; $champ->texte = $arg; + $champ->apres = $champ->avant = $regs[1]; $result[] = $champ; $collecte[] = $champ; - } else { // valeur = ", ', ou vide - if ((count($regs) > 3) && - ereg("^(.*)(#[A-Z0-9:_=]+[{].*[}])(.*)$",$arg, $r)) - { - // champ avec arg, sans les [( )]: on les rajoute - $arg = $r[1] . '[(' . $r[2] . ')' . $r[3] . ']'; - $arg = phraser_champs_etendus($arg, array()); - - } else { - $arg = phraser_champs_exterieurs(ltrim($arg), $sep, $result); + $args = ltrim($regs[count($regs)-1]); + } else { + if (!ereg("^(.*)" . NOM_DE_CHAMP ."[|{]", $arg, $r)) { + $arg = phraser_champs_exterieurs($arg, $sep, $result); + $args = ltrim($regs[count($regs)-1]); + $collecte = array_merge($collecte, $arg); + $result = array_merge($result, $arg); + } + else { + $pred = $r[1]; + $par = ',}'; + if (ereg('(.*)\($', $pred, $m)) + {$pred = $m[1]; $par =')';} + if ($pred) { + $champ = new Texte; + $champ->texte = $pred; + $champ->apres = $champ->avant = ""; + $result[] = $champ; + $collecte[] = $champ; + } + $rec = substr($args, strpos($r[0],$args)+strlen($r[0])-1); + $champ = new Champ; + $champ->nom_boucle = $r[3]; + $champ->nom_champ = $r[4]; + $champ->etoile = $r[5]; + phraser_args($rec, $par, $sep, array(), $champ); + $args = $champ->apres ; + $champ->apres = ''; + if ($par==')') $args = substr($args,1); + $collecte[] = $champ; + $result[] = $champ; } - $collecte = array_merge($collecte, $arg); - $result = array_merge($result, $arg); } - $args = ltrim($args); if ($args[0] == ',') { - $args = substr($args,1); + $args = ltrim(substr($args,1)); if ($collecte) {$res[] = $collecte; $collecte = array();} } + } if ($collecte) {$res[] = $collecte; $collecte = array();} $args = substr($args,1); } $n = strlen($suite) - strlen($args); - $pointeur_champ->args[] = $res; + $pointeur_champ->param[] = $res; // pour les balises avec faux filtres qui boudent ce dur larbeur $pointeur_champ->fonctions[] = array($fonc, substr($suite, 0, $n)); $texte = ltrim($args); } - # virer la parenthese fermante ou le chevron fermant - $pointeur_champ->apres = substr($texte,1); + # laisser l'appelant virer le caractere fermant + $pointeur_champ->apres = $texte; return $result; } @@ -244,7 +275,7 @@ function phraser_champs_interieurs($texte, $sep, $result) { // phraser_args indiquera ou commence apres $result = phraser_args($regs[6], ")", $sep, $result, $champ); $champ->avant = phraser_champs_exterieurs($regs[1],$sep,$result); - $champ->apres = phraser_champs_exterieurs($champ->apres,$sep,$result); + $champ->apres = phraser_champs_exterieurs(substr($champ->apres,1),$sep,$result); $p = strpos($texte, $regs[0]); @@ -264,55 +295,123 @@ function phraser_champs_interieurs($texte, $sep, $result) { else return phraser_champs_exterieurs($x, $sep, $result);} } +// analyse des criteres de boucle, + +function phraser_criteres($params, &$result) { -function phraser_param($params, &$result) { - $params2 = array(); $args = array(); $type = $result->type_requete; - while (ereg('^' . PARAM_DE_BOUCLE . '[[:space:]]*(.*)$', trim($params), $m)) { - $params = $m[3]; - $param = trim($m[1]); + foreach($params as $v) { + $var = $v[1][0]; + $param = ($var->type != 'texte') ? "" : $var->texte; + if ((count($v) > 2) && (!eregi("[^A-Za-z]IN[^A-Za-z]",$param))) + { +// plus d'un argument: +// c'est soit le critere LIMIT debut,fin si ça se termine par un chiffre +// soit le critere PAR soit un critere perso + + if (($var->type != 'texte') || + (strpos("0123456789", $param[strlen($param)-1]) + !== false)) + $op = ','; + else { + ereg("^([a-zA-Z][a-zA-Z0-9]*) *(.*)$", $param, $m); + $op = $m[1]; + $v[1][0]->texte = $m[2]; + } + array_shift($v); + $crit = new Critere; + $crit->op = $op; + $crit->not = ""; + $crit->param = $v; + $args[] = $crit; + } else { + + if ($var->type != 'texte') + erreur_squelette('criteres',''); + else { // traiter qq lexemes particuliers pour faciliter la suite - if (($param == 'tout') OR ($param == 'tous')) - $result->tout = true; - else if ($param == 'plat') - $result->plat = true; - // les separateurs (specs CSS3 aN+b a finaliser) - else if (ereg('^"([^"}]*)"( *, *(\-?[0-9]*)n)?(\+?([0-9]+))?)?$', $param, $m)) - $result->separateur[] = $m[1]; + + // les separateurs + if ($var->apres) + $result->separateur[] = $param; + elseif (($param == 'tout') OR ($param == 'tous')) + $result->tout = true; + elseif ($param == 'plat') + $result->plat = true; // Boucle hierarchie, analyser le critere id_article - id_rubrique // - id_syndic, afin, dans les cas autres que {id_rubrique}, de // forcer {tout} pour avoir la rubrique mere... - else if (($type == 'hierarchie') && - ($param == 'id_article' OR $param == 'id_syndic')) - $result->tout = true; - else if (($type == 'hierarchie') && ($param == 'id_rubrique')) - {;} - else { - $params2[] = ($param == 'unique') ? 'doublons' :$param; - /* pour bientot - if (ereg('^([0-9a-zA-Z#_}{-]+)([,/])([0-9a-zA-Z#_}{-]+)$', $param, $match)) - $args['parties'] = $match; - else if (eregi('^(`?[a-z_]+\(?[a-z_]*\)?`?) *(\??)(!?)(<=?|>=?|==?|IN) *"?([^<>=!"]*)"?$', $param, $match)) - $args['comparaison'] = $match; - else { - preg_match("/^([!]?)[[:space:]]*(debut|([a-z_]+))/ism", $param, $match); - // contient aussi les comparaisons implicites ! - $args[$match[2]] = $match; - */ + elseif (($type == 'hierarchie') && + ($param == 'id_article' OR $param == 'id_syndic')) + $result->tout = true; + elseif (($type == 'hierarchie') && ($param == 'id_rubrique')) + {;} + else { + // pas d'emplacement statique, faut un dynamique + /// mais il y a 2 cas qui ont les 2 ! + if (($param == 'unique') || ($param == 'doublons')) + { + // sera remplace ensuite par la bonne valeur + // mais il faut l'indiquer tout de suite + $result->doublons = true; + $param = 'doublons'; + } + elseif ($param == 'recherche') + // meme chose (a cause de #nom_de_boucle:URL_*) + $result->hash = true; + + if (ereg('^([0-9-]+)(/)([0-9-]+)$', $param, $m)) { + $v[0] = $v[1]; + $v[0][0]->texte = $m[1]; + $v[1][0]->texte = $m[2]; + $crit = new Critere; + $crit->op = '/'; + $crit->not = ""; + $crit->param = $v; + } elseif (ereg('^(`?[A-Za-z_]+\(?[A-Za-z_]*\)?`?) *(\??)(!?)(<=?|>=?|==?| IN) *"?([^<>=!"]*)"?$', $param, $m)) { + $v[0] = $v[1]; + $v[0][0]->texte = $m[1]; + $v[1][0]->texte = $m[5]; + $crit = new Critere; + $crit->param = $v; + $crit->op = trim($m[4]); + $crit->not = $m[3]; + $crit->cond = $m[2]; + if ($m[1] == 'lang_select') $crit->op = $m[1]; + } elseif (preg_match("/^([!]?)[[:space:]]*([a-z_]+)[[:space:]]*(\??)(.*)$/ism", $param, $m)) { + + // contient aussi les comparaisons implicites ! + array_shift($v); + if ($m[4]) + $v[0][0]->texte = $m[4]; + else { + array_shift($v[0]); + if (!$v[0]) array_shift($v); + } + $crit = new Critere; + $crit->op = $m[2]; + $crit->param = $v; + $crit->not = $m[1]; + $crit->cond = $m[3]; + } + else + erreur_squelette(_T('zbug_critere_inconnu', + array('critere' => $param))); + $args[] = $crit; + } + } } } - $result->param = $params2; - // pour bientot $result->args = $args2; + $result->criteres = $args; } function phraser($texte, $id_parent, &$boucles, $nom) { $all_res = array(); - while (preg_match(DEBUT_DE_BOUCLE, $texte, $regs)) { $nom_boucle = $regs[1].$regs[2]; $p = strpos($texte, '<BOUCLE'.$nom_boucle); @@ -330,12 +429,11 @@ function phraser($texte, $id_parent, &$boucles, $nom) { // $debut = substr($texte, 0, $p); $milieu = substr($texte, $p); - if (!ereg(BALISE_DE_BOUCLE, $milieu, $match)) { erreur_squelette((_T('zbug_erreur_boucle_syntaxe')), $milieu); } + $milieu = substr($milieu, strlen($match[0])); $id_boucle = $match[1]; - $result = new Boucle; $result->id_parent = $id_parent; $result->id_boucle = $id_boucle; @@ -354,12 +452,15 @@ function phraser($texte, $id_parent, &$boucles, $nom) { // if (substr($type, 0, 6) == 'boucle') { $result->type_requete = 'boucle'; - $result->param = substr($match[2], 6); + $result->param[0] = substr($match[2], 6); + $milieu = substr($milieu, strpos($milieu, '>')); } else { $result->type_requete = $type; - phraser_param($match[3], $result); + phraser_args($milieu,">","",$all_res,$result); + phraser_criteres($result->param, $result); + $milieu = substr($result->apres,1); + $result->apres = ""; } - // // Recuperer la partie conditionnelle avant // @@ -369,7 +470,7 @@ function phraser($texte, $id_parent, &$boucles, $nom) { $result->avant = substr($debut, $p + strlen($s)); $debut = substr($debut, 0, $p); } - $milieu = substr($milieu, strlen($match[0])); + if (strpos($milieu, $s)) { erreur_squelette(_T('zbug_erreur_boucle_syntaxe'), $id_boucle . @@ -388,7 +489,6 @@ function phraser($texte, $id_parent, &$boucles, $nom) { } $texte = substr($milieu, $p + strlen($s)); $milieu = substr($milieu, 0, $p); - // // 1. Recuperer la partie conditionnelle apres // @@ -408,7 +508,6 @@ function phraser($texte, $id_parent, &$boucles, $nom) { $result->altern = substr($texte, 0, $p); $texte = substr($texte, $p + strlen($s)); } - $result->avant = phraser($result->avant, $id_parent,$boucles, $nom); $result->apres = phraser($result->apres, $id_parent,$boucles, $nom); $result->altern = phraser($result->altern,$id_parent,$boucles, $nom); @@ -423,8 +522,6 @@ function phraser($texte, $id_parent, &$boucles, $nom) { } else $boucles[$id_boucle] = $result; } - return phraser_champs_etendus($texte, $all_res); } - ?>