
Home
» Talus' Works » Talus' TPL » Général & Support » Filtre automatique des variables » Lecture du Sujet » Page 1 | Forum Fermé - Sujet Fermé |
|
|
|
|
Bonjour, Je souhaiterais appliquer automatiquement des filtres aux variables TPL, en occurrence un filtre protect et un filtre nl2br. Je suis donc allé voir du coté du compiler, puis j'ai repérer la ligne là (je suis peut être sur une vielle version du TPL) :
Code
$compile = preg_replace_callback('`\{(\$?[][a-zA-Z_\x7f-\xff.,]+?)\|((?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\|?)+)}`', array($this, '_filters'), $compile);
Au dessus de cette ligne, j'ai rajouté ça :
Code
$compile = preg_replace('/\{([^$_{2}].*)\}/', '{$1|protect|nl2br}', $compile);
Cela transforme les variables {VAR},{VAR[key]},{VAR[key]|filtre}, etc.. en {VAR|protect|nl2br}, {VAR[key]|protect|nl2br}, etc... Puis, lorsque je ne souhaite pas affecter ces filtres je fais : {VAR|unhtml|unbr} ou {VAR|unhtml} ou {VAR|unbr}. Coté PHP, je ne cré pas de nouveau filtre pour annulé le protect et le nl2br mais je rajoute ça en dessous de la ligne du dessus :
Code
$compile = preg_replace('/\{([^$].*)\|unhtml\|protect\|nl2br\}/', '{$1|nl2br}', $compile);
$compile = preg_replace('/\{([^$].*)\|unbr\|protect\|nl2br\}/', '{$1|protect}', $compile);
$compile = preg_replace('/\{([^$].*)\|unhtml\|unbr\|protect\|nl2br\}/', '{$1}', $compile);
$compile = preg_replace('/\{([^$].*)\|unbr\|unhtml\|protect\|nl2br\}/', '{$1}', $compile);
Evidement, n'étant pas très familiarisé avec les regex, c'est un peu l'orgie et ça bug ^^ Plus exactement ça marche nikel quand je fais par exemple :
Code
texte {VAR} texte {VAR|unbr} texte {VAR[key]} texte {VAR|unbr|unhtml}
Mais si j'ai 2 {VAR} sur la même ligne ça bug, ma regex commence au début de la première {VAR} puis au lieu de finir à la fin de cette même variable elle continue jusqu'à la fin de la 2ème {VAR} (si j'en met 3 ça prendra la 3ème etc...). J'ai donc essayé ça qui ne marche pas (parmis plein d'autres trucs qui ne marche pas non plus) :
Code
$compile = preg_replace('/\{([^$_{2}][^\{\}]*.*)\}/', '{$1|protect|nl2br}', $compile);
Du coup lorsque je fais :
Code
{VAR|unbr} texte {VAR}
Le filtre unbr n'est pas effacer (ni nl2br) et du coup j'ai un "Talus_TPL_Compiler :: Le filtre "unhtml" n'existe pas, et sera donc ignoré." Pourrais-tu m'aider à régler ce problème ? Merci de m'avoir lu. Xavier. |
|
|
|
|
|
Hello, Au lieu de faire tes nouveaux filtres unhtml / unbr dans le code de compiler, je pense que tu devrais plutot les créer et laisser faire le travail aux filtres en eux-mêmes (surtout que tu as déjà des fonctions de php qui te permettent de faire el sens inverse des fonctions htmlspecialchars / nl2br (enfin plus ou moins)). Ensuite pour les filtres automatiques, c'est parce que par défaut, pour les regex, PHP se met en mode "gourmand", et essaye donc de capturer le plus de caractères possibles dans la capture pour lui ajouter le |protect & |nl2br. Il existe plusieurs solutions, dont ajouter les options "u" ou un "?" après les .* / .+ (je préfère cette solution). Je compte aussi, un de ces jours, tenter d'implémenter les filtres automatiques par défaut. La piste que j'avais, à la base, c'était plutot de passer par la classe principale plutot que par celle de compilation, lors de l'affectation des variables, qui donc applique directement le filtre... Et donc, ne pas toucher aux variables regex. :) Dev' de Talus' Works |
|
|
|
|
Salut, Désolé de ne répondre que maintenant, je suis très occupé :S Merci pour la réponse, je vais regardé ça je te tiens au courant. Les problèmes actuels que j'ai identifié : ---------------------------------------------------- Bon alors, j'ai décidé de le faire à ta manière, c'est vrai que c'est (beaucoup) plus simple :) Du coup, ça m'a l'air totalement fonctionnel : Dans talus_tpl.php
Code
public function set($var, $value = ''){
if (is_array($var)) {
$this->vars = array_merge($this->vars, $var);
} else {
$this->vars[$var] = $value;
}
}
Devient :
Code
public function set($var, $value = ''){
/*if (is_array($var)) {
$this->vars = array_merge($this->vars, $var);
} else {
$this->vars[$var] = $value;
}*/
if (is_array($var)) {
$var = array_map("htmlentities", $var);
$var = array_map("nl2br", $var);
$this->vars = array_merge($this->vars, $var);
} elseif (is_array($value)) {
$value = array_map("htmlentities", $value);
$value = array_map("nl2br", $value);
$this->vars[$var] = $value;
} else {
$this->vars[$var] = nl2br(htmlentities($value));
}
}
Puis dans les filtres, je rajoute ceux la :
Code
public static function unbr($arg){
$arg = str_replace('', '', $arg);
$arg = str_replace('<br>', '', $arg);
return $arg;
}
public static function unprotect($arg){
//return _htmlspecialchars($arg);
$tmp = get_html_translation_table(HTML_ENTITIES);
$tmp = array_flip ($tmp);
$arg = strtr ($arg, $tmp);
return $arg;
}
Donc quand on ne veut pas de code html on utilise le filtre unprotect, quand on ne veut pas de retour html on utilise le filtre unbr. Tout m'a l'air de fonctionner. Je re pour feedback après des tests poussés. En tout cas un grand merci, je n'avais pas pensé à cette solution. Dernière édition le 22/09/2010, à 14:42, par Xas |
|
|
|
|
|
Huum, le problème avec ton machin, c'est si tu as des arrays comme valeurs (des arrays ayant une profondeur au moins de 2 dimensions) ; tu contournes le problème de la deuxieme dimension si tu ne déclare qu'une seule variable ($tpl->set('VAR', array('a', 'b', 'c'));), mais si c'est plus d'une dimension, ou si tu souhaite déclarer plusieurs array d'un coup (de dimension >= 1), là ca merdera. Il faut faire appel à une fonction de traitement récursif, hors, y'a pas pour array_map... Elle est simple à faire, cependant. Dev' de Talus' Works |
|
|
|
|
Ah oui exact, je n'y avais pas pensé mais je serais surement tombé sur le problème donc merci de m'avoir fait gagner du temps ^^ Quelques choses dans le genre devrait marcher :
Code
// Fonction récursive filtrant les tableaux
private function _setArray($array){
$r = array();
if (is_array($array))
{
foreach($array as $key => $value)
{
if(is_scalar($value))
{
$value = htmlentities($value);
$value = nl2br($value);
$r[$key] = $value;
}
else
$this->_setArray($value);
}
return $r;
}
}
// Fonction set modifié
public function set($var, $value = ''){
if (is_array($var)) {
$this->vars = array_merge($this->vars, $this->_setArray($var));
} elseif (is_array($value)) {
$this->vars[$var] = $this->_setArray($value);
} else {
$this->vars[$var] = nl2br(htmlentities($value));
}
}
Je re après quelques tests ;) Edit : Je pense que c'est bon comme ça, je ne trouve pas de bug, si tu vois un problème auquel je n'aurais pas pensé, fais signe ;) Dernière édition le 23/09/2010, à 13:58, par Xas |
|
|
|
|
|
Me revoilà après quelques tests, donc ça ne marche toujours pas pour les array multidimensionnels, je dois avoir un problème dans ma récursive mais je ne vois pas où. Ca marche pour ça :
Code
$mon_array = array('var1', 'var2');
$tpl->set('MON_ARRAY', $mon_array);
Mais pas pour ça :
Code
$mon_array = array(
array('var1', 'var2'),
array('var3', 'var4')
);
// Marche pas
$tpl->set('MON_ARRAY', $mon_array);
// Marche
$tpl->set('MON_ARRAY', $mon_array[0]);
Un dump de la variable me renvoie : array(0) Aurais-tu une idée d'où vient le problème ? Je vois vraiment pas ou je me plante :S Edit : C'est bon, petite boulette, la fonction était rappelé sans être stocké dans le nouveau array, donc là c'est bon ça nikel :) La récursive final :
Code
private function _setArray($array){
$r = array();
if (is_array($array))
{
foreach($array as $key => $value)
{
if(is_array($value))
$r[$key] = $this->_setArray($value);
else
{
$value = htmlentities($value);
$value = nl2br($value);
$r[$key] = $value;
}
}
return $r;
}
}
Edit : Pour ce qui est des variables affectés par setBlock, elle ne sont pas protégées par cette modification, je viendrais remettre la modif à faire ici quand je l'aurais testé au cas où des personnes souhaiteraient mettre en place la protection auto des variables. Dernière édition le 25/09/2010, à 16:09, par Xas |
|
|
|
|
|
Sinon j'ai mis à jour le dépot GIT, en incluant donc pour les variables et les blocs.... Et avec un filtre "en général" (en gros, pouvoir choisir plusieurs filtres à êtte inclus...) Dev' de Talus' Works |
|
|
|
|
Ah, je n'avais pas vu, je regarde ça dès que j'ai un peu de temps ;) |
|
|
|
|
|
Yop, Je viens de copier la 1.8.0.1, j'étais resté à la 1.5.1 (je crois), y'a pas mal de changement. Concernant les filtres auto, je n'ai pas trouvé ou cela se jouait, tu peux m'aider ? Concernant les autres changements que j'ai pu constater et qui m'ont fait un peu tiquer : |
|
|
|
|
|
Il y a une version encore plus à jour sur le dépot (une 1.9.0 à priori). Les filtres auto y sont pour le moment, tout comme le retour de {$__CONSTANTE__} (pour les filtres). Concernant le nom du fichier, oui, c'était pour qu'on puisse différencier les qqch.tempalte.html de qqch/template.html... Dev' de Talus' Works |
|
|
|
|
Je ne vois toujours pas l'intérêt des $constantes ... |
|
|
|
|
|
Pour les arguments de filtres : {VAR|filtre:{$__NEED_CONSTANT__}}. Sinon, si on utilise NEED_CONSTANT, ce sera interpreté comme étant 'NEED_CONSTANT', soit une chaine de caractères. Dev' de Talus' Works |
|
|
|
|
Donc c'est plus un problème du parser qu'autre chose :p. |
|
|
|
|
|
Ben... Non. Je peux pas deviner quand il s'agit d'une constante ou du texte, hein. A moins que forcer le mec à entourer les chaines de caractères entre des délimiteurs, mais autant le faire automatiquement... Dev' de Talus' Works |
|
|
|
|
Bah on pourrait avoir besoin du mettre du texte en dur comme paramètre d'un filtre, ça me paraît pas si aberrant que ça moi ... |
|
|
|
|
|
Justement ; au lieu d'avoir {A|F:'texte'}, vaut mieux {A|F:texte}... Dev' de Talus' Works |
| Forum Fermé - Sujet Fermé |