Initial commit
This commit is contained in:
611
www/classes/parseur/Analyse.class.php
Normal file
611
www/classes/parseur/Analyse.class.php
Normal file
@@ -0,0 +1,611 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) 2005-2013 OpenStudio */
|
||||
/* email : info@thelia.fr */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
class Analyse{
|
||||
public $contenu;
|
||||
public $tokens;
|
||||
|
||||
public $pile_nom_boucle;
|
||||
public $pile_boucle_courante;
|
||||
|
||||
private $in_comment = false;
|
||||
|
||||
private static $no_debug;
|
||||
|
||||
public static $debug_text;
|
||||
|
||||
function __construct($allow_debug)
|
||||
{
|
||||
self::$no_debug = ! ($allow_debug && (DEBUG_PARSER || DEBUG_EVAL));
|
||||
|
||||
$this->tokens = array();
|
||||
$this->pile_nom_boucles = array();
|
||||
$this->pile_boucle_courante = array();
|
||||
|
||||
self::$debug_text = false;
|
||||
}
|
||||
|
||||
function terminer()
|
||||
{
|
||||
if (! self::$no_debug)
|
||||
{
|
||||
self::$debug_text = '
|
||||
<div style="border: 1px solid black; margin: 5px; background-color: white; color: black; text-align: left; font-size: 11px;">
|
||||
<div style="border-bottom: 1px solid black; margin: 0; padding: 5px; background-color: #f0f0f0; font-weight: bold;">Information de debug du parser</div>
|
||||
<pre style="margin: 0; padding: 5px; height: 200px; overflow: scroll;">'
|
||||
. self::$debug_text
|
||||
.'</pre></div>'
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static function strlen_cmp($a, $b)
|
||||
{
|
||||
$la = strlen($a);
|
||||
$lb = strlen($b);
|
||||
|
||||
if ($la == $lb) return 0;
|
||||
|
||||
return ($la > $lb) ? -1 : 1;
|
||||
}
|
||||
|
||||
public static function echo_debug()
|
||||
{
|
||||
if (self::$no_debug) return;
|
||||
|
||||
$text = '';
|
||||
|
||||
$numargs = func_num_args();
|
||||
|
||||
for($idx = 0; $idx < $numargs; $idx++)
|
||||
{
|
||||
$arg = func_get_arg($idx);
|
||||
|
||||
$text .= is_scalar($arg) ? $arg : print_r($arg, true);
|
||||
}
|
||||
|
||||
self::$debug_text .= '<pre>[DEBUG] ' . htmlspecialchars($text)."</pre>\n";
|
||||
}
|
||||
|
||||
function parse_string(&$filecontents)
|
||||
{
|
||||
$this->tokens = preg_split("/( |\t|\n|\r|<|>|\\#|\")/", $filecontents, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
// Comme on fait un next() dans parse content, insérer une valeur non significative en début de tableau
|
||||
array_unshift($this->tokens, '');
|
||||
|
||||
// if (DEBUG_PARSER) {Analyse::echo_debug("Tokens: ", $this->tokens); }
|
||||
|
||||
return $this->parse_content();
|
||||
}
|
||||
|
||||
function parse_string_with_cache(&$filecontents, $cache_dir)
|
||||
{
|
||||
if (! is_dir($cache_dir))
|
||||
{
|
||||
if (mkdir($cache_dir, 0777, true) === false)
|
||||
{
|
||||
die('Impossible de créer le répertoire '.$cache_dir.'. Vérifiez les droits d\'accès');
|
||||
}
|
||||
}
|
||||
|
||||
$this->cleanup_cache($cache_dir);
|
||||
|
||||
$cache_file = $cache_dir . hash('md5', $filecontents) . '.cache';
|
||||
|
||||
if (file_exists($cache_file))
|
||||
{
|
||||
// Mettre à jour la date du fichier: les fichiers les plus souvent accédés restent plus longtemps dans le cache.
|
||||
@touch($cache_file);
|
||||
|
||||
return unserialize(file_get_contents($cache_file));
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = $this->parse_string($filecontents);
|
||||
|
||||
file_put_contents($cache_file, serialize($data));
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
public static function cleanup_cache($cache_dir, $force = 0)
|
||||
{
|
||||
// Doit-on purger le cache ?
|
||||
$last_check = intval(Variable::lire(Parseur::PREFIXE.'_cache_check_time'));
|
||||
$check_period = intval(3600 * Variable::lire(Parseur::PREFIXE.'_cache_check_period'));
|
||||
|
||||
if ($force == 0 && time() - $last_check < $check_period) return;
|
||||
|
||||
Variable::ecrire(Parseur::PREFIXE.'_cache_check_time', time());
|
||||
|
||||
$cache_file_lifetime = 3600 * Variable::lire(Parseur::PREFIXE.'_cache_file_lifetime');
|
||||
|
||||
if ($dh = @opendir($cache_dir))
|
||||
{
|
||||
while ($file = readdir($dh))
|
||||
{
|
||||
if (strstr($file, '.cache') !== false)
|
||||
{
|
||||
$path = $cache_dir . $file;
|
||||
|
||||
$filemtime = @filemtime($path);
|
||||
|
||||
if (! $filemtime || (time() - $filemtime) >= $cache_file_lifetime )
|
||||
{
|
||||
@unlink($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@closedir($dh);
|
||||
}
|
||||
}
|
||||
|
||||
function parse_args()
|
||||
{
|
||||
$args = '';
|
||||
|
||||
$in_quote = false;
|
||||
|
||||
while (1)
|
||||
{
|
||||
$tok = next($this->tokens);
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Parse args: tok='$tok', in_quote=$in_quote"); }
|
||||
|
||||
if ($tok == '#')
|
||||
{
|
||||
$token = next($this->tokens);
|
||||
|
||||
if (preg_match('/([A-Z0-9_]+)/', $token, $varname) > 0)
|
||||
{
|
||||
$tok = '#'.$varname[1];
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("new arg var: '$tok'"); }
|
||||
}
|
||||
|
||||
$this->add_var($tok);
|
||||
|
||||
// Il faut placer dans les args la valeur originale (sinon bug. Ex: #PROMO[X][Y])
|
||||
$tok = '#'.$token;
|
||||
}
|
||||
else if ($tok == '"')
|
||||
{
|
||||
$in_quote = ! $in_quote;
|
||||
}
|
||||
else if ($tok == '>')
|
||||
{
|
||||
if (! $in_quote) break;
|
||||
}
|
||||
else if ($tok === FALSE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$args .= $tok;
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
function add_var($token)
|
||||
{
|
||||
// Ne pas prendre en compte les filtres et les get/set
|
||||
if (strstr($token, 'FILTRE_') !== FALSE
|
||||
||
|
||||
strstr($token, 'GET{') !== FALSE
|
||||
||
|
||||
strstr($token, 'SET{') !== FALSE) return;
|
||||
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Variable: $token");}
|
||||
$count = count($this->pile_boucle_courante);
|
||||
// Pas de boucle ouverte
|
||||
if ($count == 0) return;
|
||||
|
||||
//$boucle_courante = end($this->pile_boucle_courante);
|
||||
$boucle_courante = $this->pile_boucle_courante[$count-1];
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("boucle courante: ", $boucle_courante); }
|
||||
|
||||
// La boucle n'est pas une boucle simple -> on ne stocke pas les variables
|
||||
if ($boucle_courante->type() != PexToken::TYPE_BOUCLE_SIMPLE) return;
|
||||
|
||||
if (preg_match('/([A-Z0-9_]+)/', $token, $varname) > 0)
|
||||
{
|
||||
if (! in_array($varname[1], $boucle_courante->variables))
|
||||
{
|
||||
$boucle_courante->variables[] = $varname[1];
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Variables de $boucle_courante->nom", $boucle_courante->variables);}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function controle_fermeture_boucle($nom_boucle)
|
||||
{
|
||||
$nom_pile = array_pop($this->pile_nom_boucles);
|
||||
|
||||
//if (DEBUG_PARSER) Analyse::echo_debug("Pile boucles: required: '$nom_boucle', popped: '/$nom_pile', ", $this->pile_nom_boucles);
|
||||
|
||||
if ($nom_boucle != '/' . $nom_pile)
|
||||
{
|
||||
if ($nom_pile == '')
|
||||
{
|
||||
die("Erreur de syntaxe: $nom_boucle: balise de fin sans balise de début.");
|
||||
}
|
||||
else
|
||||
{
|
||||
die("Erreur de syntaxe: $nom_boucle trouvé, /$nom_pile attendu.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function process_token(&$atoken)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("enter process_token ", $atoken);}
|
||||
|
||||
$token_type = PexToken::TXT;
|
||||
|
||||
if ($atoken == '<')
|
||||
{
|
||||
$no_match = false;
|
||||
|
||||
$token = next($this->tokens);
|
||||
|
||||
if (DEBUG_PARSER) { Analyse::echo_debug("Next PexToken:[$token]");}
|
||||
|
||||
// Optimisation (gain: ~= 0,1 sec. sur index standard)
|
||||
if ($token[0] != 'T' && strpos($token, '/T') !== 0 && strpos($token, '//T') !== 0 && $token[0] != 'R' && strpos($token, '/R') !== 0)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("N'est pas une boucle thelia");}
|
||||
|
||||
$no_match = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get token type
|
||||
if (strpos($token, 'THELIA_') === 0)
|
||||
$token_type = PexToken::OBS;
|
||||
else if (strpos($token, '/THELIA_') === 0)
|
||||
$token_type = PexToken::FBS;
|
||||
else if (strpos($token, 'TEST_') === 0)
|
||||
$token_type = PexToken::OBT;
|
||||
else if (strpos($token, '/TEST_') === 0)
|
||||
$token_type = PexToken::EBT;
|
||||
else if (strpos($token, '//TEST_') === 0)
|
||||
$token_type = PexToken::FBT;
|
||||
else if (strpos($token, 'T_') === 0)
|
||||
$token_type = PexToken::OBC;
|
||||
else if (strpos($token, '/T_') === 0)
|
||||
$token_type = PexToken::EBC;
|
||||
else if (strpos($token, '//T_') === 0)
|
||||
$token_type = PexToken::FBC;
|
||||
else if (strpos($token, 'REM') === 0)
|
||||
$token_type = PexToken::OCM;
|
||||
else if (strpos($token, '/REM') === 0)
|
||||
$token_type = PexToken::FCM;
|
||||
else if (strpos($token, 'REPETER') === 0)
|
||||
$token_type = PexToken::OBR;
|
||||
else if (strpos($token, '/REPETER') === 0)
|
||||
$token_type = PexToken::FBR;
|
||||
else if (strpos($token, 'T:') === 0)
|
||||
$token_type = PexToken::OBCV;
|
||||
else if (strpos($token, '/T:') === 0)
|
||||
$token_type = PexToken::EBCV;
|
||||
else if (strpos($token, '//T:') === 0)
|
||||
$token_type = PexToken::FBCV;
|
||||
else
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Token type texte");}
|
||||
|
||||
$no_match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($no_match)
|
||||
{
|
||||
prev($this->tokens);
|
||||
|
||||
$token = $atoken;
|
||||
}
|
||||
}
|
||||
// Variables
|
||||
else if ($atoken == '#')
|
||||
{
|
||||
// Traiter les cas similaires à ##REF
|
||||
$tmp = next($this->tokens);
|
||||
|
||||
if ($tmp == '#')
|
||||
{
|
||||
$token = '#';
|
||||
|
||||
prev($this->tokens);
|
||||
}
|
||||
else
|
||||
{
|
||||
$token = '#' . $tmp;
|
||||
|
||||
$this->add_var($token);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$token = $atoken;
|
||||
}
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug( "Token:[$token], type $token_type"); }
|
||||
|
||||
// Dans un commentaire, on attend la fin sans rien analyser
|
||||
if ($this->in_comment && $token_type !== PexToken::FCM)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("ignore: $token_type:", $token); }
|
||||
return 'vide';
|
||||
}
|
||||
|
||||
// BOUCLE SIMPLE et boucle REPETER
|
||||
if ($token_type === PexToken::OBS || $token_type === PexToken::OBR)
|
||||
{
|
||||
if ($token_type === PexToken::OBS)
|
||||
$boucle = new BoucleSimple(substr($token, 7));
|
||||
else
|
||||
$boucle = new BoucleRepeter(substr($token, 8));
|
||||
|
||||
array_push($this->pile_nom_boucles, $token);
|
||||
|
||||
// Parse args se fait avant le push, car les variables dans les args doivent être valuées
|
||||
// par la boucle enclosante.
|
||||
$boucle->set_args($this->parse_args());
|
||||
|
||||
array_push($this->pile_boucle_courante, $boucle);
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Push boucle courante $boucle->nom\n", $this->pile_boucle_courante); }
|
||||
|
||||
$boucle->ajouter($this->parse_content());
|
||||
|
||||
// Skip remaining > TODO check >
|
||||
$this->skipto('>');
|
||||
|
||||
return $boucle;
|
||||
}
|
||||
else if ($token_type === PexToken::FBS || $token_type === PexToken::FBR)
|
||||
{
|
||||
$this->controle_fermeture_boucle($token);
|
||||
|
||||
array_pop($this->pile_boucle_courante);
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Pop boucle courante $token\n", $this->pile_boucle_courante); }
|
||||
|
||||
return 'stop';
|
||||
}
|
||||
// BOUCLE CONDITIONNELLE
|
||||
else if ($token_type === PexToken::OBC)
|
||||
{
|
||||
$boucle = new BoucleConditionnelle(substr($token, 2));
|
||||
$this->skipto('>');
|
||||
|
||||
array_push($this->pile_nom_boucles, $token);
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Push boucle conditionnelle $token\n", $this->pile_boucle_courante); }
|
||||
|
||||
// Si
|
||||
$boucle->ajouter($this->parse_content());
|
||||
$this->skipto('>');
|
||||
|
||||
array_push($this->pile_nom_boucles, '/'.$token);
|
||||
|
||||
//if ( const ) { Analyse::echo_debug("Push SI boucle conditionnelle $token\n", $this->pile_boucle_courante); }
|
||||
|
||||
// Sinon
|
||||
$boucle->ajouter($this->parse_content());
|
||||
$this->skipto('>');
|
||||
|
||||
return $boucle;
|
||||
}
|
||||
else if ($token_type === PexToken::EBC)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Controle fermeture SI: $token\n", $this->pile_boucle_courante); }
|
||||
|
||||
$this->controle_fermeture_boucle($token);
|
||||
|
||||
return 'stop';
|
||||
}
|
||||
else if ($token_type === PexToken::FBC)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Controle fermeture ELSE: $token\n", $this->pile_boucle_courante);}
|
||||
|
||||
$this->controle_fermeture_boucle($token);
|
||||
|
||||
return 'stop';
|
||||
}
|
||||
// BOUCLE CONDITIONNELLE sur vaeriable
|
||||
else if ($token_type === PexToken::OBCV)
|
||||
{
|
||||
$var = substr($token, 2);
|
||||
|
||||
// Ajouter la variable à la boucle enclosante
|
||||
$this->add_var($var);
|
||||
|
||||
$boucle = new BoucleConditionnelleVariable($var);
|
||||
$this->skipto('>');
|
||||
|
||||
array_push($this->pile_nom_boucles, $token);
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Push boucle conditionnelle $token\n", $this->pile_boucle_courante); }
|
||||
|
||||
// Si
|
||||
$boucle->ajouter($this->parse_content());
|
||||
$this->skipto('>');
|
||||
|
||||
array_push($this->pile_nom_boucles, '/'.$token);
|
||||
|
||||
//if ( const ) { Analyse::echo_debug("Push SI boucle conditionnelle $token\n", $this->pile_boucle_courante); }
|
||||
|
||||
// Sinon
|
||||
$boucle->ajouter($this->parse_content());
|
||||
$this->skipto('>');
|
||||
|
||||
return $boucle;
|
||||
}
|
||||
else if ($token_type === PexToken::EBCV)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Controle fermeture SI: $token\n", $this->pile_boucle_courante); }
|
||||
|
||||
$this->controle_fermeture_boucle($token);
|
||||
|
||||
return 'stop';
|
||||
}
|
||||
else if ($token_type === PexToken::FBCV)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Controle fermeture ELSE: $token\n", $this->pile_boucle_courante);}
|
||||
|
||||
$this->controle_fermeture_boucle($token);
|
||||
|
||||
return 'stop';
|
||||
}
|
||||
|
||||
// Boucle <TEST_xxx>
|
||||
else if ($token_type === PexToken::OBT)
|
||||
{
|
||||
$boucle = new BoucleTest(substr($token, 5));
|
||||
|
||||
// Parse args se fait avant le push, car les variables dans les args doivent être valuées
|
||||
// par la boucle enclosante.
|
||||
$boucle->set_args($this->parse_args());
|
||||
|
||||
array_push($this->pile_nom_boucles, $token);
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Push boucle Test $boucle->nom\n", $this->pile_boucle_courante);}
|
||||
|
||||
// Si
|
||||
$boucle->ajouter($this->parse_content());
|
||||
$this->skipto('>');
|
||||
|
||||
array_push($this->pile_nom_boucles, '/' . $token);
|
||||
|
||||
// Sinon
|
||||
$boucle->ajouter($this->parse_content());
|
||||
$this->skipto('>');
|
||||
|
||||
return $boucle;
|
||||
}
|
||||
else if ($token_type === PexToken::EBT)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Controle fermeture TEST SI: $token\n", $this->pile_boucle_courante);}
|
||||
|
||||
$this->controle_fermeture_boucle($token);
|
||||
|
||||
return 'stop';
|
||||
}
|
||||
else if ($token_type === PexToken::FBT)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Controle fermeture TEST ELSE: $token\n", $this->pile_boucle_courante); }
|
||||
|
||||
$this->controle_fermeture_boucle($token);
|
||||
|
||||
return 'stop';
|
||||
}
|
||||
else if ($token_type === PexToken::OCM)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Ouverture commentaire: $token\n", $this->pile_boucle_courante); }
|
||||
$this->in_comment = true;
|
||||
|
||||
return 'vide';
|
||||
}
|
||||
else if ($token_type === PexToken::FCM)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Controle fermeture TEST ELSE: $token\n", $this->pile_boucle_courante); }
|
||||
$this->in_comment = false;
|
||||
$this->skipto('>');
|
||||
|
||||
return 'vide';
|
||||
}
|
||||
else if ($token !== '')
|
||||
{
|
||||
return new PexTexte($token);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'vide';
|
||||
}
|
||||
}
|
||||
|
||||
function skipto($val)
|
||||
{
|
||||
$ret = false;
|
||||
|
||||
while ( ( ($tok = next($this->tokens)) !== false) && $tok != $val )
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("skipping $tok"); }
|
||||
$ret = $tok;
|
||||
}
|
||||
}
|
||||
|
||||
function parse_content()
|
||||
{
|
||||
$contenu = new ContenuElement();
|
||||
|
||||
$i = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
$token = next($this->tokens);
|
||||
|
||||
// Done !
|
||||
if ($token === FALSE)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("No more tokens.");}
|
||||
|
||||
// Si on est encore dans un commentaire, failed !
|
||||
if ($this->in_comment)
|
||||
{
|
||||
die('Erreur de syntaxe: un commentaire n\'a pas été fermé.');
|
||||
}
|
||||
|
||||
// S'il reste des choses dans la pile des noms, des boucles n'ont pas été fermées correctement.
|
||||
if (count($this->pile_nom_boucles) > 0)
|
||||
{
|
||||
die('Erreur de syntaxe: une ou plusieurs boucles n\'ont pas été fermées: '.implode(', ', $this->pile_nom_boucles));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$res = $this->process_token($token);
|
||||
|
||||
if ($res == 'vide')
|
||||
continue;
|
||||
else if ($res == 'stop')
|
||||
break;
|
||||
else
|
||||
$contenu->ajouter($res);
|
||||
}
|
||||
|
||||
return $contenu;
|
||||
}
|
||||
}
|
||||
?>
|
||||
136
www/classes/parseur/BoucleConditionnelle.class.php
Normal file
136
www/classes/parseur/BoucleConditionnelle.class.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) 2005-2013 OpenStudio */
|
||||
/* email : info@thelia.fr */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
class BoucleConditionnelle extends PexElement{
|
||||
public $nom;
|
||||
public $contenu;
|
||||
|
||||
public $valeur;
|
||||
|
||||
function __construct($nom)
|
||||
{
|
||||
$this->nom = $nom;
|
||||
$this->contenu = array();
|
||||
}
|
||||
|
||||
function type()
|
||||
{
|
||||
return PexToken::TYPE_BOUCLE_COND;
|
||||
}
|
||||
|
||||
function evaluer(&$substitutions = array())
|
||||
{
|
||||
// Evaluer la boucle. Le scope des variables positionnes par cette boucle
|
||||
// n'est pas propage au contenu des boucles imbriquées
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Eval boucle conditionnelle $this->nom"); }
|
||||
|
||||
$si = $this->contenu[0]->evaluer($substitutions);
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Eval boucle conditionnelle $this->nom: ", $si); }
|
||||
|
||||
// Trouver la boucle concernée, ou la première boucle si aucun nom de boucle ne matche
|
||||
$premiere_boucle = false;
|
||||
$boucle_test = false;
|
||||
$nb_boucles = 0;
|
||||
|
||||
foreach($this->contenu[0]->elements as &$element)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("checking element nom='$element->nom', type=".$element->type(),':', $element); }
|
||||
|
||||
if ($element->type() == PexToken::TYPE_BOUCLE_SIMPLE)
|
||||
{
|
||||
$nb_boucles++;
|
||||
|
||||
if ($premiere_boucle === false) $premiere_boucle = &$element;
|
||||
|
||||
if ($element->nom == $this->nom)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Boucle 'si' trouve pour $this->nom"); }
|
||||
|
||||
$boucle_test = &$element;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Par defaut, la boucle est vide.
|
||||
$est_vide = true;
|
||||
|
||||
// Aucune boucle trouvée ? On evalue le texte de la condition 'si'
|
||||
if ($nb_boucles == 0)
|
||||
{
|
||||
$est_vide = trim($si) != '';
|
||||
}
|
||||
// Une boucle ? On regarde si elle est vide
|
||||
else if ($boucle_test === false)
|
||||
{
|
||||
if ($premiere_boucle === false)
|
||||
{
|
||||
die ("Boucle conditionnelle T_$this->nom: boucle THELIA_$this->nom non trouvée.");
|
||||
}
|
||||
else
|
||||
{
|
||||
$est_vide = $premiere_boucle->est_vide;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$est_vide = $boucle_test->est_vide;
|
||||
}
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("boucle $this->nom ", $est_vide ? " Vide" : " Non vide"); }
|
||||
|
||||
if ($est_vide)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Eval expression 'vide'"); }
|
||||
|
||||
return $this->contenu[1]->evaluer($substitutions);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Retourne expression 'non vide'"); }
|
||||
|
||||
return $si;
|
||||
}
|
||||
}
|
||||
|
||||
function ajouter($data)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("BoucleConditionnelle ajout:", $data); }
|
||||
|
||||
$this->contenu[] = $data;
|
||||
}
|
||||
|
||||
function imprimer()
|
||||
{
|
||||
Analyse::echo_debug("[SI $this->nom]");
|
||||
if ($this->contenu[0]) $this->contenu[0]->imprimer();
|
||||
Analyse::echo_debug("[SINON $this->nom]");
|
||||
if ($this->contenu[1]) $this->contenu[1]->imprimer();
|
||||
Analyse::echo_debug("[FINSI $this->nom]");
|
||||
}
|
||||
}
|
||||
?>
|
||||
64
www/classes/parseur/BoucleConditionnelleVariable.class.php
Normal file
64
www/classes/parseur/BoucleConditionnelleVariable.class.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : thelia@openstudio.fr */
|
||||
/* web : http://www.openstudio.fr */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* Ê Êalong with this program. ÊIf not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
class BoucleConditionnelleVariable extends PexElement{
|
||||
public $nom;
|
||||
public $contenu;
|
||||
|
||||
function __construct($nom)
|
||||
{
|
||||
$this->nom = $nom;
|
||||
$this->contenu = array();
|
||||
}
|
||||
|
||||
function type()
|
||||
{
|
||||
return PexToken::TYPE_BOUCLE_COND_VARIABLE;
|
||||
}
|
||||
|
||||
function evaluer(&$substitutions = array())
|
||||
{
|
||||
$idx = isset($substitutions['#'.$this->nom]) && $substitutions['#'.$this->nom] != '' ? 0 : 1;
|
||||
|
||||
return $this->contenu[$idx]->evaluer($substitutions);
|
||||
}
|
||||
|
||||
function ajouter($data)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("BoucleConditionnelleVariable ajout:", $data); }
|
||||
|
||||
$this->contenu[] = $data;
|
||||
}
|
||||
|
||||
function imprimer()
|
||||
{
|
||||
Analyse::echo_debug("[SI $this->nom]");
|
||||
if ($this->contenu[0]) $this->contenu[0]->imprimer();
|
||||
Analyse::echo_debug("[SINON $this->nom]");
|
||||
if ($this->contenu[1]) $this->contenu[1]->imprimer();
|
||||
Analyse::echo_debug("[FINSI $this->nom]");
|
||||
}
|
||||
}
|
||||
?>
|
||||
88
www/classes/parseur/BoucleRepeter.class.php
Normal file
88
www/classes/parseur/BoucleRepeter.class.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) 2005-2013 OpenStudio */
|
||||
/* email : info@thelia.fr */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
class BoucleRepeter extends PexElement{
|
||||
public $nom;
|
||||
public $contenu;
|
||||
public $args;
|
||||
|
||||
function __construct($nom)
|
||||
{
|
||||
$this->nom = $nom;
|
||||
}
|
||||
|
||||
function type()
|
||||
{
|
||||
return PexToken::TYPE_BOUCLE_REPETER;
|
||||
}
|
||||
|
||||
function set_args($args)
|
||||
{
|
||||
$this->args = $args;
|
||||
}
|
||||
|
||||
function ajouter($data)
|
||||
{
|
||||
$this->contenu = $data;
|
||||
}
|
||||
|
||||
function evaluer(&$substitutions = array())
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Evaluation boucle repeter $this->nom. RAW args: $this->args"); }
|
||||
|
||||
$args = $this->replace($substitutions, $this->args);
|
||||
|
||||
$debut = lireTag($args, "debut");
|
||||
$fin = lireTag($args, "fin");
|
||||
$increment = lireTag($args, "increment");
|
||||
|
||||
if ($debut == '') $debut = 1;
|
||||
if ($increment == '') $increment = 1;
|
||||
|
||||
$val = '';
|
||||
|
||||
if ($increment == 0) die("L'increment de la boucle REPETER_".$this->nom." doit être different de 0");
|
||||
|
||||
for($idx = $debut, $count = 1; $idx <= $fin; $idx += $increment, $count++)
|
||||
{
|
||||
$substitutions['#INDEX'] = $idx;
|
||||
$substitutions['#__COMPTEUR__'] = $count;
|
||||
|
||||
$val .= $this->contenu->evaluer($substitutions);
|
||||
}
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
function imprimer()
|
||||
{
|
||||
Analyse::echo_debug("[DEBUT REPETER $this->nom, args: ", $this->args, "]");
|
||||
$this->contenu->imprimer();
|
||||
Analyse::echo_debug("[FIN REPETER $this->nom]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
357
www/classes/parseur/BoucleSimple.class.php
Normal file
357
www/classes/parseur/BoucleSimple.class.php
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) 2005-2013 OpenStudio */
|
||||
/* email : info@thelia.fr */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
class BoucleSimple extends PexElement{
|
||||
public $nom;
|
||||
public $args;
|
||||
public $contenu;
|
||||
public $est_vide;
|
||||
public $variables;
|
||||
|
||||
private $compteur = 1;
|
||||
|
||||
function __construct($nom)
|
||||
{
|
||||
$this->nom = $nom;
|
||||
|
||||
$this->modules = null;
|
||||
$this->est_vide = true;
|
||||
$this->variables = array();
|
||||
}
|
||||
|
||||
function type()
|
||||
{
|
||||
return PexToken::TYPE_BOUCLE_SIMPLE;
|
||||
}
|
||||
|
||||
function set_args($args)
|
||||
{
|
||||
$this->args = $args;
|
||||
|
||||
$type_boucle = ucfirst(strtolower(lireTag($args, 'type')));
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug($this->nom, ": $type_boucle"); }
|
||||
}
|
||||
|
||||
function ajouter($data)
|
||||
{
|
||||
$this->contenu = $data;
|
||||
}
|
||||
|
||||
// Evaluer la boucle en utilisant la fonction classique
|
||||
function evaluer_boucle_classique($type_boucle, $args)
|
||||
{
|
||||
$var_template = '';
|
||||
|
||||
$this->compteur = 1;
|
||||
|
||||
// HACK: Si la liste des variables contient une variable conditionelle, assurer le traitement
|
||||
// de ces variables. Voir aussi la methode replace() de la classe PexElement
|
||||
foreach(Parseur::$VARIABLES_CONDITIONNELLES as $varcond)
|
||||
{
|
||||
if (in_array($varcond, $this->variables))
|
||||
{
|
||||
if ($var_template != '') $var_template .= PexToken::COUPLE_SEP;
|
||||
|
||||
$var_template .= '__VARCOND__'.$varcond.'__' . PexToken::ASSIGN_SEP . '#' . $varcond . '[1][0]';
|
||||
}
|
||||
}
|
||||
|
||||
usort($this->variables, array("Analyse", "strlen_cmp"));
|
||||
|
||||
foreach($this->variables as $var)
|
||||
{
|
||||
if ($var_template != '') $var_template .= PexToken::COUPLE_SEP;
|
||||
|
||||
$var_template .= $var . PexToken::ASSIGN_SEP . '#' . $var;
|
||||
}
|
||||
|
||||
// PexToken::START_MARK permet de déterminer si la boucle modifie ou remplace le texte
|
||||
// indiqué dans la boucle (plugin notation et commentaires)
|
||||
$var_template = PexToken::START_MARK . $var_template . PexToken::ITER_SEP;
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("appel boucle exec $type_boucle, args='$args', var_template='$var_template'");}
|
||||
|
||||
// Appel du boucle_exec() de base de Thélia
|
||||
$valued_text = $this->boucle_exec(strtoupper($type_boucle), $args, $var_template);
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("$this->nom: valued template='$valued_text'"); }
|
||||
|
||||
if (trim($valued_text) != '')
|
||||
{
|
||||
$boucle_subst = new EvalBoucle();
|
||||
|
||||
// Parse $texte to extract substitutions
|
||||
$rows = explode(PexToken::ITER_SEP, $valued_text);
|
||||
|
||||
// Compter le nombre de resultats
|
||||
$nbres = count($rows);
|
||||
foreach($rows as $row) if ($row == '') $nbres--;
|
||||
|
||||
foreach($rows as $row)
|
||||
{
|
||||
if ($row == '') continue;
|
||||
|
||||
$iteration = new IterationBoucle();
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("row: '$row'"); }
|
||||
|
||||
if ($row[0] != PexToken::START_MARK)
|
||||
{
|
||||
$start_pos = strpos($row, PexToken::START_MARK);
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Start mark at pos '$start_pos'"); }
|
||||
|
||||
if ($start_pos === false)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Texte remplacé par '$row'"); }
|
||||
|
||||
$iteration->remplacement = $row;
|
||||
|
||||
$boucle_subst->ajoutIteration($iteration);
|
||||
|
||||
// On n'examine pas la suite
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Texte modifié. prefixe: ".substr($row, 0, $start_pos)); }
|
||||
|
||||
// Retenir le prefixe, qui sera ajouté lors des substitutions
|
||||
$iteration->prefixe = substr($row, 0, $start_pos);
|
||||
|
||||
// Continuer , et examiner le reste.
|
||||
$row = substr($row, $start_pos + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enlever la marque de début
|
||||
$row = substr($row, 1);
|
||||
|
||||
// S'il ne reste plus rien, on ne va pas plus loin, ça ne sert à rien.
|
||||
// if ($row == '') continue;
|
||||
}
|
||||
|
||||
$vars = explode(PexToken::COUPLE_SEP, $row);
|
||||
|
||||
$line_vars = array();
|
||||
|
||||
foreach($vars as $varval)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("varval: '$varval'"); }
|
||||
|
||||
list($var, $value) = explode(PexToken::ASSIGN_SEP, $varval);
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("$var=$value"); }
|
||||
|
||||
$iteration->ajoutVarVal($var, $value);
|
||||
}
|
||||
|
||||
// Ajouter le compteur
|
||||
$iteration->ajoutVarVal('__COMPTEUR__', $this->compteur++);
|
||||
|
||||
// Ajouter le nombre de resultats total
|
||||
$iteration->ajoutVarVal('__NOMBRE__', $nbres);
|
||||
|
||||
$boucle_subst->ajoutIteration($iteration);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// la boucle est vide
|
||||
$boucle_subst = false;
|
||||
}
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("type_boucle=$type_boucle: boucle_subst: ",$boucle_subst, $boucle_subst === false ? 'FALSE' : ''); }
|
||||
|
||||
return $boucle_subst;
|
||||
}
|
||||
|
||||
function evaluer(&$substitutions = array())
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Eval boucle simple $this->nom"); }
|
||||
|
||||
// Bug signalé par tetedelard
|
||||
// Réinitialiser l'état (la boucle peut-être placée dans une boucle qui implique des iterations,
|
||||
// et influe sur les paramètres de cette boucle, et donc sur ses résultats.
|
||||
$this->est_vide = true;
|
||||
|
||||
$val = '';
|
||||
|
||||
// Effectuer les substitutions dans les arguments de la boucle a exécuter
|
||||
// avec les valeurs de la présente boucle.
|
||||
$args = $this->replace($substitutions, $this->args);
|
||||
|
||||
/*
|
||||
if (DEBUG_EVAL) {
|
||||
Analyse::echo_debug("Eval boucle simple $this->nom, args=$this->args, subst_args=$args, Substitutions: \n",
|
||||
$substitutions,
|
||||
'variables:,
|
||||
$this->variables);
|
||||
}
|
||||
*/
|
||||
$type_boucle = ucfirst(strtolower(lireTag($args, 'type')));
|
||||
|
||||
$boucle_subst = $this->evaluer_boucle_classique($type_boucle, $args);
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Eval boucle simple $this->nom, subst: ",$boucle_subst === false ? 'FALSE' : $boucle_subst, " est vide: ",$this->est_vide === false ? 'FALSE' : "TRUE"); }
|
||||
|
||||
if ($boucle_subst !== false)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Boucle simple $this->nom n'est plus vide."); }
|
||||
|
||||
// Si boucle_subst es définie, alors la boucle n'est pas vide.
|
||||
$this->est_vide = false;
|
||||
|
||||
// Evaluer la présente boucle.
|
||||
foreach($boucle_subst->iterations as $iteration)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("eval: type=".$this->contenu->type()."\nsubst: ", $iteration, "\ncontenu: "); $this->contenu->imprimer();}
|
||||
|
||||
if ($iteration->prefixe !== false)
|
||||
{
|
||||
// La boucle a place quelque chose avant le texte.
|
||||
// On l'ajoute nous aussi.
|
||||
$val .= $iteration->prefixe;
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("eval: prefixe=$iteration->prefixe"); }
|
||||
}
|
||||
|
||||
if ($iteration->remplacement !== false)
|
||||
{
|
||||
// La boucle a remplacé le texte qu'on lui a passé par un autre
|
||||
// -> on retourne simplement ce texte, sans faire d'autres évaluations
|
||||
$val .= $iteration->remplacement;
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("eval: remplacement=$iteration->remplacement"); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("eval: evaluation contenu"); }
|
||||
|
||||
$val .= $this->contenu->evaluer($iteration->varval);
|
||||
}
|
||||
}
|
||||
|
||||
// Si la boucle n'est pas vide, mais n'a retourné aucune itération,
|
||||
// il faut tout de même évaluer son contenu.
|
||||
// FIXME: retiré, car on ajoute toujours une iteration par tour de boucle
|
||||
// cf. ajoutIteration()
|
||||
// if (count($boucle_subst->iterations) == 0) $val .= $this->contenu->evaluer();
|
||||
}
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("boucle=$type_boucle vide:", $this->est_vide ? "Oui" : "Non"); }
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
function boucle_exec($type_boucle, $args, $texte, $nom_boucle = ""){
|
||||
|
||||
global $page;
|
||||
|
||||
$variables="";
|
||||
$res = "";
|
||||
|
||||
$exec_boucle = 1;
|
||||
|
||||
//$param = array(&$type_boucle, &$args, &$texte, &$nom_boucle, &$exec_boucle);
|
||||
//ActionsModules::instance()->appel_module( "avantboucle", $param);
|
||||
|
||||
if($exec_boucle)
|
||||
switch($type_boucle){
|
||||
case 'RUBRIQUE' : $res .= boucleRubrique($texte, $args); break;
|
||||
case 'DOSSIER' : $res .= boucleDossier($texte, $args); break;
|
||||
case 'CONTENU' : $res .= boucleContenu($texte, $args); break;
|
||||
case 'CONTENUASSOC' : $res .= boucleContenuassoc($texte, $args); break;
|
||||
case 'PRODUIT' : $res .= boucleProduit($texte, $args); break;
|
||||
case 'PAGE' : $res .= bouclePage($texte, $args); break;
|
||||
case 'PANIER' : $res .= bouclePanier($texte, $args); break;
|
||||
case 'QUANTITE' : $res .= boucleQuantite($texte, $args); break;
|
||||
case 'CHEMIN' : $res .= boucleChemin($texte, $args); break;
|
||||
case 'CHEMINDOS' : $res .= boucleChemindos($texte, $args); break;
|
||||
case 'PAIEMENT' : $res .= bouclePaiement($texte, $args); break;
|
||||
case 'ADRESSE' : $res .= boucleAdresse($texte, $args); break;
|
||||
case 'VENTEADR' : $res .= boucleVenteadr($texte, $args); break;
|
||||
case 'COMMANDE' : $res .= boucleCommande($texte, $args); break;
|
||||
case 'VENTEPROD' : $res .= boucleVenteprod($texte, $args); break;
|
||||
case 'IMAGE' : $res .= boucleImage($texte, $args); break;
|
||||
case 'DOCUMENT' : $res .= boucleDocument($texte, $args); break;
|
||||
case 'ACCESSOIRE' : $res .= boucleAccessoire($texte, $args); break;
|
||||
case 'TRANSPORT' : $res .= boucleTransport($texte, $args); break;
|
||||
case 'PAYS' : $res .= bouclePays($texte, $args); break;
|
||||
case 'CARACTERISTIQUE' : $res .= boucleCaracteristique($texte, $args); break;
|
||||
case 'CARACDISP' : $res .= boucleCaracdisp($texte, $args); break;
|
||||
case 'CARACVAL' : $res .= boucleCaracval($texte, $args); break;
|
||||
case 'DEVISE' : $res .= boucleDevise($texte, $args); break;
|
||||
case 'CLIENT' : $res .= boucleClient($texte, $args); break;
|
||||
case 'DECLINAISON' : $res .= boucleDeclinaison($texte, $args); break;
|
||||
case 'DECLIDISP' : $res .= boucleDeclidisp($texte, $args); break;
|
||||
case 'DECVAL' : $res .= boucleDecval($texte, $args); break;
|
||||
case 'RSS' : $res .= boucleRSS($texte, $args); break;
|
||||
case 'STOCK' : $res .= boucleStock($texte, $args); break;
|
||||
case 'PAGERUBRIQUE' : $res .= bouclePagerubrique($texte, $args); break;
|
||||
case 'RAISON' : $res .= boucleRaison($texte, $args); break;
|
||||
case 'TVA' : $res .= boucleTva($texte, $args); break;
|
||||
case 'LANGUE' : $res .= boucleLangue($texte, $args); break;
|
||||
case 'REPRISEPAIEMENT' : $res .= boucleReprisePaiement($texte, $args); break;
|
||||
default: $res.= $this->moduleBoucle($type_boucle, $texte, $args); break;
|
||||
}
|
||||
|
||||
else
|
||||
$res = $texte;
|
||||
|
||||
//$param = array(&$type_boucle, &$args, &$res, &$nom_boucle);
|
||||
//ActionsModules::instance()->appel_module( "apresboucle", $param);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
function moduleBoucle($type_boucle, $texte, $args){
|
||||
|
||||
try {
|
||||
$modules = new Modules();
|
||||
|
||||
if ($modules->charger(strtolower($type_boucle)) && $modules->actif) {
|
||||
|
||||
$instance = ActionsModules::instance()->instancier($modules->nom);
|
||||
|
||||
if (method_exists($instance, 'boucle'))
|
||||
return $instance->boucle($texte, $args);
|
||||
}
|
||||
} catch (Exception $ex) {}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function imprimer()
|
||||
{
|
||||
Analyse::echo_debug("[DEBUT $this->nom, args: ", $this->args, "]");
|
||||
$this->contenu->imprimer();
|
||||
Analyse::echo_debug("[FIN $this->nom]");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
148
www/classes/parseur/BoucleTest.class.php
Normal file
148
www/classes/parseur/BoucleTest.class.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : info@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
class BoucleTest extends PexElement{
|
||||
public $nom;
|
||||
public $contenu;
|
||||
public $args;
|
||||
|
||||
function __construct($nom)
|
||||
{
|
||||
$this->nom = $nom;
|
||||
$this->contenu = array();
|
||||
}
|
||||
|
||||
function type()
|
||||
{
|
||||
return PexToken::TYPE_BOUCLE_TEST;
|
||||
}
|
||||
|
||||
function set_args($args)
|
||||
{
|
||||
$this->args = $args;
|
||||
}
|
||||
|
||||
function ajouter($data)
|
||||
{
|
||||
$this->contenu[] = $data;
|
||||
}
|
||||
|
||||
function evaluer(&$substitutions = array())
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Evaluation boucle test $this->nom. RAW args: $this->args"); }
|
||||
|
||||
$args = $this->replace($substitutions, $this->args);
|
||||
|
||||
$var = lireTag($args, "variable");
|
||||
if ($var == '') $var = lireTag($args, "var");
|
||||
|
||||
$test = lireTag($args, "test");
|
||||
$val = lireTag($args, "valeur");
|
||||
if ($val == '') $val = lireTag($args, "val");
|
||||
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Boucle test: args='$args', var='$var', test='$test', val='$val'"); }
|
||||
|
||||
$vrai = false;
|
||||
|
||||
switch(strtolower($test))
|
||||
{
|
||||
case "vide" :
|
||||
$vrai = trim($var) == '';
|
||||
break;
|
||||
|
||||
case "nonvide" :
|
||||
$vrai = trim($var) != '';
|
||||
break;
|
||||
|
||||
case "egal" :
|
||||
$vrai = ($var == $val);
|
||||
break;
|
||||
|
||||
case "different" :
|
||||
$vrai = ($var != $val);
|
||||
break;
|
||||
|
||||
case "superieur" :
|
||||
$vrai = ($var > $val);
|
||||
break;
|
||||
|
||||
case "superieurouegal" :
|
||||
$vrai = ($var >= $val);
|
||||
break;
|
||||
|
||||
case "inferieur" :
|
||||
$vrai = ($var < $val);
|
||||
break;
|
||||
|
||||
case "inferieurouegal" :
|
||||
$vrai = ($var <= $val);
|
||||
break;
|
||||
|
||||
case "dansliste" :
|
||||
$sep = lireTag($args, "separateur");
|
||||
|
||||
if (empty($sep)) $sep = ",";
|
||||
|
||||
$vrai = in_array($var, explode($sep, $val));
|
||||
break;
|
||||
|
||||
case "contient" :
|
||||
$vrai = strstr($var, $val) !== false;
|
||||
break;
|
||||
|
||||
// Contribution de asturyan
|
||||
case "modulo" :
|
||||
$val = explode(",", $val);
|
||||
|
||||
$vrai = ($var % $val[0] == $val[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
die("L'argument 'test' de la boucle $this->nom est manquant ou inconnu: '$test'");
|
||||
break;
|
||||
}
|
||||
|
||||
if ($vrai)
|
||||
{
|
||||
return $this->contenu[0]->evaluer($substitutions);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->contenu[1]->evaluer($substitutions);
|
||||
}
|
||||
}
|
||||
|
||||
function imprimer()
|
||||
{
|
||||
Analyse::echo_debug("[TEST_VRAI $this->nom $args]");
|
||||
if ($this->contenu[0]) $this->contenu[0]->imprimer();
|
||||
Analyse::echo_debug("[TEST_FAUX $this->nom]");
|
||||
if ($this->contenu[1]) $this->contenu[1]->imprimer();
|
||||
Analyse::echo_debug("[TEST_FIN $this->nom]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
98
www/classes/parseur/ContenuElement.class.php
Normal file
98
www/classes/parseur/ContenuElement.class.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) 2005-2013 OpenStudio */
|
||||
/* email : info@thelia.fr */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
class ContenuElement extends PexElement{
|
||||
public $elements;
|
||||
public $idx;
|
||||
public $last_type;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->elements = array();
|
||||
|
||||
$this->idx = 0;
|
||||
|
||||
$this->last_type = -1;
|
||||
}
|
||||
|
||||
function type()
|
||||
{
|
||||
return PexToken::TYPE_CONTENU;
|
||||
}
|
||||
|
||||
function ajouter($element)
|
||||
{
|
||||
// Merge subsequent text elements
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Contenu ajouter: idx=".$this->idx.", last_type=".$this->last_type.", element type=".$element->type());}
|
||||
|
||||
if ($this->idx > 0
|
||||
&&
|
||||
$this->last_type == PexToken::TYPE_TEXTE
|
||||
&&
|
||||
$element->type() == PexToken::TYPE_TEXTE)
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Contenu append: "); $element->imprimer();}
|
||||
|
||||
$this->elements[$this->idx-1]->ajouter($element->texte);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Contenu ajout:"); $element->imprimer(); }
|
||||
|
||||
$this->elements[] = $element;
|
||||
|
||||
$this->last_type = $element->type();
|
||||
|
||||
//if (DEBUG_PARSER) { Analyse::echo_debug("Après ajout: last_type=".$this->last_type); }
|
||||
|
||||
$this->idx++;
|
||||
}
|
||||
}
|
||||
|
||||
function evaluer(&$substitutions = array())
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Eval contenu $this->idx"); }
|
||||
|
||||
$val = '';
|
||||
|
||||
foreach($this->elements as $element)
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("CONT:eval ". $element->type()); $element->imprimer();}
|
||||
|
||||
$val .= $element->evaluer($substitutions);
|
||||
}
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
function imprimer()
|
||||
{
|
||||
foreach($this->elements as $element)
|
||||
{
|
||||
$element->imprimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
44
www/classes/parseur/EvalBoucle.class.php
Normal file
44
www/classes/parseur/EvalBoucle.class.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) 2005-2013 OpenStudio */
|
||||
/* email : info@thelia.fr */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
// Stocke les infos sur une boucle pendant son évaluation
|
||||
class EvalBoucle{
|
||||
public $iterations;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->iterations = array();
|
||||
}
|
||||
|
||||
public function ajoutIteration($iteration)
|
||||
{
|
||||
/*
|
||||
Retiré: if ($iteration->estValuee())
|
||||
On ajoute une iteration par tour de boucle, comme le fait le parser de base.
|
||||
*/
|
||||
$this->iterations[] = $iteration;
|
||||
}
|
||||
}
|
||||
?>
|
||||
47
www/classes/parseur/IterationBoucle.class.php
Normal file
47
www/classes/parseur/IterationBoucle.class.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) 2005-2013 OpenStudio */
|
||||
/* email : info@thelia.fr */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
// Définit les données resultant d'une iteration de boucle
|
||||
class IterationBoucle{
|
||||
public $remplacement;
|
||||
public $prefixe;
|
||||
public $varval;
|
||||
|
||||
public function __construct(){
|
||||
$this->remplacement = false;
|
||||
$this->prefixe = false;
|
||||
$this->varval = array();
|
||||
}
|
||||
|
||||
public function ajoutVarVal($var, $value){
|
||||
if (trim($var) != '') $this->varval['#'.$var] = $value;
|
||||
}
|
||||
|
||||
public function estValuee(){
|
||||
return count($this->varval) > 0 || $this->remplacement !== false || $this->prefixe !== false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
63
www/classes/parseur/PexElement.class.php
Normal file
63
www/classes/parseur/PexElement.class.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) 2005-2013 OpenStudio */
|
||||
/* email : info@thelia.fr */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
// Classe de base des éléments de template
|
||||
abstract class PexElement{
|
||||
public abstract function imprimer();
|
||||
public abstract function evaluer(&$substitutions = array());
|
||||
public abstract function ajouter($data);
|
||||
public abstract function type();
|
||||
|
||||
public function replace($substitutions, $texte){
|
||||
if (trim($texte) == '' /* || count($substitutions) == 0 */) return $texte;
|
||||
|
||||
$val = &$texte;
|
||||
|
||||
// Cas spécial des variables conditionnelles
|
||||
foreach(Parseur::$VARIABLES_CONDITIONNELLES as $varcond)
|
||||
{
|
||||
if (isset($substitutions['#__VARCOND__'.$varcond.'__']))
|
||||
{
|
||||
$num_exp = $substitutions['#__VARCOND__'.$varcond.'__'] == '1' ? '1' : '2';
|
||||
|
||||
$val = preg_replace('/#'.$varcond.'\[([^]]*)\]\[([^]]*)\]/', "\\$num_exp", $texte);
|
||||
}
|
||||
}
|
||||
|
||||
$subs = str_replace(array_keys($substitutions), array_values($substitutions), $val);
|
||||
|
||||
// Traiter les variables de template s'il y en a
|
||||
if (strpos($subs, '#SET') !== false || strpos($subs, '#GET') !== false || strpos($subs, '#ENV') !== false || strpos($subs, '#SESSION') !== false)
|
||||
{
|
||||
include_once(__DIR__.'/VariablesTemplate.class.php');
|
||||
|
||||
$subs = VariablesTemplate::analyser($subs);
|
||||
}
|
||||
|
||||
return $subs;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
57
www/classes/parseur/PexTexte.class.php
Normal file
57
www/classes/parseur/PexTexte.class.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : info@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
class PexTexte extends PexElement{
|
||||
public $texte;
|
||||
|
||||
function __construct(&$texte)
|
||||
{
|
||||
$this->texte = $texte;
|
||||
}
|
||||
|
||||
function type()
|
||||
{
|
||||
return PexToken::TYPE_TEXTE;
|
||||
}
|
||||
|
||||
function ajouter($texte)
|
||||
{
|
||||
$this->texte .= $texte;
|
||||
}
|
||||
|
||||
function evaluer(&$substitutions = array())
|
||||
{
|
||||
if (DEBUG_EVAL) { Analyse::echo_debug("Eval texte '$this->texte'"); }
|
||||
|
||||
return $this->replace($substitutions, $this->texte);
|
||||
}
|
||||
|
||||
function imprimer()
|
||||
{
|
||||
Analyse::echo_debug($this->texte);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
63
www/classes/parseur/PexToken.interface.php
Normal file
63
www/classes/parseur/PexToken.interface.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : info@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
// Tokens and separators
|
||||
// ---------------------
|
||||
interface PexToken{
|
||||
// Token types
|
||||
const OBS = 1;
|
||||
const FBS = 2;
|
||||
const OBC = 3;
|
||||
const EBC = 4;
|
||||
const FBC = 5;
|
||||
const TXT = 7;
|
||||
const OBT = 8;
|
||||
const EBT = 9;
|
||||
const FBT = 10;
|
||||
const OCM = 11;
|
||||
const FCM = 12;
|
||||
const OBR = 13;
|
||||
const FBR = 14;
|
||||
const OBCV = 15;
|
||||
const EBCV = 16;
|
||||
const FBCV = 17;
|
||||
|
||||
// Element types
|
||||
const TYPE_BOUCLE_SIMPLE = 1;
|
||||
const TYPE_BOUCLE_COND = 2;
|
||||
const TYPE_BOUCLE_TEST = 21;
|
||||
const TYPE_TEXTE = 3;
|
||||
const TYPE_CONTENU = 4;
|
||||
const TYPE_BOUCLE_REPETER = 5;
|
||||
const TYPE_BOUCLE_COND_VARIABLE = 6;
|
||||
|
||||
// Separateurs
|
||||
const ITER_SEP = "\x01";
|
||||
const COUPLE_SEP = "\x02";
|
||||
const ASSIGN_SEP = "\x03";
|
||||
const START_MARK = "\x04";
|
||||
}
|
||||
|
||||
?>
|
||||
297
www/classes/parseur/VariablesTemplate.class.php
Normal file
297
www/classes/parseur/VariablesTemplate.class.php
Normal file
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) 2005-2013 OpenStudio */
|
||||
/* email : info@thelia.fr */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
// ------------------------------------------------------------------
|
||||
// Traitement de variables de template, avec la syntaxe:
|
||||
// #SET{var, valeur}, #GET{var [, defaut]} et #ENV{var [, defaut]}
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
require_once __DIR__ . "/../../fonctions/autoload.php";
|
||||
|
||||
class VariablesTemplate
|
||||
{
|
||||
private static $instance = null;
|
||||
|
||||
private static $symboles = array();
|
||||
|
||||
private static $modules = false;
|
||||
|
||||
// Trouver tous les plugins avec une fonction post() et #FILTRE dans leur code
|
||||
private function trouver_modules_filtre()
|
||||
{
|
||||
if (self::$modules !== false) return;
|
||||
|
||||
self::$modules = array();
|
||||
|
||||
// Trouver tous les modules ayant '#FILTRE' dans leur code (hack pour la perf)
|
||||
$liste = ActionsModules::instance()->lister(false, true);
|
||||
|
||||
foreach($liste as $module) {
|
||||
|
||||
try {
|
||||
$class_name = ucfirst($module->nom);
|
||||
|
||||
$class_file = ActionsModules::instance()->lire_chemin_module . "/" . $class_name. ".class.php";
|
||||
|
||||
if (file_exists($class_file))
|
||||
{
|
||||
$code = file_get_contents($class_file);
|
||||
|
||||
if (strpos($code, '#FILTRE') !== false)
|
||||
{
|
||||
$instance = ActionsModules::instance()->instancier($module->nom);
|
||||
|
||||
if (method_exists($instance, 'post'))
|
||||
{
|
||||
self::$modules[] = $clazz;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {}
|
||||
}
|
||||
}
|
||||
|
||||
public static function analyser($texte)
|
||||
{
|
||||
if (self::$instance == null) self::$instance = new VariablesTemplate();
|
||||
|
||||
return self::$instance->demarrer($texte);
|
||||
}
|
||||
|
||||
private function syntax_error($text)
|
||||
{
|
||||
die("Erreur de syntaxe: $text");
|
||||
}
|
||||
|
||||
// Appliquer les filtres de base et les filtres utilisateur
|
||||
private function appliquer_filtres($texte)
|
||||
{
|
||||
global $res;
|
||||
|
||||
if (strpos($texte, '#FILTRE') !== false)
|
||||
{
|
||||
$this->trouver_modules_filtre();
|
||||
|
||||
$tmp_res = $res;
|
||||
|
||||
// Filtres standard
|
||||
// $res = filtres($texte);
|
||||
Filtres::exec($texte);
|
||||
|
||||
$res = $texte;
|
||||
|
||||
// Filtres utilisateur
|
||||
foreach(self::$modules as $module)
|
||||
{
|
||||
$module->post();
|
||||
}
|
||||
|
||||
$res = $tmp_res;
|
||||
}
|
||||
|
||||
return $texte;
|
||||
}
|
||||
|
||||
|
||||
// Récupérer une valeur de variable, avec filtrage éventuel, et valeur par defaut
|
||||
// si la variable ne peut être valuée.
|
||||
private function filtrer_var($type, $var, $defaut = '')
|
||||
{
|
||||
if ($type == 'ENV' && isset($_REQUEST[$var]))
|
||||
{
|
||||
$var = is_array($_REQUEST[$var]) ? implode(',', $_REQUEST[$var]) : $_REQUEST[$var];
|
||||
|
||||
return strip_tags($var);
|
||||
}
|
||||
else if ($type == 'GET' && isset(self::$symboles[$var]) && self::$symboles[$var] != '')
|
||||
{
|
||||
return self::$symboles[$var];
|
||||
}
|
||||
else if ($type == 'SESSION' && isset($_SESSION["thelia_$var"]) && $_SESSION["thelia_$var"] != '')
|
||||
{
|
||||
return $_SESSION["thelia_$var"];
|
||||
}
|
||||
|
||||
return $defaut;
|
||||
}
|
||||
|
||||
private function analyser_nom_var()
|
||||
{
|
||||
$var = trim(next($this->tokens));
|
||||
|
||||
if (! preg_match('/^[\w\:]+$/', $var)) $this->syntax_error("Nom de variable invalide: '$var'");
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
private function analyser_set($directive)
|
||||
{
|
||||
//Parser::echo_debug("get_set()");
|
||||
|
||||
$tok = next($this->tokens);
|
||||
|
||||
if ($tok == '{')
|
||||
{
|
||||
$var = $this->analyser_nom_var();
|
||||
|
||||
if (next($this->tokens) == ',')
|
||||
{
|
||||
// Lire jusqu'<27> la fermeture
|
||||
$val = $this->analyser_contenu('}');
|
||||
|
||||
if (current($this->tokens) == '}')
|
||||
{
|
||||
$val = $this->appliquer_filtres(trim($val));
|
||||
|
||||
if ($directive == 'SET')
|
||||
{
|
||||
// Evaluer les filtres THELIA sur la valeur
|
||||
self::$symboles[$var] = $val;
|
||||
}
|
||||
else if ($directive == 'SESSION_SET')
|
||||
{
|
||||
$_SESSION["thelia_$var"] = $val;
|
||||
}
|
||||
|
||||
// Parser::echo_debug("FIN $directive $var = $val");
|
||||
|
||||
return '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->syntax_error("$directive $var: } attendu, $tok trouv<75>.");
|
||||
}
|
||||
}
|
||||
else if (current($this->tokens) == '}')
|
||||
{
|
||||
if ($directive == 'SET')
|
||||
{
|
||||
unset(self::$symboles[$var]);
|
||||
}
|
||||
else if ($directive == 'SESSION_SET')
|
||||
{
|
||||
unset($_SESSION["thelia_$var"]);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->syntax_error("$directive $var: ',' attendu $tok trouv<75>.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $tok;
|
||||
}
|
||||
}
|
||||
|
||||
private function analyser_get($type)
|
||||
{
|
||||
//Parser::echo_debug( "analyser_get()");
|
||||
|
||||
// Lire jusqu'<27> la fermeture
|
||||
if (($tok = next($this->tokens)) == '{')
|
||||
{
|
||||
$var = $this->analyser_nom_var();
|
||||
|
||||
if (($tok = next($this->tokens)) == ',')
|
||||
{
|
||||
// Une valeur par defaut - appliquer les filtres Thelia à cette valeur
|
||||
$defaut = $this->appliquer_filtres(trim($this->analyser_contenu('}')));
|
||||
|
||||
return $this->filtrer_var($type, $var, $defaut);
|
||||
}
|
||||
else if ($tok == '}')
|
||||
{
|
||||
// Pas de valeur par defaut
|
||||
return $this->filtrer_var($type, $var);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->syntax_error("$type $var: ',' ou '}' attendu, $tok trouv<75>.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $tok;
|
||||
}
|
||||
}
|
||||
|
||||
private function analyser_contenu($stopchar = '')
|
||||
{
|
||||
// Parser::echo_debug( "analyser_contenu($stopchar)");
|
||||
|
||||
$content = '';
|
||||
|
||||
while (($tok = next($this->tokens)) !== false)
|
||||
{
|
||||
if ($tok == '#')
|
||||
{
|
||||
$tok = next($this->tokens);
|
||||
|
||||
if ($tok == 'SET' || $tok == 'SESSION_SET')
|
||||
{
|
||||
$this->analyser_set($tok);
|
||||
}
|
||||
else if ($tok == 'GET' || $tok == 'ENV' || $tok == 'SESSION')
|
||||
{
|
||||
$content .= $this->analyser_get($tok);
|
||||
}
|
||||
else
|
||||
{
|
||||
$content .= '#'.$tok;
|
||||
}
|
||||
}
|
||||
else if ($stopchar != '' && $tok == $stopchar)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$content .= $tok;
|
||||
}
|
||||
}
|
||||
|
||||
// Parser::echo_debug( "parsing done.");
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function demarrer($chaine)
|
||||
{
|
||||
$this->tokens = preg_split('/(\#|\{|\}|,)/', $chaine, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
// Comme on fait un next() dans parse content, insérer une valeur non significative en début de tableau
|
||||
array_unshift($this->tokens, '');
|
||||
|
||||
//Parser::echo_debug("Tokens:", $this->tokens);
|
||||
|
||||
$content = $this->analyser_contenu();
|
||||
|
||||
//Parser::echo_debug("Content:", $content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user