[SPIP Zone] spip-bonux : bug embêtant avec les boucles conditions

préambule :
spip 2.0.8 rev 13982
spip bonux 1.8 rev 28778

Je ne sais pas si quelqu'un a déjà rencontré ce(s) bug(s).

- dans certaines conditions que je n'ai pas réussi à identifier, certaines boucles sont détectées comme (condition) quand je fais var_profile alors qu'elles n'en sont pas.
    Elles ne génèrent et n'exécutent donc pas leur requête sql, impossible de savoir pourquoi.
    Comme je l'ai dit, je n'ai pas réussi à identifier le déclencheur exact car si on isole ces boucles dans un squelette à part, le comportement ne se reproduit pas,
    mais je soupçonne que c'est lié d'une manière ou d'une autre à la présence de ces boucles dans une boucle parente (CONDITION) ou sa partie alternative.
    Ca semble aussi arriver plus souvent quand une des valeurs testées dans un critère est vide (mais pas toujours, voir deuxième exemple)

    Deux exemples :
               - une requête un peu compliquée pour un cas un peu compliqué ; mais bon, ça devrait marcher, et ça marchait en 1.9.2
          (à #NOW près, le supprimer ne change rien)
          L'appel qui fait foirer utilise une valeur vide pour #GET{mot_groupe}, je n'ai pas réussi à le reproduire avec d'autres valeurs
          (ça ne plante pas quand j'isole la boucle de son contexte)
          contexte : elle est dans le //B d'une boucle condition qui teste {si #ENV{static_page} |!={''}}

            01 <BOUCLE_mot_publication_numero(MOTS){type=Publications}{descriptif=#GET{mot_groupe}}>
            02 <BOUCLE_check_articles_numero(ARTICLES){id_mot=#ENV{id_mot}}{lang=#GET{autre_langue}}{0,1}{date<#NOW}>
            03 #SET{url,#GET{mot_url}}
            04 </BOUCLE_check_articles_numero>
            05 </BOUCLE_mot_publication_numero>

          Le code php généré :
            02 function BOUCLE_mot_publication_numerohtmlcondition_75c6a3802406a2fe4a5bb2518e81e29f(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {
            03 04 static $connect = 'condition'; //***je suppose que le symptôme est là***
            05 static $table = 'mots';
            06 static $id = '_mot_publication_numero';
            07 static $from = array('mots' => 'spip_mots');
            08 static $type = array();
            09 static $groupby = array();
            10 static $select = array("1");
            11 static $orderby = array();
            12 $where =
            13 array(
            14 array('=', 'mots.type',
            15 // 12 signes
            16 "'Publications'"),
            17 array('=', 'mots.descriptif', sql_quote(
            18 // #GET
            19 (is_array($a = ($Pile["vars"])) ? $a[
            20 // 10 signes
            21 'mot_groupe'] : ""))));
            22 static $join = array();
            23 static $limit = '';
            24 static $having =
            25 array();
            26 // REQUETE
            27 $result = calculer_select($select, $from, $type, $where, $join, $groupby, $orderby, $limit, $having, $table, $id, $connect);
            28 $t0 = "";
            29 $SP++;
            30
            31 // RESULTATS
            32 while ($Pile[$SP] = @sql_fetch($result, 'condition')) {
            33
            34 $t0 .= (
            35
            36 // 8 signes
            37 '
            38 ' .
            39
            40 // ?_check_articles_numero
            41 BOUCLE_check_articles_numerohtmlcondition_75c6a3802406a2fe4a5bb2518e81e29f($Cache, $Pile, $doublons, $Numrows, $SP) .
            42
            43 // 7 signes
            44 '
            45 ');
            46 }
            47
            48 @sql_free($result, 'condition');
            49 return $t0;
            50 }

        - deuxième exemple sur une boucle du plugin spip-lettres d'artego (qui fonctionne très bien par ailleurs),
          L'appel utilisait un id_theme valant 16, #SET doit normalement mettre rub à 898 dans mon cas
          (la structure de la table spip_themes est : "id_theme,id_rubrique,titre,lang")
          Là encore la boucle est dans le //B de la même condition

            <BOUCLE_theme(THEMES){id_theme=#ENV{id_theme}}>
                <BOUCLE_recup_rubrique_newsletter(RUBRIQUES){id_rubrique}{!lang_select}>
                    #SET{rub,#ID_RUBRIQUE}
                </BOUCLE_recup_rubrique_newsletter>
            </BOUCLE_theme>

          génère le code suivant :
             01 <?php
            02 function BOUCLE_themehtmlcondition_75c6a3802406a2fe4a5bb2518e81e29f(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {
            03
            04 static $connect = 'condition'; //***là encore***
            05 static $table = 'themes';
            06 static $id = '_theme';
            07 static $from = array('themes' => 'spip_themes');
            08 static $type = array();
            09 static $groupby = array();
            10 static $select = array("themes.id_rubrique");
            11 static $orderby = array();
            12 $where =
            13 array(
            14 array('=', 'themes.id_theme', sql_quote(
            15 // #ENV
            16 interdire_scripts(entites_html((@$Pile[0][
            17 // 8 signes
            18 'id_theme']),true)))));
            19 static $join = array();
            20 static $limit = '';
            21 static $having =
            22 array();
            23 // REQUETE
            24 $result = calculer_select($select, $from, $type, $where, $join, $groupby, $orderby, $limit, $having, $table, $id, $connect);
            25 $t0 = "";
            26 $SP++;
            27
            28 // RESULTATS
            29 while ($Pile[$SP] = @sql_fetch($result, 'condition')) {
            30
            31 $t0 .= (
            32
            33 // 6 signes
            34 '
            35 ' .
            36
            37 // ?_recup_rubrique_newsletter
            38 BOUCLE_recup_rubrique_newsletterhtmlcondition_75c6a3802406a2fe4a5bb2518e81e29f($Cache, $Pile, $doublons, $Numrows, $SP) .
            39
            40 // 5 signes
            41 '
            42 ');
            43 }
            44
            45 @sql_free($result, 'condition');
            46 return $t0;
            47 }
            48
            49
            50 ?>

    J'ai aussi remarqué que les boucles (condition) ont tendance à altérer le contexte local :
    <BOUCLE_rub(RUBRIQUES){id_rubrique}>
       <BOUCLE_test(CONDITION){si... }>
         <INCLURE{fond=x}{id_rubrique}>
       </BOUCLE_test>
    </BOUCLE_rub>
    => je n'ai pas réussi à pondre un exemple qui provoque le bug à 100% mais dans certains cas, le squelette inclus x ne reçoit pas id_rubrique, on est obligé de le lui passer explicitement par #SET #GET d'une variable pour contourner la (condition)

Quelqu'un a déjà rencontré ce genre de trucs ? Est-ce qu'il y a des moyens de les contourner ?

Simon

Evidemment, il suffit que je me décide à poster après des heures de recherche pour que je trouve instantanément la raison, donc je m'auto-réponds :

    Le problème venait du fait que le squelette contenant ce code était inclus en utilisant #INCLURE à l'intérieur dune boucle CONDITION.
    Le passage sur <INCLURE> corrige le souci.

Verdict : *ne pas utiliser #INCLURE dans les boucles CONDITION tant que c'est pas réparé*

Simon

Simon Camerlo a écrit :

préambule :
spip 2.0.8 rev 13982
spip bonux 1.8 rev 28778

Je ne sais pas si quelqu'un a déjà rencontré ce(s) bug(s).

- dans certaines conditions que je n'ai pas réussi à identifier, certaines boucles sont détectées comme (condition) quand je fais var_profile alors qu'elles n'en sont pas.
   Elles ne génèrent et n'exécutent donc pas leur requête sql, impossible de savoir pourquoi.
   Comme je l'ai dit, je n'ai pas réussi à identifier le déclencheur exact car si on isole ces boucles dans un squelette à part, le comportement ne se reproduit pas,
   mais je soupçonne que c'est lié d'une manière ou d'une autre à la présence de ces boucles dans une boucle parente (CONDITION) ou sa partie alternative.
   Ca semble aussi arriver plus souvent quand une des valeurs testées dans un critère est vide (mais pas toujours, voir deuxième exemple)

   Deux exemples :
             - une requête un peu compliquée pour un cas un peu compliqué ; mais bon, ça devrait marcher, et ça marchait en 1.9.2
         (à #NOW près, le supprimer ne change rien)
         L'appel qui fait foirer utilise une valeur vide pour #GET{mot_groupe}, je n'ai pas réussi à le reproduire avec d'autres valeurs
         (ça ne plante pas quand j'isole la boucle de son contexte)
         contexte : elle est dans le //B d'une boucle condition qui teste {si #ENV{static_page} |!={''}}

           01 <BOUCLE_mot_publication_numero(MOTS){type=Publications}{descriptif=#GET{mot_groupe}}>

           02 <BOUCLE_check_articles_numero(ARTICLES){id_mot=#ENV{id_mot}}{lang=#GET{autre_langue}}{0,1}{date<#NOW}>

           03 #SET{url,#GET{mot_url}}
           04 </BOUCLE_check_articles_numero>
           05 </BOUCLE_mot_publication_numero>

         Le code php généré :
           02 function BOUCLE_mot_publication_numerohtmlcondition_75c6a3802406a2fe4a5bb2518e81e29f(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {
           03 04 static $connect = 'condition'; //***je suppose que le symptôme est là***
           05 static $table = 'mots';
           06 static $id = '_mot_publication_numero';
           07 static $from = array('mots' => 'spip_mots');
           08 static $type = array();
           09 static $groupby = array();
           10 static $select = array("1");
           11 static $orderby = array();
           12 $where =
           13 array(
           14 array('=', 'mots.type',
           15 // 12 signes
           16 "'Publications'"),
           17 array('=', 'mots.descriptif', sql_quote(
           18 // #GET
           19 (is_array($a = ($Pile["vars"])) ? $a[
           20 // 10 signes
           21 'mot_groupe'] : ""))));
           22 static $join = array();
           23 static $limit = '';
           24 static $having =
           25 array();
           26 // REQUETE
           27 $result = calculer_select($select, $from, $type, $where, $join, $groupby, $orderby, $limit, $having, $table, $id, $connect);
           28 $t0 = "";
           29 $SP++;
           30
           31 // RESULTATS
           32 while ($Pile[$SP] = @sql_fetch($result, 'condition')) {
           33
           34 $t0 .= (
           35
           36 // 8 signes
           37 '
           38 ' .
           39
           40 // ?_check_articles_numero
           41 BOUCLE_check_articles_numerohtmlcondition_75c6a3802406a2fe4a5bb2518e81e29f($Cache, $Pile, $doublons, $Numrows, $SP) .
           42
           43 // 7 signes
           44 '
           45 ');
           46 }
           47
           48 @sql_free($result, 'condition');
           49 return $t0;
           50 }

       - deuxième exemple sur une boucle du plugin spip-lettres d'artego (qui fonctionne très bien par ailleurs),
         L'appel utilisait un id_theme valant 16, #SET doit normalement mettre rub à 898 dans mon cas
         (la structure de la table spip_themes est : "id_theme,id_rubrique,titre,lang")
         Là encore la boucle est dans le //B de la même condition

           <BOUCLE_theme(THEMES){id_theme=#ENV{id_theme}}>
               <BOUCLE_recup_rubrique_newsletter(RUBRIQUES){id_rubrique}{!lang_select}>
                   #SET{rub,#ID_RUBRIQUE}
               </BOUCLE_recup_rubrique_newsletter>
           </BOUCLE_theme>

         génère le code suivant :
            01 <?php
           02 function BOUCLE_themehtmlcondition_75c6a3802406a2fe4a5bb2518e81e29f(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {
           03
           04 static $connect = 'condition'; //***là encore***
           05 static $table = 'themes';
           06 static $id = '_theme';
           07 static $from = array('themes' => 'spip_themes');
           08 static $type = array();
           09 static $groupby = array();
           10 static $select = array("themes.id_rubrique");
           11 static $orderby = array();
           12 $where =
           13 array(
           14 array('=', 'themes.id_theme', sql_quote(
           15 // #ENV
           16 interdire_scripts(entites_html((@$Pile[0][
           17 // 8 signes
           18 'id_theme']),true)))));
           19 static $join = array();
           20 static $limit = '';
           21 static $having =
           22 array();
           23 // REQUETE
           24 $result = calculer_select($select, $from, $type, $where, $join, $groupby, $orderby, $limit, $having, $table, $id, $connect);
           25 $t0 = "";
           26 $SP++;
           27
           28 // RESULTATS
           29 while ($Pile[$SP] = @sql_fetch($result, 'condition')) {
           30
           31 $t0 .= (
           32
           33 // 6 signes
           34 '
           35 ' .
           36
           37 // ?_recup_rubrique_newsletter
           38 BOUCLE_recup_rubrique_newsletterhtmlcondition_75c6a3802406a2fe4a5bb2518e81e29f($Cache, $Pile, $doublons, $Numrows, $SP) .
           39
           40 // 5 signes
           41 '
           42 ');
           43 }
           44
           45 @sql_free($result, 'condition');
           46 return $t0;
           47 }
           48
           49
           50 ?>

   J'ai aussi remarqué que les boucles (condition) ont tendance à altérer le contexte local :
   <BOUCLE_rub(RUBRIQUES){id_rubrique}>
      <BOUCLE_test(CONDITION){si... }>
        <INCLURE{fond=x}{id_rubrique}>
      </BOUCLE_test>
   </BOUCLE_rub>
   => je n'ai pas réussi à pondre un exemple qui provoque le bug à 100% mais dans certains cas, le squelette inclus x ne reçoit pas id_rubrique, on est obligé de le lui passer explicitement par #SET #GET d'une variable pour contourner la (condition)

Quelqu'un a déjà rencontré ce genre de trucs ? Est-ce qu'il y a des moyens de les contourner ?

Simon

Le 29 juil. 09 à 10:34, Simon Camerlo a écrit :

Evidemment, il suffit que je me décide à poster après des heures de recherche pour que je trouve instantanément la raison, donc je m'auto-réponds :

  Le problème venait du fait que le squelette contenant ce code était inclus en utilisant #INCLURE à l'intérieur dune boucle CONDITION.
  Le passage sur <INCLURE> corrige le souci.

Verdict : *ne pas utiliser #INCLURE dans les boucles CONDITION tant que c'est pas réparé*

Ah oui on avait dit que c'etait une mauvaise idée, il faut que je revert cette transmission automatique...

Cédric

Ah ben je comprend mieux pourquoi ça ne marchait pas chez moi! Je me suis arraché les cheveux pendant des heures! Je me disais que je ne codais pas si mal que ça mais ça merdait toujours! Arf! Les bugs!

Le 29 juillet 2009 11:00, cedric.morin@yterium.com <cedric.morin@yterium.com> a écrit :

Le 29 juil. 09 à 10:34, Simon Camerlo a écrit :

Evidemment, il suffit que je me décide à poster après des heures de recherche pour que je trouve instantanément la raison, donc je m’auto-réponds :

Le problème venait du fait que le squelette contenant ce code était inclus en utilisant #INCLURE à l’intérieur dune boucle CONDITION.
Le passage sur corrige le souci.

Verdict : ne pas utiliser #INCLURE dans les boucles CONDITION tant que c’est pas réparé

Ah oui on avait dit que c’etait une mauvaise idée, il faut que je revert cette transmission automatique…

Cédric


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