Changeset 113006 in spip-zone


Ignore:
Timestamp:
Dec 21, 2018, 12:01:27 AM (3 months ago)
Author:
maieul@…
Message:

avant d'aller plus loin, on met dans un fichier a part tout ce qui est gestion des afficher_si

Location:
_plugins_/saisies/trunk
Files:
3 edited
1 copied

Legend:

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

    r112927 r113006  
    2020// Les outils pour afficher les saisies et leur vue
    2121include_spip('inc/saisies_afficher');
     22
     23// Les outils pour l'affichage conditionnelle des saisies
     24include_spip('inc/saisies_afficher_si');
    2225
    2326/**
  • _plugins_/saisies/trunk/inc/saisies_afficher.php

    r113005 r113006  
    308308}
    309309
    310 /**
    311  * Génère, à partir d'un tableau de saisie le code javascript ajouté à la fin de #GENERER_SAISIES
    312  * pour produire un affichage conditionnel des saisies ayant une option afficher_si
    313  *
    314  * @param array  $saisies
    315  *                        Tableau de descriptions des saisies
    316  * @param string $id_form
    317  *                        Identifiant unique pour le formulaire
    318  *
    319  * @return text
    320  *              Code javascript
    321  */
    322 function saisies_generer_js_afficher_si($saisies, $id_form) {
    323         $i = 0;
    324         $saisies = saisies_lister_par_nom($saisies, true);
    325         $code = '';
    326         $code .= "$(function(){\n\tchargement=true;\n";
    327         $code .= "\tverifier_saisies_".$id_form." = function(form){\n";
    328         foreach ($saisies as $saisie) {
    329                 // on utilise comme selecteur l'identifiant de saisie en priorite s'il est connu
    330                 // parce que conteneur_class = 'tableau[nom][option]' ne fonctionne evidement pas
    331                 // lorsque le name est un tableau
    332                 if (isset($saisie['options']['afficher_si'])) {
    333                         ++$i;
    334                         // Les [] dans le nom de la saisie sont transformés en _ dans le
    335                         // nom de la classe, il faut faire pareil
    336                         $nom_underscore = rtrim(
    337                                         preg_replace('/[][]\[?/', '_', $saisie['options']['nom']),
    338                                         '_'
    339                         );
    340                         // retrouver la classe css probable
    341                         switch ($saisie['saisie']) {
    342                                 case 'fieldset':
    343                                         $class_li = 'fieldset_'.$nom_underscore;
    344                                         break;
    345                                 case 'explication':
    346                                         $class_li = 'explication_'.$nom_underscore;
    347                                         break;
    348                                 default:
    349                                         // Les [] dans le nom de la saisie sont transformés en _ dans le
    350                                         // nom de la classe, il faut faire pareil
    351                                         $class_li = 'editer_'.$nom_underscore;
    352                         }
    353                         $condition = isset($saisie['options']['afficher_si']) ? $saisie['options']['afficher_si'] : '';
    354                         // retrouver l'identifiant
    355                         $identifiant = '';
    356                         if (isset($saisie['identifiant']) and $saisie['identifiant']) {
    357                                 $identifiant = $saisie['identifiant'];
    358                         }
    359                         // On gère le cas @plugin:non_plugin@
    360                         preg_match_all('#@plugin:(.+)@#U', $condition, $matches);
    361                         foreach ($matches[1] as $plug) {
    362                                 if (defined('_DIR_PLUGIN_'.strtoupper($plug))) {
    363                                         $condition = preg_replace('#@plugin:'.$plug.'@#U', 'true', $condition);
    364                                 } else {
    365                                         $condition = preg_replace('#@plugin:'.$plug.'@#U', 'false', $condition);
    366                                 }
    367                         }
    368                         // On gère le cas @config:plugin:meta@ suivi d'un test
    369                         preg_match_all('#@config:(.+):(.+)@#U', $condition, $matches);
    370                         foreach ($matches[1] as $plugin) {
    371                                 $config = lire_config($plugin);
    372                                 $condition = preg_replace('#@config:'.$plugin.':'.$matches[2][0].'@#U', '"'.$config[$matches[2][0]].'"', $condition);
    373                         }
    374                         // On transforme en une condition valide
    375                         preg_match_all('#@(.+)@#U', $condition, $matches);
    376                         foreach ($matches[1] as $nom) {
    377                                 switch ($saisies[$nom]['saisie']) {
    378                                         case 'radio':
    379                                         case 'oui_non':
    380                                         case 'true_false':
    381                                                 $condition = preg_replace('#@'.preg_quote($nom).'@#U', '$(form).find("[name=\''.$nom.'\']:checked").val()', $condition);
    382                                                 break;
    383                                         case 'case':
    384                                                 $condition = preg_replace('#@'.preg_quote($nom).'@#U', '($(form).find(".checkbox[name=\''.$nom.'\']").is(":checked") ? $(form).find(".checkbox[name=\''.$nom.'\']").val() : "")', $condition);
    385                                                 break;
    386                                         case 'checkbox':
    387                                                 /**
    388                                                  * Faire fonctionner @checkbox_xx@ == 'valeur' et @checkbox_xx@ != 'valeur'
    389                                                  */
    390                                                 $condition = preg_replace('#@(.+)@\s*(==|(!)=)\s*(\'[^\']*\'|"[^"]*")#U', "@$1@ $3IN $4", $condition );
    391                                                 /**
    392                                                  * Faire fonctionner @checkbox_xx@ IN 'valeur' ou @checkbox_xx@ !IN 'valeur'
    393                                                  */
    394                                                 preg_match_all('#@(.+)@\s*(!IN|IN)\s*[\'"](.*)[\'"]#U', $condition, $matches3);
    395                                                 foreach ($matches3[3] as $key => $value) {
    396                                                         $not = '';
    397                                                         if ($matches3[2][$key] == '!IN') {
    398                                                                 $not = '!';
    399                                                         }
    400                                                         $values = explode(',', $value);
    401                                                         $new_condition = $not.'(';
    402                                                         foreach ($values as $key2 => $cond) {
    403                                                                 if ($key2 > 0) {
    404                                                                         $new_condition .= ' || ';
    405                                                                 }
    406                                                                 $new_condition .= '($(form).find(".checkbox[name=\''.$nom.'[]\'][value='.$cond.']").is(":checked") ? $(form).find(".checkbox[name=\''.$nom.'[]\'][value='.$cond.']").val() : "") == "'.$cond.'"';
    407                                                         }
    408                                                         $new_condition .= ')';
    409                                                         $condition = str_replace($matches3[0][$key], $new_condition, $condition);
    410                                                 }
    411                                                 break;
    412                                         default:
    413                                                 $condition = preg_replace('#@'.preg_quote($nom).'@#U', '$(form).find("[name=\''.$nom.'\']").val()', $condition);
    414                                 }
    415                         }
    416                         if ($identifiant) {
    417                                 $sel = "[data-id='$identifiant']";
    418                         } else {
    419                                 $sel = ".$class_li";
    420                         }
    421                         $code .= "\tif (".$condition.") {\n"
    422                                                          .      "\t\t$(form).find(\"$sel\").show(400);\n";
    423                         if (html5_permis()) {
    424                         $pour_html_5 =  "$sel.obligatoire > input, "// si le afficher_si porte directement sur le input
    425                                                         ."$sel .obligatoire > input, "// si le afficher_si porte sur le fieldset
    426                                                         ."$sel.obligatoire > textarea, "// si le afficher_si porte directement sur le textearea
    427                                                         ."$sel .obligatoire > textarea, "// si le afficher_si porte sur le fiedset
    428                                                         ."$sel.obligatoire > select, "//si le afficher_si porte directement sur le select
    429                                                         ."$sel .obligatoire > select";//si le afficher_si porte sur le fieldset
    430                         $code .=        "\t\t$(form).find("
    431                                                         .'"'."$pour_html_5\")".
    432                                                         ".attr(\"required\",true);\n";
    433                         }
    434                         $code .=        "\t}\n";
    435                         $code .= "\telse {\n";
    436                         if (html5_permis()) {
    437                                 $code .= "\t\t$(form).find(\n\t\t\t"
    438                                                         .'"'."$pour_html_5\")\n"
    439                                                         ."\t\t.attr(".'"required"'.",false);\n";
    440                         }
    441                         $code .= "\t\tif (chargement==true) {\n"
    442                                         ."\t\t\t$(form).find(\"$sel\").hide(400).css".'("display","none")'.";\n"
    443                                         ."\t\t}\n"
    444                                         ."\t\telse {\n"
    445                                         ."\t\t\t$(form).find(\"$sel\").hide(400);\n"
    446                                         ."\t\t};\n"
    447                                         ."\t}\n";
    448                 }
    449         }
    450         $code .= "$(form).trigger('saisies_afficher_si_js_ok');\n";
    451         $code .= "};\n";
    452         $code .= "\t".'$("#afficher_si_'.$id_form.'").parents("form").each(function(){'."\n\t\t".'verifier_saisies_'.$id_form.'(this);});'."\n";
    453         $code .= "\t".'$("#afficher_si_'.$id_form.'").parents("form").change(function(){'."\n\t\t".'verifier_saisies_'.$id_form.'(this);});'."\n";
    454         $code .= "\tchargement=false;})\n";
    455 
    456         if (!defined('_SAISIES_AFFICHER_SI_JS_LISIBLE')) {
    457                 define('_SAISIES_AFFICHER_SI_JS_LISIBLE', false);
    458         }
    459         if (!_SAISIES_AFFICHER_SI_JS_LISIBLE) {
    460                 // il suffit de régler cette constante à TRUE pour afficher le js de manière plus lisible (et moins sibyllin)
    461                 $code = str_replace("\n", '', $code); //concatener
    462                 $code = str_replace("\t", '', $code); //concatener
    463         }
    464         return $i > 0 ? $code : '';
    465 }
    466 
    467 /**
    468  * Lorsque l'on affiche les saisies (#VOIR_SAISIES), les saisies ayant une option afficher_si
    469  * et dont les conditions ne sont pas remplies doivent être retirées du tableau de saisies.
    470  *
    471  * Cette fonction sert aussi lors de la vérification des saisies avec saisies_verifier().
    472  * À ce moment là, les saisies non affichées sont retirées de _request
    473  * (on passe leur valeur à NULL).
    474  *
    475  * @param array      $saisies
    476  *                            Tableau de descriptions de saisies
    477  * @param array|null $env
    478  *                            Tableau d'environnement transmis dans inclure/voir_saisies.html,
    479  *                            NULL si on doit rechercher dans _request (pour saisies_verifier()).
    480  *
    481  * @return array
    482  *               Tableau de descriptions de saisies
    483  */
    484 function saisies_verifier_afficher_si($saisies, $env = null) {
    485         // eviter une erreur par maladresse d'appel :)
    486         if (!is_array($saisies)) {
    487                 return array();
    488         }
    489         foreach ($saisies as $cle => $saisie) {
    490                 if (isset($saisie['options']['afficher_si'])) {
    491                         $condition = $saisie['options']['afficher_si'];
    492                         // Si tentative de code malicieux, on rejete
    493                         if (!saisies_verifier_securite_afficher_si($condition)) {
    494                                 spip_log("Afficher_si malicieuse : $condition", "saisies"._LOG_CRITIQUE);
    495                                 $condition = '$ok';
    496                         }
    497                         // Est-ce uniquement au remplissage?
    498                         if (isset($saisie['options']['afficher_si_remplissage_uniquement'])
    499                                 and $saisie['options']['afficher_si_remplissage_uniquement']=='on'){
    500                                 $remplissage_uniquement = true;
    501                         } else {
    502                                 $remplissage_uniquement = false;
    503                         }
    504 
    505                         // On gère le cas @plugin:non_plugin@
    506                         preg_match_all('#@plugin:(.+)@#U', $condition, $matches);
    507                         foreach ($matches[1] as $plug) {
    508                                 if (defined('_DIR_PLUGIN_'.strtoupper($plug))) {
    509                                         $condition = preg_replace('#@plugin:'.$plug.'@#U', 'true', $condition);
    510                                 } else {
    511                                         $condition = preg_replace('#@plugin:'.$plug.'@#U', 'false', $condition);
    512                                 }
    513                         }
    514                         // On gère le cas @config:plugin:meta@ suivi d'un test
    515                         preg_match_all('#@config:(.+):(.+)@#U', $condition, $matches);
    516                         foreach ($matches[1] as $plugin) {
    517                                 $config = lire_config($plugin);
    518                                 $condition = preg_replace('#@config:'.$plugin.':'.$matches[2][0].'@#U', '"'.$config[$matches[2][0]].'"', $condition);
    519                         }
    520                         // On transforme en une condition PHP valide
    521                         $condition_originale = $condition;
    522                         if (is_null($env)) {
    523                                 $condition = preg_replace('#@(.+)@#U', '_request(\'$1\')', $condition);
    524                         } else {
    525                                 $condition = preg_replace('#@(.+)@#U', '$env["valeurs"][\'$1\']', $condition);
    526                         }
    527                         /**
    528                          * Tester si la condition utilise des champs qui sont des tableaux
    529                          * Si _request() ou $env["valeurs"] est un tableau, changer == et != par in_array et !in_array
    530                          * TODO: c'est vraiment pas terrible comme fonctionnement
    531                          */
    532                         preg_match_all('/(_request\([\'"].*?[\'"]\)|\$env\[[\'"].*?[\'"]\]\[[\'"].*?[\'"]\])\s*(!=|==|IN|!IN)\s*[\'"](.*?)[\'"]/', $condition, $matches);
    533                         foreach ($matches[1] as $key => $val) {
    534                                 eval('$requete = '.$val.';');
    535                                 //Pour eviter une fatale erreur si on évalue une chose qui devrait normalement être un tableau mais qui n'a pas été envoyé (type checkbox), si la chose en question est null, la transformer en tableau vide. Pareil c'est pas terrible.
    536                                 if (is_null($requete)) {
    537                                         $requete = array();
    538                                         //C'est un request, alors on va faire un set_request
    539                                         if (strpos($val, '_request') === 0) {
    540                                                 $set_tableau = "set$val";
    541                                                 $set_tableau = str_replace(")",",array())",$set_tableau);
    542                                         } elseif (strpos($val, '$env') === 0) {//C'est un tablau direct
    543                                                 $set_tableau = ("$val = array()");
    544                                         }
    545                                         if (isset($set_tableau)) {
    546                                                 eval("$set_tableau;");
    547                                         }
    548                                 }
    549                                 if (is_array($requete)) {
    550                                         $not = '>';
    551                                         if (in_array($matches[2][$key], array('!=', '!IN'))) {
    552                                                 $not = '==';
    553                                         }
    554                                         $array = var_export(explode(',', $matches[3][$key]), true);
    555                                         $condition = str_replace($matches[0][$key], "(count(array_intersect($val, $array)) $not 0)", $condition);
    556                                 }
    557                         }
    558                         // On vérifie que l'on a pas @toto@="valeur" qui fait planter l'eval(),
    559                         // on annule cette condition dans ce cas pour éviter une erreur du type :
    560                         // PHP Fatal error:  Can't use function return value in write context
    561                         $type_condition = preg_replace('#@(.+)@#U', '', $condition_originale);
    562                         if (trim($type_condition) != '=') {
    563                                 eval('$ok = '.$condition.';');
    564                         }
    565                         if (!$ok) {
    566                                 if ($remplissage_uniquement == false or is_null($env)) {
    567                                         unset($saisies[$cle]);
    568                                 }
    569                                 if (is_null($env)) {
    570                                         saisies_set_request_null_recursivement($saisie);
    571                                 }
    572                         }
    573                 }
    574                 if (isset($saisies[$cle]['saisies'])) {
    575                         // S'il s'agit d'un fieldset ou equivalent, verifier les sous-saisies
    576                         $saisies[$cle]['saisies'] = saisies_verifier_afficher_si($saisies[$cle]['saisies'], $env);
    577                 }
    578         }
    579 
    580         return $saisies;
    581 }
    582 
    583 
    584 /**
    585  * Pose un set_request null sur une saisie et toute ses sous-saisies.
    586  * Utiliser notamment pour annuler toutes les sous saisies d'un fieldeset
    587  * si le fieldset est masquée à cause d'un afficher_si.
    588  * @param array $saisie
    589 **/
    590 function saisies_set_request_null_recursivement($saisie) {
    591         set_request($saisie['options']['nom'], null);
    592         if (isset($saisie['saisies'])) {
    593                 foreach ($saisie['saisies'] as $sous_saisie) {
    594                         saisies_set_request_null_recursivement($sous_saisie);
    595                 }
    596         }
    597 }
    598 
    599 /**
    600  * Vérifie qu'on tente pas de faire executer du code PHP en utilisant afficher_si.
    601  * N'importe quoi autorisé entre @@ et "" et ''
    602  * Liste de mot clé autorisé en dehors
    603  * @param string $condition
    604  * @return bool true si usage légitime, false si tentative d'execution de code PHP
    605  */
    606 function saisies_verifier_securite_afficher_si($condition) {
    607         $autoriser_hors_guillemets = array("!", "IN", "\(", "\)", "=", "\s", "&&", "\|\|");
    608         $autoriser_hors_guillemets = "#(".implode($autoriser_hors_guillemets, "|").")#m";
    609 
    610         $entre_guillemets = "#(?<guillemet>(^\\\)?(\"|'|@))(.*)(\k<guillemet>)#mU"; // trouver tout ce qu'il y entre guillemet, sauf si les guillemets sont échapés
    611         $condition = preg_replace($entre_guillemets, "", $condition);//Supprimer tout ce qu'il y a entre guillement
    612         $condition = preg_replace($autoriser_hors_guillemets, "", $condition);//Supprimer tout ce qui est autorisé hors guillemets
    613         if ($condition) {//S'il restre quelque chose, c'est pas normal
    614                 return false;
    615         }
    616         //Sinon c'est que c'est bon
    617         return true;
    618 }
    619 
    620 /**
    621  * Teste une condition d'afficher_si
    622  * @param string|array champ le champ à tester. Cela peut être :
    623  *      - un string
    624  *      - un tableau
    625  *      - un tableau sérializé
    626  * @param string $operateur : l'opérateur:
    627  *      - IN
    628  *      - !IN
    629  *      - ==
    630  *      - !=
    631  *      @param string $valeur la valeur à tester pour un IN. Par exemple "23" ou encore "23", "25"
    632  * @return booleen false / true selon la condition
    633  **/
    634 function saisies_tester_condition_afficher_si($champ, $operateur, $valeur) {
    635         // Dans tous les cas, enlever les guillemets qui sont au sein de valeur
    636         $valeur = str_replace("'", "", $valeur);
    637         $valeur = str_replace('"', "", $valeur);
    638 
    639         //Si champ est de type string, tenter d'unserializer
    640         $tenter_unserialize = @unserialize($champ);
    641         if ($tenter_unserialize)  {
    642                 $champ = $tenter_unserialize;
    643         }
    644 
    645         //Et maintenant appeler les sous fonctions qui vont bien
    646         if (is_string($champ)) {
    647                 return saisies_tester_condition_afficher_si_string($champ, $operateur, $valeur);
    648         }  elseif (is_array($champ)) {
    649                 return saisies_tester_condition_afficher_si_array($champ, $operateur, $valeur);
    650         } else {
    651                 return false;
    652         }
    653 }
    654 
    655 
    656 
    657 function saisies_tester_condition_afficher_si_string($champ, $operateur, $valeur) {
    658         if ($operateur == "==") {
    659                 return $champ == $valeur;
    660         } elseif ($operateur == "!=") {
    661                 return $champ != $valeur;
    662         } else {//Si mauvaise operateur -> on annule
    663                 return false;
    664         }
    665 }
    666 
    667 function saisies_tester_condition_afficher_si_array($champ, $operateur, $valeur) {
    668         // Convertir les valeurs en vrai tableau
    669         $valeur = explode(",", $valeur);
    670         $intersection = array_intersect($champ, $valeur);
    671         if ($operateur == "==" or $operateur == "IN") {
    672                 return count($intersection) > 0;
    673         } else {
    674                 return count($intersection) == 0;
    675         }
    676         return false;
    677 }
  • _plugins_/saisies/trunk/inc/saisies_afficher_si.php

    r113005 r113006  
    22
    33/**
    4  * Gestion de l'affichage des saisies.
    5  *
    6  * @return SPIP\Saisies\Afficher
    7  **/
     4 * Gestion de l'affichage conditionnelle des saisies
     5 *
     6 * @package SPIP\Saisies\Afficher_si
     7**/
    88
    99// Sécurité
     
    1212}
    1313
    14 /**
    15  * Indique si une saisie peut être affichée.
    16  *
    17  * On s'appuie sur l'éventuelle clé "editable" du $champ.
    18  * Si editable vaut :
    19  *    - absent : le champ est éditable
    20  *    - 1, le champ est éditable
    21  *    - 0, le champ n'est pas éditable
    22  *    - -1, le champ est éditable s'il y a du contenu dans le champ (l'environnement)
    23  *         ou dans un de ses enfants (fieldsets)
    24  *
    25  * @param array $champ
    26  *                                 Tableau de description de la saisie
    27  * @param array $env
    28  *                                 Environnement transmis à la saisie, certainement l'environnement du formulaire
    29  * @param bool  $utiliser_editable
    30  *                                 - false pour juste tester le cas -1
    31  *
    32  * @return bool
    33  *              Retourne un booléen indiquant l'état éditable ou pas :
    34  *              - true si la saisie est éditable (peut être affichée)
    35  *              - false sinon
    36  */
    37 function saisie_editable($champ, $env, $utiliser_editable = true) {
    38         if ($utiliser_editable) {
    39                 // si le champ n'est pas éditable, on sort.
    40                 if (!isset($champ['editable'])) {
    41                         return true;
    42                 }
    43                 $editable = $champ['editable'];
    44 
    45                 if ($editable > 0) {
    46                         return true;
    47                 }
    48                 if ($editable == 0) {
    49                         return false;
    50                 }
    51         }
    52 
    53         // cas -1
    54         // name de la saisie
    55         if (isset($champ['options']['nom'])) {
    56                 // si on a le name dans l'environnement, on le teste
    57                 $nom = $champ['options']['nom'];
    58                 if (isset($env[$nom])) {
    59                         return $env[$nom] ? true : false;
    60                 }
    61         }
    62         // sinon, si on a des sous saisies
    63         if (isset($champ['saisies']) and is_array($champ['saisies'])) {
    64                 foreach ($champ['saisies'] as $saisie) {
    65                         if (saisie_editable($saisie, $env, false)) {
    66                                 return true;
    67                         }
    68                 }
    69         }
    70 
    71         // aucun des paramètres demandés n'avait de contenu
    72         return false;
    73 }
    74 
    75 /**
    76  * Génère une saisie à partir d'un tableau la décrivant et de l'environnement.
    77  *
    78  * @param array $champ
    79  *                     Description de la saisie.
    80  *                     Le tableau doit être de la forme suivante :
    81  *                     array(
    82  *                     'saisie' => 'input',
    83  *                     'options' => array(
    84  *                     'nom' => 'le_name',
    85  *                     'label' => 'Un titre plus joli',
    86  *                     'obligatoire' => 'oui',
    87  *                     'explication' => 'Remplissez ce champ en utilisant votre clavier.'
    88  *                     )
    89  *                     )
    90  * @param array $env
    91  *                     Environnement du formulaire
    92  *                     Permet de savoir les valeurs actuelles des contenus des saisies,
    93  *                     les erreurs eventuelles présentes...
    94  *
    95  * @return string
    96  *                Code HTML des saisies de formulaire
    97  */
    98 function saisies_generer_html($champ, $env = array()) {
    99         // Si le parametre n'est pas bon, on genere du vide
    100         if (!is_array($champ)) {
    101                 return '';
    102         }
    103 
    104         // Si la saisie n'est pas editable, on sort aussi.
    105         if (!saisie_editable($champ, $env)) {
    106                 return '';
    107         }
    108 
    109         $contexte = array();
    110 
    111         // On sélectionne le type de saisie
    112         $contexte['type_saisie'] = $champ['saisie'];
    113         // Identifiant unique de saisie, si present
    114         if (isset($champ['identifiant'])) {
    115                 $contexte['id_saisie'] = $champ['identifiant'];
    116         }
    117 
    118         // Peut-être des transformations à faire sur les options textuelles
    119         $options = isset($champ['options']) ? $champ['options'] : array();
    120         foreach ($options as $option => $valeur) {
    121                 if ($option == 'datas') {
    122                         // exploser une chaine datas en tableau (applique _T_ou_typo sur chaque valeur)
    123                         $options[$option] = saisies_chaine2tableau($valeur);
    124                 } else {
    125                         $options[$option] = _T_ou_typo($valeur, 'multi');
    126                 }
    127         }
    128 
    129         // compatibilité li_class > conteneur_class
    130         if (!empty($options['li_class'])) {
    131                 $options['conteneur_class'] = $options['li_class'];
    132         }
    133 
    134         // On ajoute les options propres à la saisie
    135         $contexte = array_merge($contexte, $options);
    136 
    137         // On ajoute aussi les infos de vérification, si cela peut se faire directement en HTML5
    138         if (isset($champ['verifier'])) {
    139                 $contexte = array_merge($contexte, array('verifier'=>$champ['verifier']));
    140         }
    141 
    142         // Si env est définie dans les options ou qu'il y a des enfants, on ajoute tout l'environnement
    143         if (isset($contexte['env']) or (isset($champ['saisies']) and is_array($champ['saisies']))) {
    144                 unset($contexte['env']);
    145 
    146                 // on sauve l'ancien environnement
    147                 // car les sous-saisies ne doivent pas être affectees
    148                 // par les modification sur l'environnement servant à generer la saisie mère
    149                 $contexte['_env'] = $env;
    150 
    151                 // À partir du moment où on passe tout l'environnement,
    152                 // il faut enlever certains éléments qui ne doivent absolument provenir que des options
    153                 unset($env['inserer_debut']);
    154                 unset($env['inserer_fin']);
    155                 $saisies_disponibles = saisies_lister_disponibles();
    156                 if (isset($saisies_disponibles[$contexte['type_saisie']])
    157                         and isset($saisies_disponibles[$contexte['type_saisie']]['options'])
    158                         and is_array($saisies_disponibles[$contexte['type_saisie']]['options'])) {
    159                         $options_a_supprimer = saisies_lister_champs($saisies_disponibles[$contexte['type_saisie']]['options']);
    160                         foreach ($options_a_supprimer as $option_a_supprimer) {
    161                                 unset($env[$option_a_supprimer]);
    162                         }
    163                 }
    164 
    165                 $contexte = array_merge($env, $contexte);
    166         } else {
    167                 // Sinon on ne sélectionne que quelques éléments importants
    168                 // On récupère la liste des erreurs
    169                 $contexte['erreurs'] = $env['erreurs'];
    170                 // On récupère la langue de l'objet si existante
    171                 if (isset($env['langue'])) {
    172                         $contexte['langue'] = $env['langue'];
    173                 }
    174                 // On ajoute toujours le bon self
    175                 $contexte['self'] = self();
    176         }
    177 
    178         // Dans tous les cas on récupère de l'environnement la valeur actuelle du champ
    179         // Si le nom du champ est un tableau indexé, il faut parser !
    180         if (
    181                 isset($contexte['nom'])
    182                 and preg_match('/([\w]+)((\[[\w]+\])+)/', $contexte['nom'], $separe)
    183                 and isset($env[$separe[1]])
    184         ) {
    185                 $contexte['valeur'] = $env[$separe[1]];
    186                 preg_match_all('/\[([\w]+)\]/', $separe[2], $index);
    187                 // On va chercher au fond du tableau
    188                 foreach ($index[1] as $cle) {
    189                         $contexte['valeur'] = isset($contexte['valeur'][$cle]) ? $contexte['valeur'][$cle] : null;
    190                 }
    191         } elseif (isset($contexte['nom']) and isset($env[$contexte['nom']])) {
    192                 // Sinon la valeur est juste celle du nom si elle existe
    193                 $contexte['valeur'] = $env[$contexte['nom']];
    194         } else {
    195                 // Sinon rien
    196                 $contexte['valeur'] = null;
    197         }
    198 
    199         // Si ya des enfants on les remonte dans le contexte
    200         if (isset($champ['saisies']) and is_array($champ['saisies'])) {
    201                 $contexte['saisies'] = $champ['saisies'];
    202         }
    203 
    204         // On génère la saisie
    205         return recuperer_fond(
    206                 'saisies/_base',
    207                 $contexte
    208         );
    209 }
    210 
    211 /**
    212  * Génère une vue d'une saisie à partir d'un tableau la décrivant.
    213  *
    214  * @see saisies_generer_html()
    215  *
    216  * @param array $saisie
    217  *                               Tableau de description d'une saisie
    218  * @param array $env
    219  *                               L'environnement, contenant normalement la réponse à la saisie
    220  * @param array $env_obligatoire
    221  *                               ???
    222  *
    223  * @return string
    224  *                Code HTML de la vue de la saisie
    225  */
    226 function saisies_generer_vue($saisie, $env = array(), $env_obligatoire = array()) {
    227         // Si le paramètre n'est pas bon, on génère du vide
    228         if (!is_array($saisie)) {
    229                 return '';
    230         }
    231 
    232         $contexte = array();
    233 
    234         // On sélectionne le type de saisie
    235         $contexte['type_saisie'] = $saisie['saisie'];
    236 
    237         // Peut-être des transformations à faire sur les options textuelles
    238         $options = $saisie['options'];
    239         foreach ($options as $option => $valeur) {
    240                 if ($option == 'datas') {
    241                         // exploser une chaine datas en tableau (applique _T_ou_typo sur chaque valeur)
    242                         $options[$option] = saisies_chaine2tableau($valeur);
    243                 } else {
    244                         $options[$option] = _T_ou_typo($valeur, 'multi');
    245                 }
    246         }
    247 
    248         // On ajoute les options propres à la saisie
    249         $contexte = array_merge($contexte, $options);
    250 
    251         // Si env est définie dans les options ou qu'il y a des enfants, on ajoute tout l'environnement
    252         if (isset($contexte['env']) or (isset($saisie['saisies']) and is_array($saisie['saisies']))) {
    253                 unset($contexte['env']);
    254 
    255                 // on sauve l'ancien environnement
    256                 // car les sous-saisies ne doivent pas être affectees
    257                 // par les modification sur l'environnement servant à generer la saisie mère
    258                 $contexte['_env'] = $env;
    259 
    260                 // À partir du moment où on passe tout l'environnement, il faut enlever
    261                 // certains éléments qui ne doivent absolument provenir que des options
    262                 $saisies_disponibles = saisies_lister_disponibles();
    263 
    264                 if (isset($saisies_disponibles[$contexte['type_saisie']]['options'])
    265                         and is_array($saisies_disponibles[$contexte['type_saisie']]['options'])) {
    266                         $options_a_supprimer = saisies_lister_champs($saisies_disponibles[$contexte['type_saisie']]['options']);
    267                         foreach ($options_a_supprimer as $option_a_supprimer) {
    268                                 unset($env[$option_a_supprimer]);
    269                         }
    270                 }
    271 
    272                 $contexte = array_merge($env, $contexte);
    273         }
    274 
    275         // Dans tous les cas on récupère de l'environnement la valeur actuelle du champ
    276 
    277         // On regarde en priorité s'il y a un tableau listant toutes les valeurs
    278         if (!empty($env['valeurs']) and is_array($env['valeurs']) and isset($env['valeurs'][$contexte['nom']])) {
    279                 $contexte['valeur'] = $env['valeurs'][$contexte['nom']];
    280         } elseif (preg_match('/([\w]+)((\[[\w]+\])+)/', $contexte['nom'], $separe)) {
    281                 // Si le nom du champ est un tableau indexé, il faut parser !
    282                 $contexte['valeur'] = $env[$separe[1]];
    283                 preg_match_all('/\[([\w]+)\]/', $separe[2], $index);
    284                 // On va chercher au fond du tableau
    285                 foreach ($index[1] as $cle) {
    286                         $contexte['valeur'] = $contexte['valeur'][$cle];
    287                 }
    288         } else {
    289                 // Sinon la valeur est juste celle du nom
    290                 // certains n'ont pas de nom (fieldset)
    291                 $contexte['valeur'] = isset($env[$contexte['nom']]) ? $env[$contexte['nom']] : '';
    292         }
    293 
    294         // Si ya des enfants on les remonte dans le contexte
    295         if (isset($saisie['saisies']) and is_array($saisie['saisies'])) {
    296                 $contexte['saisies'] = $saisie['saisies'];
    297         }
    298 
    299         if (is_array($env_obligatoire)) {
    300                 $contexte = array_merge($contexte, $env_obligatoire);
    301         }
    302 
    303         // On génère la saisie
    304         return recuperer_fond(
    305                 'saisies-vues/_base',
    306                 $contexte
    307         );
    308 }
    30914
    31015/**
  • _plugins_/saisies/trunk/tests/saisies_afficher/saisies_tester_condition_afficher_si.php

    r113005 r113006  
    1313                $remonte = "../$remonte";
    1414        require $remonte.'tests/test.inc';
    15         find_in_path("../plugins/saisies/inc/saisies_afficher.php",'',true);
     15        find_in_path("../plugins/saisies/inc/saisies_afficher_si.php",'',true);
    1616
    1717        // chercher la fonction si elle n'existe pas
Note: See TracChangeset for help on using the changeset viewer.