Changeset 113011 in spip-zone


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

Transformer au sein des conditions les @champ_1@ == "" et similaire en résultats de leur évaluation, puis passer la condition en eval().

Au stade du eval(), la seule choses qui reste à évaluer, ce sont les opérateurs booléens entre chaque test individuel de champ.

Location:
_plugins_/saisies/trunk
Files:
1 added
1 edited

Legend:

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

    r113009 r113011  
    224224                        }
    225225                        // On transforme en une condition PHP valide
    226                         $condition_originale = $condition;
    227                         if (is_null($env)) {
    228                                 $condition = preg_replace('#@(.+)@#U', '_request(\'$1\')', $condition);
    229                         } else {
    230                                 $condition = preg_replace('#@(.+)@#U', '$env["valeurs"][\'$1\']', $condition);
    231                         }
    232                         /**
    233                          * Tester si la condition utilise des champs qui sont des tableaux
    234                          * Si _request() ou $env["valeurs"] est un tableau, changer == et != par in_array et !in_array
    235                          * TODO: c'est vraiment pas terrible comme fonctionnement
    236                          */
    237                         preg_match_all('/(_request\([\'"].*?[\'"]\)|\$env\[[\'"].*?[\'"]\]\[[\'"].*?[\'"]\])\s*(!=|==|IN|!IN)\s*[\'"](.*?)[\'"]/', $condition, $matches);
    238                         foreach ($matches[1] as $key => $val) {
    239                                 eval('$requete = '.$val.';');
    240                                 //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.
    241                                 if (is_null($requete)) {
    242                                         $requete = array();
    243                                         //C'est un request, alors on va faire un set_request
    244                                         if (strpos($val, '_request') === 0) {
    245                                                 $set_tableau = "set$val";
    246                                                 $set_tableau = str_replace(")",",array())",$set_tableau);
    247                                         } elseif (strpos($val, '$env') === 0) {//C'est un tablau direct
    248                                                 $set_tableau = ("$val = array()");
    249                                         }
    250                                         if (isset($set_tableau)) {
    251                                                 eval("$set_tableau;");
    252                                         }
    253                                 }
    254                                 if (is_array($requete)) {
    255                                         $not = '>';
    256                                         if (in_array($matches[2][$key], array('!=', '!IN'))) {
    257                                                 $not = '==';
    258                                         }
    259                                         $array = var_export(explode(',', $matches[3][$key]), true);
    260                                         $condition = str_replace($matches[0][$key], "(count(array_intersect($val, $array)) $not 0)", $condition);
    261                                 }
    262                         }
    263                         // On vérifie que l'on a pas @toto@="valeur" qui fait planter l'eval(),
    264                         // on annule cette condition dans ce cas pour éviter une erreur du type :
    265                         // PHP Fatal error:  Can't use function return value in write context
    266                         $type_condition = preg_replace('#@(.+)@#U', '', $condition_originale);
    267                         if (trim($type_condition) != '=') {
    268                                 eval('$ok = '.$condition.';');
    269                         }
     226                        $ok = saisies_evaluer_afficher_si($condition, $env);
    270227                        if (!$ok) {
    271228                                if ($remplissage_uniquement == false or is_null($env)) {
     
    285242        return $saisies;
    286243}
     244
    287245
    288246
     
    321279        //Sinon c'est que c'est bon
    322280        return true;
     281}
     282
     283/**
     284 * Prend un test conditionnel,
     285 * le sépare en une série de sous-tests de type champ - operateur - valeur
     286 * remplace chacun de ces sous-tests par son résultat
     287 * renvoie la chaine transformé
     288 * @param string $condition
     289 * @param array|null $env
     290 *   Tableau d'environnement transmis dans inclure/voir_saisies.html,
     291 *   NULL si on doit rechercher dans _request (pour saisies_verifier()).
     292 * @return string $condition
     293**/
     294function saisies_transformer_condition_afficher_si($condition, $env = null) {
     295        $regexp = "(?:@(?<champ>.+?)@)" // @champ_@
     296                . "(?:\s*?)" // espaces éventuels après
     297                . "(?<operateur>==|!=|IN|!IN)" // opérateur
     298                . "(?:\s*?)" // espaces éventuels après
     299                . "(?<guillemet>\"|')(?<valeur>.*?)(\k<guillemet>)"; // valeur
     300        $regexp = "#$regexp#";
     301        if (preg_match_all($regexp, $condition, $tests, PREG_SET_ORDER)) {
     302                foreach ($tests as $test) {
     303                        $expression = $test[0];
     304                        $champ = $test['champ'];
     305                        if (is_null($env)) {
     306                                $champ = _request($champ);
     307                        } else {
     308                                $champ = $env["valeurs"][$champ];
     309                        }
     310                        $operateur = $test['operateur'];
     311                        $valeur = $test['valeur'];
     312                        $test_modifie = saisies_tester_condition_afficher_si($champ, $operateur, $valeur) ? 'true' : 'false';
     313                        $condition = str_replace($expression, $test_modifie, $condition);
     314                }
     315        }
     316        return $condition;
    323317}
    324318
     
    395389        return false;
    396390}
     391
     392/**
     393 * Evalue un afficher_si
     394 * @param string $condition (déjà checkée en terme de sécurité)
     395 * @param array|null $env
     396 *   Tableau d'environnement transmis dans inclure/voir_saisies.html,
     397 *   NULL si on doit rechercher dans _request (pour saisies_verifier()).
     398 * @return bool le résultat du test
     399**/
     400function saisies_evaluer_afficher_si($condition, $env = null) {
     401        $condition = saisies_transformer_condition_afficher_si($condition, $env);
     402        eval('$ok = '.$condition.';');
     403        return $ok;
     404}
Note: See TracChangeset for help on using the changeset viewer.