[SPIP Zone] [Spip-zone-commit] r11357 - /_plugins_/_stable_/forms/forms_et_tables_1_9_1/public/forms_boucles.php

le commit est parti trop vite, avant que je corrige le commentaire :
(DONNEES) -> les donnees d'une table
(TABLE_CHAMPS) -> les champs d'une table
(DONNEE_CHAMPS) -> les valeur des champs pour une donnee (donc attention DONNEE au singulier, CHAMPS au pluriel)

voila ces nommages vont alleger l'ecriture
Par ailleurs, le formulaire de recherche sur les tables applique un AND entre les conditions des champs (il faut que le champ 1 ait telle valeur ET le champ 2 telle valeur)
Mais, attention tout de meme, sur les champs de type multiple, cela reste un OU entre les valeurs du meme champ (champ 1 ait telle ou telle valeur ET champ 2 aie telle valeur)

Pour etendre le formulaire de recherche à tous les types de champs(select,multiple, mot par defaut) il suffit de personaliser formulaires/forms_recherche dans son dossier squelette)

cedric@yterium.com a écrit :

Author: cedric@yterium.com
Date: Tue Apr 17 11:00:15 2007
New Revision: 11357

Log:
"des alias DONNEES (au lieu de FORMS_DONNEES), TABLE_CHAMPS (au lieur de FORMS_CHAMPS) et DONNEES_CHAMPS au lieu de (FORMS_DONNEES_CHAMPS)
pour les skelette"

Modified:
    _plugins_/_stable_/forms/forms_et_tables_1_9_1/public/forms_boucles.php

Modified: _plugins_/_stable_/forms/forms_et_tables_1_9_1/public/forms_boucles.php

--- _plugins_/_stable_/forms/forms_et_tables_1_9_1/public/forms_boucles.php (original)
+++ _plugins_/_stable_/forms/forms_et_tables_1_9_1/public/forms_boucles.php Tue Apr 17 11:00:15 2007
@@ -69,6 +69,11 @@
     $boucle->modificateur['crit_filtre'] = 1;
     //$boucle->where= array("'='", "'$boucle->id_table." . "id_parent'", 0);
   }
+
+ function boucle_DONNEES_dist($id_boucle, &$boucles){
+ if (function_exists($f='boucle_FORMS_DONNEES') OR function_exists($f='boucle_FORMS_DONNEES_dist'))
+ return $f($id_boucle, &$boucles);
+ }
   //
   // <BOUCLE(FORMS_DONNEES)>
   //
@@ -105,13 +110,13 @@
     if ((\$r = _request(\$row['champ']))!==NULL){
       if (is_array(\$r)){
         if (strlen(implode("",\$r))) - \$filtre .= " OR (dc.champ="._q(\$row['champ'])." AND dc.valeur IN (".implode(',',array_map('_q',\$r))."))";
+ \$filtre .= " AND (dc.champ="._q(\$row['champ'])." AND dc.valeur IN (".implode(',',array_map('_q',\$r))."))";
       }
       elseif (strlen(\$r))
- \$filtre .= " OR (dc.champ="._q(\$row['champ'])." AND dc.valeur="._q(\$r).")";
+ \$filtre .= " AND (dc.champ="._q(\$row['champ'])." AND dc.valeur="._q(\$r).")";
     }
   }
- if (strlen(\$filtre)) \$filtre = substr(\$filtre,4);
+ if (strlen(\$filtre)) \$filtre = substr(\$filtre,5);
   else \$filtre="1=1";
code;
       $boucle->where = '$filtre';
@@ -162,6 +167,10 @@
     return calculer_boucle($id_boucle, $boucles); }
+ function boucle_TABLE_CHAMPS_dist($id_boucle, &$boucles){
+ if (function_exists($f='boucle_FORMS_CHAMPS') OR function_exists($f='boucle_FORMS_CHAMPS_dist'))
+ return $f($id_boucle, &$boucles);
+ }
   //
   // <BOUCLE(FORMS_CHAMPS)>
   //
@@ -177,6 +186,10 @@
     return calculer_boucle($id_boucle, $boucles); }
   
+ function boucle_DONNEE_CHAMPS_dist($id_boucle, &$boucles){
+ if (function_exists($f='boucle_FORMS_DONNEES_CHAMPS') OR function_exists($f='boucle_FORMS_DONNEES_CHAMPS_dist'))
+ return $f($id_boucle, &$boucles);
+ }
   //
   // <BOUCLE(FORMS_DONNEES_CHAMPS)>
   //

_______________________________________________
Spip-zone-commit@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone-commit
  

cedric.morin@yterium.com a écrit :

....
Par ailleurs, le formulaire de recherche sur les tables applique un AND entre les conditions des champs (il faut que le champ 1 ait telle valeur ET le champ 2 telle valeur)
Mais, attention tout de meme, sur les champs de type multiple, cela reste un OU entre les valeurs du meme champ (champ 1 ait telle ou telle valeur ET champ 2 aie telle valeur)

Pour etendre le formulaire de recherche à tous les types de champs(select,multiple, mot par defaut) il suffit de personaliser formulaires/forms_recherche dans son dossier squelette)

