Browse Source

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

svn/root/tags/v3.26.0
maieul@maieul.net 3 years ago
parent
commit
26964c5767
  1. 22
      inc/saisies_afficher_si_commun.php
  2. 171
      inc/saisies_afficher_si_php.php

22
inc/saisies_afficher_si_commun.php

@ -5,4 +5,26 @@
* Partie commun js/php
*
* @package SPIP\Saisies\Afficher_si_commun
**/
/**
* Reçoit une condition
* la parse pour trouver champs/opérateurs/valeurs etc.
* @param string $condition
* @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.
**/
function saisies_parser_condition_afficher_si($condition) {
$regexp =
"(?<negation>!?)" // négation éventuelle
. "(?:@(?<champ>.+?)@)" // @champ_@
. "(" // partie operateur + valeur (optionnelle) : debut
. "(?:\s*?)" // espaces éventuels après
. "(?<operateur>==|!=|IN|!IN|>=|>|<=|<)" // opérateur
. "(?:\s*?)" // espaces éventuels après
. "((?<guillemet>\"|')(?<valeur>.*?)(\k<guillemet>)|(?<valeur_numerique>\d+))" // valeur (string) ou valeur_numérique (int)
. ")?"; // partie operateur + valeur (optionnelle) : fin
$regexp = "#$regexp#";
preg_match_all($regexp, $condition, $tests, PREG_SET_ORDER);
return $tests;
}

171
inc/saisies_afficher_si_php.php

