Changeset 117730 in spip-zone


Ignore:
Timestamp:
Sep 6, 2019, 4:36:44 PM (2 months ago)
Author:
maieul@…
Message:

mettre toute la partie de parsage des conditions dans une fonction à part

Location:
_plugins_/saisies/trunk/inc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/saisies/trunk/inc/saisies_afficher_si_commun.php

    r117729 r117730  
    66 *
    77 * @package SPIP\Saisies\Afficher_si_commun
     8 **/
     9
     10
     11/**
     12 * Reçoit une condition
     13 * la parse pour trouver champs/opérateurs/valeurs etc.
     14 * @param string $condition
     15 * @return array tableau d'analyse (resultat d'un preg_match_all) montrant sous condition par sous condition l'analyse en champ/opérateur/valeur etc.
    816**/
     17function saisies_parser_condition_afficher_si($condition) {
     18        $regexp =
     19          "(?<negation>!?)" // négation éventuelle
     20                . "(?:@(?<champ>.+?)@)" // @champ_@
     21                . "(" // partie operateur + valeur (optionnelle) : debut
     22                . "(?:\s*?)" // espaces éventuels après
     23                . "(?<operateur>==|!=|IN|!IN|>=|>|<=|<)" // opérateur
     24                . "(?:\s*?)" // espaces éventuels après
     25                . "((?<guillemet>\"|')(?<valeur>.*?)(\k<guillemet>)|(?<valeur_numerique>\d+))" // valeur (string) ou valeur_numérique (int)
     26                . ")?"; // partie operateur + valeur (optionnelle) : fin
     27        $regexp = "#$regexp#";
     28        preg_match_all($regexp, $condition, $tests, PREG_SET_ORDER);
     29        return $tests;
     30}
  • _plugins_/saisies/trunk/inc/saisies_afficher_si_php.php

    r117729 r117730  
    22
    33/**
    4  * Gestion de l'affichage conditionnelle des saisies
     4 * Gestion de l'affichage conditionnelle des saisies.
     5 * Partie spécifique php
    56 *
    6  * @package SPIP\Saisies\Afficher_si
     7 * @package SPIP\Saisies\Afficher_si_php
    78**/
    89
     
    1213}
    1314
    14 
    15 /**
    16  * Génère, à partir d'un tableau de saisie le code javascript ajouté à la fin de #GENERER_SAISIES
    17  * pour produire un affichage conditionnel des saisies ayant une option afficher_si
    18  *
    19  * @param array  $saisies
    20  *                        Tableau de descriptions des saisies
    21  * @param string $id_form
    22  *                        Identifiant unique pour le formulaire
    23  *
    24  * @return text
    25  *              Code javascript
    26  */
    27 function saisies_generer_js_afficher_si($saisies, $id_form) {
    28         $i = 0;
    29         $saisies = saisies_lister_par_nom($saisies, true);
    30         $code = '';
    31         $code .= "$(function(){\n\tchargement=true;\n";
    32         $code .= "\tverifier_saisies_".$id_form." = function(form){\n";
    33 
    34         if (!defined('_SAISIES_AFFICHER_SI_JS_SHOW')) {
    35                 define ('_SAISIES_AFFICHER_SI_JS_SHOW', 'show(400)');
    36         }
    37         if (!defined('_SAISIES_AFFICHER_SI_JS_HIDE')) {
    38                 define ('_SAISIES_AFFICHER_SI_JS_HIDE', 'hide(400)');
    39         }
    40         foreach ($saisies as $saisie) {
    41                 // on utilise comme selecteur l'identifiant de saisie en priorite s'il est connu
    42                 // parce que conteneur_class = 'tableau[nom][option]' ne fonctionne evidement pas
    43                 // lorsque le name est un tableau
    44                 if (isset($saisie['options']['afficher_si']) && trim($saisie['options']['afficher_si'])) {
    45                         ++$i;
    46                         // Les [] dans le nom de la saisie sont transformés en _ dans le
    47                         // nom de la classe, il faut faire pareil
    48                         $nom_underscore = rtrim(
    49                                         preg_replace('/[][]\[?/', '_', $saisie['options']['nom']),
    50                                         '_'
    51                         );
    52                         // retrouver la classe css probable
    53                         switch ($saisie['saisie']) {
    54                                 case 'fieldset':
    55                                         $class_li = 'fieldset_'.$nom_underscore;
    56                                         break;
    57                                 case 'explication':
    58                                         $class_li = 'explication_'.$nom_underscore;
    59                                         break;
    60                                 default:
    61                                         // Les [] dans le nom de la saisie sont transformés en _ dans le
    62                                         // nom de la classe, il faut faire pareil
    63                                         $class_li = 'editer_'.$nom_underscore;
    64                         }
    65                         $condition = trim($saisie['options']['afficher_si']);
    66                         // retrouver l'identifiant
    67                         $identifiant = '';
    68                         if (isset($saisie['identifiant']) and $saisie['identifiant']) {
    69                                 $identifiant = $saisie['identifiant'];
    70                         }
    71                         // On gère le cas @plugin:non_plugin@
    72                         preg_match_all('#@plugin:(.+)@#U', $condition, $matches);
    73                         foreach ($matches[1] as $plug) {
    74                                 if (defined('_DIR_PLUGIN_'.strtoupper($plug))) {
    75                                         $condition = preg_replace('#@plugin:'.$plug.'@#U', 'true', $condition);
    76                                 } else {
    77                                         $condition = preg_replace('#@plugin:'.$plug.'@#U', 'false', $condition);
    78                                 }
    79                         }
    80                         $condition = saisies_transformer_condition_afficher_si_config($condition);
    81                         // On transforme en une condition valide
    82                         preg_match_all('#@(.+)@#U', $condition, $matches);
    83                         foreach ($matches[1] as $nom) {
    84                                 switch ($saisies[$nom]['saisie']) {
    85                                         case 'radio':
    86                                         case 'oui_non':
    87                                         case 'true_false':
    88                                                 $condition = preg_replace('#@'.preg_quote($nom).'@#U', '$(form).find("[name=\''.$nom.'\']:checked").val()', $condition);
    89                                                 break;
    90                                         case 'case':
    91                                                 $condition = preg_replace('#@'.preg_quote($nom).'@#U', '($(form).find(".checkbox[name=\''.$nom.'\']").is(":checked") ? $(form).find(".checkbox[name=\''.$nom.'\']").val() : "")', $condition);
    92                                                 break;
    93                                         case 'checkbox':
    94                                                 /**
    95                                                  * Faire fonctionner @checkbox_xx@ == 'valeur' et @checkbox_xx@ != 'valeur'
    96                                                  */
    97                                                 $condition = preg_replace('#@(.+)@\s*(==|(!)=)\s*(\'[^\']*\'|"[^"]*")#U', "@$1@ $3IN $4", $condition );
    98                                                 /**
    99                                                  * Faire fonctionner @checkbox_xx@ IN 'valeur' ou @checkbox_xx@ !IN 'valeur'
    100                                                  */
    101                                                 preg_match_all('#@(.+)@\s*(!IN|IN)\s*[\'"](.*)[\'"]#U', $condition, $matches3);
    102                                                 foreach ($matches3[3] as $key => $value) {
    103                                                         $not = '';
    104                                                         if ($matches3[2][$key] == '!IN') {
    105                                                                 $not = '!';
    106                                                         }
    107                                                         $values = explode(',', $value);
    108                                                         $new_condition = $not.'(';
    109                                                         foreach ($values as $key2 => $cond) {
    110                                                                 if ($key2 > 0) {
    111                                                                         $new_condition .= ' || ';
    112                                                                 }
    113                                                                 $new_condition .= '($(form).find(".checkbox[name=\''.$nom.'[]\'][value='.$cond.']").is(":checked") ? $(form).find(".checkbox[name=\''.$nom.'[]\'][value='.$cond.']").val() : "") == "'.$cond.'"';
    114                                                         }
    115                                                         $new_condition .= ')';
    116                                                         $condition = str_replace($matches3[0][$key], $new_condition, $condition);
    117                                                 }
    118                                                 break;
    119                                         default:
    120                                                 $condition = preg_replace('#@'.preg_quote($nom).'@#U', '$(form).find("[name=\''.$nom.'\']").val()', $condition);
    121                                 }
    122                         }
    123                         if ($identifiant) {
    124                                 $sel = "[data-id='$identifiant']";
    125                         } else {
    126                                 $sel = ".$class_li";
    127                         }
    128                         $code .= "\tif (".$condition.") {\n"
    129                                                          .      "\t\t$(form).find(\"$sel\")."._SAISIES_AFFICHER_SI_JS_SHOW.".addClass('afficher_si_visible').removeClass('afficher_si_masque');\n";
    130                         if (html5_permis()) {
    131                         $code .=        "\t\t$(form).find(\"$sel [data-afficher-si-required]\").attr(\"required\",true).attr(\"data-afficher-si-required\",null);\n";
    132                         }
    133                         $code .=        "\t}\n";
    134                         $code .= "\telse {\n";
    135                         if (html5_permis()) {
    136                                 $code .= "\t\t$(form).find(\"$sel [required]\").attr(\"required\",false).attr(\"data-afficher-si-required\",true);\n";
    137                         }
    138                         $code .= "\t\tif (chargement==true) {\n"
    139                                         ."\t\t\t$(form).find(\"$sel\")."._SAISIES_AFFICHER_SI_JS_HIDE.".addClass('afficher_si_masque').removeClass('afficher_si_visible').css".'("display","none")'.";\n"
    140                                         ."\t\t}\n"
    141                                         ."\t\telse {\n"
    142                                         ."\t\t\t$(form).find(\"$sel\")."._SAISIES_AFFICHER_SI_JS_HIDE.".addClass('afficher_si_masque').removeClass('afficher_si_visible');\n"
    143                                         ."\t\t};\n"
    144                                         ."\t}\n";
    145                 }
    146         }
    147         $code .= "$(form).trigger('saisies_afficher_si_js_ok');\n";
    148         $code .= "};\n";
    149         $code .= "\t".'$("#afficher_si_'.$id_form.'").parents("form").each(function(){'."\n\t\t".'verifier_saisies_'.$id_form.'(this);});'."\n";
    150         $code .= "\t".'$("#afficher_si_'.$id_form.'").parents("form").change(function(){'."\n\t\t".'verifier_saisies_'.$id_form.'(this);});'."\n";
    151         $code .= "\tchargement=false;})\n";
    152 
    153         if (!defined('_SAISIES_AFFICHER_SI_JS_LISIBLE')) {
    154                 define('_SAISIES_AFFICHER_SI_JS_LISIBLE', false);
    155         }
    156         if (!_SAISIES_AFFICHER_SI_JS_LISIBLE) {
    157                 // il suffit de régler cette constante à TRUE pour afficher le js de manière plus lisible (et moins sibyllin)
    158                 $code = str_replace("\n", '', $code); //concatener
    159                 $code = str_replace("\t", '', $code); //concatener
    160         }
    161         return $i > 0 ? $code : '';
    162 }
     15include_spip('inc/saisies_afficher_si_commun');
    16316
    16417/**
     
    306159**/
    307160function saisies_transformer_condition_afficher_si($condition, $env = null) {
    308         $regexp =
    309           "(?<negation>!?)" // négation éventuelle
    310                 . "(?:@(?<champ>.+?)@)" // @champ_@
    311                 . "(" // partie operateur + valeur (optionnelle) : debut
    312                 . "(?:\s*?)" // espaces éventuels après
    313                 . "(?<operateur>==|!=|IN|!IN|>=|>|<=|<)" // opérateur
    314                 . "(?:\s*?)" // espaces éventuels après
    315                 . "((?<guillemet>\"|')(?<valeur>.*?)(\k<guillemet>)|(?<valeur_numerique>\d+))" // valeur (string) ou valeur_numérique (int)
    316                 . ")?"; // partie operateur + valeur (optionnelle) : fin
    317         $regexp = "#$regexp#";
    318         if (preg_match_all($regexp, $condition, $tests, PREG_SET_ORDER)) {
    319                 if (!saisies_afficher_si_secure($condition, $tests)) {
    320                         spip_log("Afficher_si incorrect. $condition non sécurisée", "saisies"._LOG_CRITIQUE);
    321                         return '';
    322                 }
     161        if ($tests = saisies_parser_condition_afficher_si($condition)) {
    323162                foreach ($tests as $test) {
    324163                        $expression = $test[0];
Note: See TracChangeset for help on using the changeset viewer.