- \$filtre .= " OR (dc.champ="._q(\$row['champ'])." AND dc.valeur IN (".implode(',',array_map('_q',\$r))."))";
+ \$filtre .= " AND (dc.champ="._q(\$row['champ'])." AND dc.valeur IN (".implode(',',array_map('_q',\$r))."))";
    

Bonjour,

Il me semble que transformer la recherche de OU en ET entre les champs d'un formulaire de recherche n'est pas si trivial : remplacer le OR par un AND entre les conditions ne marche que si on ne fait une recherche que sur UN SEUL champ du formulaire !

Dès lors que l'on spécifie plusieurs champs, on se retrouve avec des requêtes de type dc.champ='mot_1' AND dc.champ='mot_2' ce qui ne peut conduire à un résultat.
Il faudrait plutôt envisager de faire une requête sur forms_donnees_champs pour chacun des champs renseigné du formulaire et de n'en tirer que l'intersection des résultats (ce qui devient plus compliqué). :frowning:

Ci après exemples de log des requêtes SQL de la recherche.

Amicalement,
Philippe

SELECT forms_donnees.id_form, forms_donnees.id_donnee, donnees_champs.valeur AS id_mot
FROM `test`.spip_forms_donnees AS `forms_donnees`, `test`.spip_forms_donnees_champs AS `dc`, `test`.spip_forms_donnees_champs AS `donnees_champs`, `test`.spip_forms_champs AS `champs`
WHERE (forms_donnees.id_form = '3')
        AND (forms_donnees.confirmation = "valide")
        AND (forms_donnees.statut = "publie")
        AND (dc.champ='mot_1' AND dc.valeur='65') AND (dc.champ='mot_2' AND dc.valeur='89')
        AND (dc.id_donnee = forms_donnees.id_donnee)
        AND (forms_donnees.id_form = champs.id_form)
        AND (champs.type = "mot")
        AND (donnees_champs.champ = champs.champ)
        AND (donnees_champs.id_donnee = forms_donnees.id_donnee)
GROUP BY forms_donnees.id_donnee, forms_donnees.id_donnee
ORDER BY forms_donnees.rang

=> la condition dc.champ='mot_1' AND dc.champ='mot_2' ne peut aboutir !

SELECT forms_donnees.id_form, forms_donnees.id_donnee, donnees_champs.valeur AS id_mot
FROM `test`.spip_forms_donnees AS `forms_donnees`, `test`.spip_forms_donnees_champs AS `dc`, `test`.spip_forms_donnees_champs AS `donnees_champs`, `test`.spip_forms_champs AS `champs`
WHERE (forms_donnees.id_form = '3')
        AND (forms_donnees.confirmation = "valide")
        AND (forms_donnees.statut = "publie")
        AND (dc.champ='mot_1' AND dc.valeur='62') AND (dc.champ='mot_3' AND dc.valeur IN ('5','8'))
        AND (dc.id_donnee = forms_donnees.id_donnee)
        AND (forms_donnees.id_form = champs.id_form)
        AND (champs.type = "mot")
        AND (donnees_champs.champ = champs.champ)
        AND (donnees_champs.id_donnee = forms_donnees.id_donnee)
GROUP BY forms_donnees.id_donnee, forms_donnees.id_donnee
ORDER BY forms_donnees.rang

=> sur la condition (dc.champ='mot_3' AND dc.valeur IN ('5','8')) (champs multiples), le comportement logique est de bien de faire un OU entre les valeurs par le bien d'un IN.

Philippe Drouot a écrit :

cedric.morin@yterium.com a écrit :
  

....
Par ailleurs, le formulaire de recherche sur les tables applique un AND entre les conditions des champs (il faut que le champ 1 ait telle valeur ET le champ 2 telle valeur)
Mais, attention tout de meme, sur les champs de type multiple, cela reste un OU entre les valeurs du meme champ (champ 1 ait telle ou telle valeur ET champ 2 aie telle valeur)

Pour etendre le formulaire de recherche à tous les types de champs(select,multiple, mot par defaut) il suffit de personaliser formulaires/forms_recherche dans son dossier squelette)

- \$filtre .= " OR (dc.champ="._q(\$row['champ'])." AND dc.valeur IN (".implode(',',array_map('_q',\$r))."))";
+ \$filtre .= " AND (dc.champ="._q(\$row['champ'])." AND dc.valeur IN (".implode(',',array_map('_q',\$r))."))";
    

Bonjour,

Il me semble que transformer la recherche de OU en ET entre les champs d'un formulaire de recherche n'est pas si trivial : remplacer le OR par un AND entre les conditions ne marche que si on ne fait une recherche que sur UN SEUL champ du formulaire !

Dès lors que l'on spécifie plusieurs champs, on se retrouve avec des requêtes de type dc.champ='mot_1' AND dc.champ='mot_2' ce qui ne peut conduire à un résultat.
Il faudrait plutôt envisager de faire une requête sur forms_donnees_champs pour chacun des champs renseigné du formulaire et de n'en tirer que l'intersection des résultats (ce qui devient plus compliqué). :frowning:

Ci après exemples de log des requêtes SQL de la recherche.

Amicalement,
Philippe
  

Oui j'ai commité un peu trop vite :slight_smile:
Mais je vois que tu suis !
Je suis dessus la, du coup (ou comment se faire embarquer dans une modif que l'on pensait simple ...), et je l'ai presque.
Commit a venir !

Cedric