@ -1,9 +1,10 @@
<?php
/**
* Gestion de l'affichage conditionnelle des saisies
* Gestion de l'affichage conditionnelle des saisies.
* Partie spécifique php
*
* @package SPIP\Saisies\Afficher_si
* @package SPIP\Saisies\Afficher_si_php
**/
// Sécurité
@ -11,155 +12,7 @@ if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Génère, à partir d'un tableau de saisie le code javascript ajouté à la fin de #GENERER_SAISIES
* pour produire un affichage conditionnel des saisies ayant une option afficher_si
*
* @param array $saisies
* Tableau de descriptions des saisies
* @param string $id_form
* Identifiant unique pour le formulaire
*
* @return text
* Code javascript
*/
function saisies_generer_js_afficher_si($saisies, $id_form) {
$i = 0;
$saisies = saisies_lister_par_nom($saisies, true);
$code = '';
$code .= "$(function(){\n\tchargement=true;\n";
$code .= "\tverifier_saisies_".$id_form." = function(form){\n";
if (!defined('_SAISIES_AFFICHER_SI_JS_SHOW')) {
define ('_SAISIES_AFFICHER_SI_JS_SHOW', 'show(400)');
}
if (!defined('_SAISIES_AFFICHER_SI_JS_HIDE')) {
define ('_SAISIES_AFFICHER_SI_JS_HIDE', 'hide(400)');
}
foreach ($saisies as $saisie) {
// on utilise comme selecteur l'identifiant de saisie en priorite s'il est connu
// parce que conteneur_class = 'tableau[nom][option]' ne fonctionne evidement pas
// lorsque le name est un tableau
if (isset($saisie['options']['afficher_si']) && trim($saisie['options']['afficher_si'])) {
++$i;
// Les [] dans le nom de la saisie sont transformés en _ dans le
// nom de la classe, il faut faire pareil
$nom_underscore = rtrim(
preg_replace('/[][]\[?/', '_', $saisie['options']['nom']),
'_'
);
// retrouver la classe css probable
switch ($saisie['saisie']) {
case 'fieldset':
$class_li = 'fieldset_'.$nom_underscore;
break;
case 'explication':
$class_li = 'explication_'.$nom_underscore;
break;
default:
// Les [] dans le nom de la saisie sont transformés en _ dans le
// nom de la classe, il faut faire pareil
$class_li = 'editer_'.$nom_underscore;
}
$condition = trim($saisie['options']['afficher_si']);
// retrouver l'identifiant
$identifiant = '';
if (isset($saisie['identifiant']) and $saisie['identifiant']) {
$identifiant = $saisie['identifiant'];
}
// On gère le cas @plugin:non_plugin@
preg_match_all('#@plugin:(.+)@#U', $condition, $matches);
foreach ($matches[1] as $plug) {
if (defined('_DIR_PLUGIN_'.strtoupper($plug))) {
$condition = preg_replace('#@plugin:'.$plug.'@#U', 'true', $condition);
} else {
$condition = preg_replace('#@plugin:'.$plug.'@#U', 'false', $condition);
}
}
$condition = saisies_transformer_condition_afficher_si_config($condition);
// On transforme en une condition valide
preg_match_all('#@(.+)@#U', $condition, $matches);
foreach ($matches[1] as $nom) {
switch ($saisies[$nom]['saisie']) {
case 'radio':
case 'oui_non':
case 'true_false':
$condition = preg_replace('#@'.preg_quote($nom).'@#U', '$(form).find("[name=\''.$nom.'\']:checked").val()', $condition);
break;
case 'case':
$condition = preg_replace('#@'.preg_quote($nom).'@#U', '($(form).find(".checkbox[name=\''.$nom.'\']").is(":checked") ? $(form).find(".checkbox[name=\''.$nom.'\']").val() : "")', $condition);
break;
case 'checkbox':
/**
* Faire fonctionner @checkbox_xx@ == 'valeur' et @checkbox_xx@ != 'valeur'
*/
$condition = preg_replace('#@(.+)@\s*(==|(!)=)\s*(\'[^\']*\'|"[^"]*")#U', "@$1@ $3IN $4", $condition );
/**
* Faire fonctionner @checkbox_xx@ IN 'valeur' ou @checkbox_xx@ !IN 'valeur'
*/
preg_match_all('#@(.+)@\s*(!IN|IN)\s*[\'"](.*)[\'"]#U', $condition, $matches3);
foreach ($matches3[3] as $key => $value) {
$not = '';
if ($matches3[2][$key] == '!IN') {
$not = '!';
}
$values = explode(',', $value);
$new_condition = $not.'(';
foreach ($values as $key2 => $cond) {
if ($key2 > 0) {
$new_condition .= ' || ';
}
$new_condition .= '($(form).find(".checkbox[name=\''.$nom.'[]\'][value='.$cond.']").is(":checked") ? $(form).find(".checkbox[name=\''.$nom.'[]\'][value='.$cond.']").val() : "") == "'.$cond.'"';
}
$new_condition .= ')';
$condition = str_replace($matches3[0][$key], $new_condition, $condition);
}
break;
default:
$condition = preg_replace('#@'.preg_quote($nom).'@#U', '$(form).find("[name=\''.$nom.'\']").val()', $condition);
}
}
if ($identifiant) {
$sel = "[data-id='$identifiant']";
} else {
$sel = ".$class_li";
}
$code .= "\tif (".$condition.") {\n"
. "\t\t$(form).find(\"$sel\")."._SAISIES_AFFICHER_SI_JS_SHOW.".addClass('afficher_si_visible').removeClass('afficher_si_masque');\n";
if (html5_permis()) {
$code .= "\t\t$(form).find(\"$sel [data-afficher-si-required]\").attr(\"required\",true).attr(\"data-afficher-si-required\",null);\n";
}
$code .= "\t}\n";
$code .= "\telse {\n";
if (html5_permis()) {
$code .= "\t\t$(form).find(\"$sel [required]\").attr(\"required\",false).attr(\"data-afficher-si-required\",true);\n";
}
$code .= "\t\tif (chargement==true) {\n"
."\t\t\t$(form).find(\"$sel\")."._SAISIES_AFFICHER_SI_JS_HIDE.".addClass('afficher_si_masque').removeClass('afficher_si_visible').css".'("display","none")'.";\n"
."\t\t}\n"
."\t\telse {\n"
."\t\t\t$(form).find(\"$sel\")."._SAISIES_AFFICHER_SI_JS_HIDE.".addClass('afficher_si_masque').removeClass('afficher_si_visible');\n"
."\t\t};\n"
."\t}\n";
}
}
$code .= "$(form).trigger('saisies_afficher_si_js_ok');\n";
$code .= "};\n";
$code .= "\t".'$("#afficher_si_'.$id_form.'").parents("form").each(function(){'."\n\t\t".'verifier_saisies_'.$id_form.'(this);});'."\n";
$code .= "\t".'$("#afficher_si_'.$id_form.'").parents("form").change(function(){'."\n\t\t".'verifier_saisies_'.$id_form.'(this);});'."\n";
$code .= "\tchargement=false;})\n";
if (!defined('_SAISIES_AFFICHER_SI_JS_LISIBLE')) {
define('_SAISIES_AFFICHER_SI_JS_LISIBLE', false);
}
if (!_SAISIES_AFFICHER_SI_JS_LISIBLE) {
// il suffit de régler cette constante à TRUE pour afficher le js de manière plus lisible (et moins sibyllin)
$code = str_replace("\n", '', $code); //concatener
$code = str_replace("\t", '', $code); //concatener
}
return $i > 0 ? $code : '';
}
include_spip('inc/saisies_afficher_si_commun');
/**
* Lorsque l'on affiche les saisies (#VOIR_SAISIES), les saisies ayant une option afficher_si
@ -305,21 +158,7 @@ function saisies_transformer_condition_afficher_si_config($condition) {
* @return string $condition
**/
function saisies_transformer_condition_afficher_si($condition, $env = null) {
$regexp =
"(?<negation>!?)" // négation éventuelle
. "(?:@(?<champ>.+?)@)" // @champ_@
. "(" // partie operateur + valeur (optionnelle) : debut
. "(?:\s*?)" // espaces éventuels après
. "(?<operateur>==|!=|IN|!IN|>=|>|<=|<)" // opérateur
. "(?:\s*?)" // espaces éventuels après
. "((?<guillemet>\"|')(?<valeur>.*?)(\k<guillemet>)|(?<valeur_numerique>\d+))" // valeur (string) ou valeur_numérique (int)
. ")?"; // partie operateur + valeur (optionnelle) : fin
$regexp = "#$regexp#";
if (preg_match_all($regexp, $condition, $tests, PREG_SET_ORDER)) {
if (!saisies_afficher_si_secure($condition, $tests)) {
spip_log("Afficher_si incorrect. $condition non sécurisée", "saisies"._LOG_CRITIQUE);
return '';
}
if ($tests = saisies_parser_condition_afficher_si($condition)) {
foreach ($tests as $test) {
$expression = $test[0];
$champ = saisies_afficher_si_get_valeur_champ($test['champ'], $env);

Loading…
Cancel
Save