1559 lines
65 KiB
PHP
Executable File
1559 lines
65 KiB
PHP
Executable File
<?php
|
|
|
|
/*
|
|
Licence et conditions d'utilisations-----------------------------------------------------------------------------
|
|
|
|
-English---------------------------------------------------------------------------------------------------------
|
|
Copyright (C) 2001-2004 Thierry ANDRE
|
|
|
|
- ORIGINAL AUTHOR
|
|
- ANDRE thierry
|
|
- CURRENT MAINTAINER
|
|
- TRICHARD Rémy
|
|
- ADDING
|
|
- VILDAY Laurent.
|
|
- MOULRON Diogène.
|
|
- DELVILLE Romain.
|
|
- BOUCHERY Frederic.
|
|
- PERRICHOT Florian.
|
|
- RODIER Phillipe.
|
|
- HOUZE Sébastien.
|
|
- DECLEE Frédéric.
|
|
- HORDEAUX Sébastien.
|
|
- LELARGE Guillaume.
|
|
- GAUTHIER Jérémy.
|
|
- CASANOVA Matthieu.
|
|
- KELLER Christophe.
|
|
- MARK HUMPHREYS Aidan.
|
|
- KELLUM Patrick.
|
|
- DE CORNUAUD Sébastien.
|
|
- PIEL Régis.
|
|
- LE LOARER Loïc.
|
|
- TRICHARD Rémy
|
|
|
|
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
|
|
Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
|
|
any later version.
|
|
|
|
This library 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 Lesser General Public License for more
|
|
details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to :
|
|
|
|
Free Software Foundation,
|
|
Inc., 59 Temple Place,
|
|
Suite 330, Boston,
|
|
MA 02111-1307, Etats-Unis.
|
|
------------------------------------------------------------------------------------------------------------------
|
|
|
|
-Français---------------------------------------------------------------------------------------------------------
|
|
ModeliXe est distribué sous licence LGPL, merci de laisser cette en-tête, gage et garantie de cette licence.
|
|
ModeliXe est un moteur de template destiné à être utilisé par des applications écrites en PHP.
|
|
ModeliXe peut être utilisé dans des scripts vendus à des tiers aux titres de la licence LGPL. ModeliXe n'en reste
|
|
pas moins OpenSource et libre de droits en date du 23 Août 2001.
|
|
|
|
Copyright (C) 2001-2004 Thierry ANDRE
|
|
|
|
- Auteur original
|
|
- ANDRE thierry
|
|
- Mainteneur actuel du projet
|
|
- TRICHARD Rémy
|
|
- Ajouts
|
|
- VILDAY Laurent.
|
|
- MOULRON Diogène.
|
|
- DELVILLE Romain.
|
|
- BOUCHERY Frederic.
|
|
- PERRICHOT Florian.
|
|
- RODIER Phillipe.
|
|
- HOUZE Sébastien.
|
|
- DECLEE Frédéric.
|
|
- HORDEAUX Sébastien.
|
|
- LELARGE Guillaume.
|
|
- GAUTHIER Jérémy.
|
|
- CASANOVA Matthieu.
|
|
- KELLER Christophe.
|
|
- MARK HUMPHREYS Aidan.
|
|
- KELLUM Patrick.
|
|
- DE CORNUAUD Sébastien.
|
|
- PIEL Régis.
|
|
- LE LOARER Loïc.
|
|
- TRICHARD Rémy
|
|
|
|
Cette bibliothèque est libre, vous pouvez la redistribuer et/ou la modifier selon les termes de la Licence Publique
|
|
Générale GNU Limitée publiée par la Free Software Foundation version 2.1 et ultérieure.
|
|
|
|
Cette bibliothèque est distribuée car potentiellement utile, mais SANS AUCUNE GARANTIE, ni explicite ni implicite,
|
|
y compris les garanties de commercialisation ou d'adaptation dans un but spécifique. Reportez-vous à la Licence
|
|
Publique Générale GNU Limitée pour plus de détails.
|
|
|
|
Vous devez avoir reçu une copie de la Licence Publique Générale GNU Limitée en même temps que cette bibliothèque;
|
|
si ce n'est pas le cas, écrivez à:
|
|
|
|
Free Software Foundation,
|
|
Inc., 59 Temple Place,
|
|
Suite 330, Boston,
|
|
MA 02111-1307, Etats-Unis.
|
|
|
|
Pour tout renseignements mailez à modelixe@free.fr ou tungsten180@hotmail.com
|
|
--------------------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
//Initialisation de l'include_path
|
|
$os = ((stristr(getenv('SERVER_SOFTWARE'), 'win') || stristr(getenv('SERVER_SOFTWARE'), 'microsoft'))? ';' : ':');
|
|
$path = ((defined('MX_GENERAL_PATH'))? MX_GENERAL_PATH : '').$os.((defined('MX_ERROR_PATH'))? MX_ERROR_PATH : '').$os.ini_get('include_path');
|
|
ini_set('include_path', $path);
|
|
|
|
//Inclusion du fichier de configuration et de Error Manager
|
|
//require_once('Mxconf.php');
|
|
//require_once('ErrorManager.php');
|
|
|
|
//Désactivation de magic_quotes_runtime de php.ini
|
|
if (get_magic_quotes_runtime()) set_magic_quotes_runtime(0);
|
|
|
|
class ModeliXe extends ErrorManager{
|
|
|
|
var $template = '';
|
|
var $absolutePath = '';
|
|
var $relativePath = '';
|
|
var $sessionParameter = '';
|
|
var $mXParameterFile = '';
|
|
var $mXTemplatePath = '';
|
|
var $mXCachePath = '';
|
|
var $mXUrlKey = '';
|
|
|
|
var $outputSystem = '/>';
|
|
var $flagSystem = 'xml';
|
|
var $adressSystem = 'relative';
|
|
var $mXVersion = '1.2';
|
|
|
|
var $mXCacheDelay = 0;
|
|
var $debut = 0;
|
|
var $fin = 0;
|
|
var $ExecutionTime = 0;
|
|
|
|
var $mXcompress = false;
|
|
var $mXsetting = false;
|
|
var $mXmodRewrite = false;
|
|
var $performanceTracer = false;
|
|
var $mXoutput = false;
|
|
|
|
var $mXsignature = true;
|
|
var $isTemplateFile = true;
|
|
|
|
var $templateContent = array();
|
|
var $sheetBuilding = array();
|
|
var $deleted = array();
|
|
var $replacement = array();
|
|
var $loop = array();
|
|
var $IsALoop = array();
|
|
var $xPattern = array();
|
|
var $formField = array();
|
|
var $checker = array();
|
|
var $attribut = array();
|
|
var $attributKey = array();
|
|
var $htmlAtt = array();
|
|
var $select = array();
|
|
var $hidden = array();
|
|
var $image = array();
|
|
var $text = array();
|
|
var $father = array();
|
|
var $son = array();
|
|
var $plugInMethods = array();
|
|
|
|
var $flagArray = array(0 => 'hidden', 1 => 'select', 2 => 'image', 3 => 'text', 4 => 'checker', 5 => 'formField');
|
|
var $attributArray = array(0 => 'attribut');
|
|
|
|
//MX Generator----------------------------------------------------------------------------------------------------
|
|
|
|
//Constructeur de ModeliXe
|
|
// function ModeliXe ($template, $sessionParameter = '', $templateFileParameter = '', $cacheDelay = -1){
|
|
public function __construct($template, $sessionParameter = '', $templateFileParameter = '', $cacheDelay = -1){
|
|
|
|
// $this->ErrorManager();
|
|
parent::__construct();
|
|
|
|
$time = explode(' ',microtime());
|
|
$this->debut = $time[1] + $time[0];
|
|
|
|
//Gestion des paramètres par défaut
|
|
//Definition du systeme de compression
|
|
if (defined('MX_COMPRESS')) $this->SetMxCompress(MX_COMPRESS);
|
|
|
|
//Activation du mode rewrite
|
|
if (defined('MX_REWRITEURL')) $this->SetMxModRewrite(MX_REWRITEURL);
|
|
|
|
//Activation de la signature
|
|
if (defined('MX_SIGNATURE')) $this->SetMxSignature(MX_SIGNATURE);
|
|
|
|
//Définition du répertoire de template
|
|
if (defined('MX_TEMPLATE_PATH')) $this->SetMxTemplatePath(MX_TEMPLATE_PATH);
|
|
|
|
//Définition du fichier de paramétrage
|
|
if (defined('MX_DEFAULT_PARAMETER') && ! $templateFileParameter)
|
|
$this->SetMxFileParameter(MX_DEFAULT_PARAMETER);
|
|
elseif ($templateFileParameter != '')
|
|
$this->SetMxFileParameter($templateFileParameter);
|
|
|
|
//Définition du type de balisage
|
|
if (defined('MX_FLAGS_TYPE')) $this->SetMxFlagsType(MX_FLAGS_TYPE);
|
|
|
|
//Définition du type de balisage en sortie
|
|
if (defined('MX_OUTPUT_TYPE')) $this->SetMxOutputType(MX_OUTPUT_TYPE);
|
|
|
|
//Définition du répertoire de cache
|
|
if (defined('MX_CACHE_PATH')) $this->SetMxCachePath(MX_CACHE_PATH);
|
|
if (defined('MX_CACHE_DELAY')) $this->SetMxCacheDelay(MX_CACHE_DELAY);
|
|
if ($cacheDelay >= 0 && $cacheDelay != '') $this->SetMxCacheDelay($cacheDelay);
|
|
|
|
//Activation du traceur de performance
|
|
if (defined('MX_PERFORMANCE_TRACER') && MX_PERFORMANCE_TRACER == 'on') $this->performanceTracer = true;
|
|
|
|
//Gestion des paramètres de sessions
|
|
if ($sessionParameter) $this->sessionParameter = $sessionParameter;
|
|
|
|
//Instanciation de la ressource templates
|
|
if (@is_file($this->mXTemplatePath.$template)) $this->template = $template;
|
|
elseif (isset($template)) {
|
|
$this->template = $template;
|
|
$this->isTemplateFile = false;
|
|
}
|
|
else $this->ErrorTracker (5, 'No template file defined.', 'ModeliXe', __FILE__, __LINE__);
|
|
|
|
//Affectation du path d'origine
|
|
if ($this->ErrorChecker()) {
|
|
$this->absolutePath = substr(basename($this->template), 0, strpos(basename($this->template), '.'));
|
|
$this->relativePath = $this->absolutePath;
|
|
}
|
|
}
|
|
|
|
//Setting ModeliXe -------------------------------------------------------------------------------------------
|
|
|
|
//Méthode d'instanciation du template
|
|
function SetModelixe($out = ''){
|
|
if ($this->mXsetting) $this->ErrorTracker(4, 'You can\'t re-use this method after instanciate ModeliXe once time.', 'SetModelixe', __FILE__, __LINE__);
|
|
if ($out) $this->mXoutput = true;
|
|
|
|
//Test du cache et insertion éventuelle
|
|
if ($this->mXCacheDelay > 0){
|
|
$this->mXUrlKey = $this->GetMD5UrlKey();
|
|
|
|
if ($this->MxCheckCache())$this->MxGetCache();
|
|
}
|
|
|
|
//Initialisation de la classe
|
|
$this->GetMxFile();
|
|
if ($this->ErrorChecker()) $this->MxParsing($this->templateContent[$this->absolutePath]);
|
|
|
|
$this->mXsetting = true;
|
|
}
|
|
|
|
//Instanciation de la compression
|
|
function SetMxCompress($arg = ''){
|
|
if ($arg != 'on') $this->mXcompress = false;
|
|
else $this->mXcompress = true;
|
|
|
|
return $this->mXcompress;
|
|
}
|
|
|
|
//Instanciation du mode rewrite
|
|
function SetMxModRewrite($arg = ''){
|
|
if ($arg != 'on') $this->mXmodRewrite = false;
|
|
else $this->mXmodRewrite = true;
|
|
|
|
return $this->mXmodRewrite;
|
|
}
|
|
|
|
//Instanciation de la signature
|
|
function SetMxSignature($arg = ''){
|
|
if ($arg != 'on') $this->mXsignature = false;
|
|
else $this->mXsignature = true;
|
|
|
|
return $this->mXsignature;
|
|
}
|
|
|
|
//Instanciation du template path
|
|
function SetMxTemplatePath($arg = ''){
|
|
if ($this->mXsetting) $this->ErrorTracker(1, 'You can\'t use this method after instanciate ModeliXe with setModeliXe method, it will be without effects.', 'SetMxTemplatePath', __FILE__, __LINE__);
|
|
else {
|
|
if ($arg[strlen($arg) - 1] != '/' && $arg) $arg .= '/';
|
|
if (! is_dir($arg)) $this->ErrorTracker(5, 'The MX_TEMPLATE_PATH (<b>'.$arg.'</b>) is not a directory.', 'SetMxTemplatePath', __FILE__, __LINE__);
|
|
else $this->mXTemplatePath = $arg;
|
|
}
|
|
|
|
return $this->mXTemplatePath;
|
|
}
|
|
|
|
//Instanciation du fichier de paramètre
|
|
function SetMxFileParameter($arg = ''){
|
|
if ($arg != '' && ! is_file($arg)) $this->ErrorTracker(1, 'The parameter\'s file path (<b>'.$arg.'</b>) does not exist.', 'SetMxFileParameter', __FILE__, __LINE__);
|
|
else $this->mXParameterFile = $arg;
|
|
|
|
return $this->mXParameterFile;
|
|
}
|
|
|
|
//Instanciation du balisage du template
|
|
function SetMxFlagsType($arg){
|
|
if ($this->mXsetting) $this->ErrorTracker(1, 'You can\'t use this method after instanciate ModeliXe with setModeliXe method, it will be without effects.', 'SetMxFlagsType', __FILE__, __LINE__);
|
|
else {
|
|
switch (strtolower($arg)){
|
|
case 'classical':
|
|
$this->flagSystem = 'classical';
|
|
break;
|
|
case 'pear':
|
|
$this->flagSystem = 'classical';
|
|
break;
|
|
case 'xml':
|
|
$this->flagSystem = 'xml';
|
|
break;
|
|
default:
|
|
$this->ErrorTracker(2, 'This type of flag system ('.$arg.') is unrecognized.', 'SetMxFlagsType', __FILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
return $this->flagSystem;
|
|
}
|
|
|
|
//Instanciation du balisage de sortie
|
|
function SetMxOutputType($arg){
|
|
if ($this->mXsetting) $this->ErrorTracker(1, 'You can\'t use this method after instanciate ModeliXe with setModeliXe method, it will be without effects.', 'SetMxOutputType', __FILE__, __LINE__);
|
|
else {
|
|
switch (strtolower($arg)){
|
|
case 'xhtml':
|
|
$this->outputSystem = '/>';
|
|
break;
|
|
case 'html':
|
|
$this->outputSystem = '>';
|
|
break;
|
|
default:
|
|
$this->ErrorTracker(2, 'This type of output flag system ('.$arg.') is unrecognized.', 'SetMxOutputType', __FILE__, __LINE__);
|
|
}
|
|
}
|
|
return $arg;
|
|
}
|
|
|
|
//Instanciation du répertoire de cache
|
|
function SetMxCachePath($arg){
|
|
if ($this->mXsetting) $this->ErrorTracker(1, 'You can\'t use this method after instanciate ModeliXe with setModeliXe method, it will be without effects.', 'SetMxCachePath', __FILE__, __LINE__);
|
|
else {
|
|
if ($arg[strlen($arg) - 1] != '/') $arg .= '/';
|
|
if (! is_dir($arg) && $arg != '') $this->ErrorTracker(5, 'The MxCachePath (<b>'.$arg.'</b>) is not a directory.', 'SetMxCachePath', __FILE__, __LINE__);
|
|
elseif ($arg) $this->mXCachePath = $arg;
|
|
}
|
|
|
|
return $this->mXCachePath;
|
|
}
|
|
|
|
//Instanciation du délai de cache
|
|
function SetMxCacheDelay($arg){
|
|
if ($this->mXsetting) $this->ErrorTracker(1, 'You can\'t use this method after instanciate ModeliXe with setModeliXe method, it will be without effects.', 'SetMxCachePath', __FILE__, __LINE__);
|
|
elseif ($arg >= 0) $this->mXCacheDelay = (integer)$arg;
|
|
|
|
return $this->mXCacheDelay;
|
|
}
|
|
|
|
//Instanciation des paramètres de session
|
|
function SetMxSession($arg){
|
|
$this->sessionParameter = $arg;
|
|
}
|
|
|
|
//Setting tools -----------------------------------------------------------------------------------------------
|
|
|
|
//Recherche du fichier de template
|
|
function GetMxFile($source = ''){
|
|
|
|
if (! $source) $source = $this->mXTemplatePath.$this->template;
|
|
|
|
if (! $read = @fopen($source, 'rb')) $this->ErrorTracker (3, 'Can\'t open this template file (<b>'.$source.'</b>) in read, see for change the read modalities.', 'GetMxFile', __FILE__, __LINE__);
|
|
else {
|
|
|
|
if (! $result = @fread($read, filesize($source))) $this->ErrorTracker (3, 'Can\'t read the template file (<b>'.$source.'</b>), see for file format and integrity.', 'GetMxFile', __FILE__, __LINE__);
|
|
fclose($read);
|
|
}
|
|
|
|
/* Correction d'un bug : le bloc inclu était interprété comme un
|
|
commentaire HTML par certains navigateurs (testé avec Firefox 0.9) */
|
|
if (empty($result)) $result = '[no parsing, template file not found or invalid]';
|
|
if ($this->mXsignature && $source != $this->mXTemplatePath.$this->template) $result = "\n<!-- ModeliXe ".$this->mXVersion.' [StartOf'.$dyn.'Inclusion : '.$source."] -->\n\n".$result."\n\n<!-- ModeliXe ".$this->mXVersion.' [EndOf'.$dyn.'Inclusion : '.$source."] -->\n";
|
|
|
|
//Affectation du path d'origine, et du content du template
|
|
if ($source == $this->mXTemplatePath.$this->template) $this->templateContent[$this->absolutePath] = $result;
|
|
else return $result;
|
|
}
|
|
|
|
//Lecture du fichier de configuration et parsing
|
|
function GetParameterParsing ($template){
|
|
$ligne = '';
|
|
$signal = '';
|
|
|
|
if (! $read = @fopen($this->mXParameterFile, 'r')) $this->ErrorTracker(4, 'The mXParameterFile (<b>'.$this->mXParameterFile.'</b>) can\'t be open, the first parsing can\'t be do.', 'GetParameterParsing', __FILE__, __LINE__);
|
|
for ($multi = false; !feof($read) && $this->ErrorChecker(); $ligne = trim(@fgets($read, 1200))){
|
|
if (strlen($ligne)) {
|
|
if ($ligne[0] == '#' && $ligne[1] != '#'){
|
|
|
|
//Changement d'état pour les paramètres
|
|
switch(strtolower($ligne)){
|
|
case '#flag' :
|
|
$signal = 'flag';
|
|
break;
|
|
case '#attribut' :
|
|
$signal = 'attribut';
|
|
break;
|
|
default :
|
|
$this->ErrorTracker(3, '<b>'.$ligne.' </b> is not a valid section parameter type', 'GetParameterParsing', __FILE__, __LINE__);
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
if($ligne[0] == '#') $ligne = substr($ligne,1);
|
|
if (! $multi){
|
|
$keyC = chop(substr($ligne, 0, strpos($ligne, '=') - 1));
|
|
|
|
//Gestion du multiligne, début d'une valeur sur plusieurs lignes
|
|
if (($content = ltrim(substr($ligne, strpos($ligne, '=') + 1))) && substr($content, 0, 3) == '"""') {
|
|
$multi = true;
|
|
$content = substr($content, 3);
|
|
}
|
|
}
|
|
|
|
//Gestion du multiligne, fin d'une valeur sur plusieurs lignes
|
|
else {
|
|
if (substr($ligne, strlen($ligne) - 3) == '"""') {
|
|
$multi = false;
|
|
$content .= ' '.substr($ligne, 0, strpos($ligne, '"""'));
|
|
}
|
|
else $content .= ' '.$ligne;
|
|
}
|
|
|
|
//Si nous ne sommes pas dans une valeur sur plusieurs lignes (valeur compléte)
|
|
if (! $multi){
|
|
switch ($this->flagSystem){
|
|
case 'xml':
|
|
$flagRegexp = '<mx:preformating id="'.$keyC.'"/>';
|
|
$attRegexp = 'mXpreformating="'.$keyC.'"';
|
|
break;
|
|
case 'classical':
|
|
$flagRegexp = '{preformating id="'.$keyC.'"}';
|
|
$attRegexp = '{preformatingAtt id="'.$keyC.'"}';
|
|
break;
|
|
}
|
|
|
|
if ($signal == 'flag') $template = str_replace($flagRegexp, $content, $template);
|
|
if ($signal == 'attribut') $template = str_replace($attRegexp, $content, $template);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($read) @fclose($read);
|
|
|
|
return $template;
|
|
}
|
|
|
|
//MX Builder-----------------------------------------------------------------------------------------
|
|
function MxBloc($index, $mod, $value = ''){
|
|
$mod = substr(strtolower($mod), 0, 4);
|
|
|
|
if ($this->adressSystem == 'relative') {
|
|
if ($index) $index = $this->relativePath.'.'.$index;
|
|
else $index = $this->relativePath;
|
|
}
|
|
else $index = $this->absolutePath.'.'.$index;
|
|
|
|
$fat = $this->father[$index];
|
|
if (! $fat && $index != $this->absolutePath) $this->ErrorTracker(2, 'The current path (<b>'.$index.'</b>) does not exist, or was deleting, him or his father, before.', 'MxBloc', __FILE__, __LINE__);
|
|
|
|
switch ($mod){
|
|
//Looping
|
|
case 'loop':
|
|
$this->MxLoopBuilder($index);
|
|
break;
|
|
//Deleting
|
|
case 'dele':
|
|
$this->sheetBuilding[$index] = ' ';
|
|
$this->loop[$index] = '';
|
|
$this->deleted[$index] = true;
|
|
break;
|
|
//Concatenating
|
|
case 'appe':
|
|
if (@is_file($value)) $value = $this->GetMxFile($value);
|
|
$this->templateContent[$index] .= $value;
|
|
$this->MxParsing($value, $index, $this->father[$index]);
|
|
break;
|
|
//Replacing
|
|
case 'repl':
|
|
if (@is_file($value)) $value = $this->GetMxFile($value);
|
|
$this->sheetBuilding[$index] = $value;
|
|
$this->replacement[$index] = true;
|
|
break;
|
|
//Modify template references of this bloc
|
|
case 'modi':
|
|
$this->sheetBuilding[$index] = '';
|
|
$this->loop[$index] = '';
|
|
if (@is_file($value)) $value = $this->GetMxFile($value);
|
|
$this->templateContent[$index] = $value;
|
|
$this->MxParsing($value, $index, $this->father[$index]);
|
|
break;
|
|
//Reset, destroy all references
|
|
case 'rese':
|
|
$this->sheetBuilding[$index] = '';
|
|
$this->loop[$index] = '';
|
|
$this->templateContent[$index] = '';
|
|
$ind = substr($index, strrpos($index, '.') + 1);
|
|
$this->templateContent[$fat] = str_replace('<mx:inclusion id="'.$ind.'"/>', '', $this->templateContent[$fat]);
|
|
$this->deleted[$index] = true;
|
|
$this->xPattern['inclusion'][$index] = '';
|
|
break;
|
|
}
|
|
}
|
|
|
|
function MxFormField($index, $type, $name, $value, $attribut = '', $placeholder='', $special=''){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
$end = $this->outputSystem;
|
|
|
|
switch (strtolower($type)){
|
|
case 'text':
|
|
$replace = '<input type="text" name="'.$name.'" value="'.$value.'" placeholder="'.$placeholder.'" '.$attribut.' '.$this->htmlAtt[$index].$end;
|
|
break;
|
|
case 'email':
|
|
$replace = '<input type="email" name="'.$name.'" value="'.$value.'" placeholder="'.$placeholder.'" '.$attribut.' '.$this->htmlAtt[$index].$end;
|
|
break;
|
|
case 'password':
|
|
$replace = '<input type="password" name="'.$name.'" value="'.$value.'" placeholder="'.$placeholder.'" '.$attribut.' '.$this->htmlAtt[$index].$end.$special;
|
|
break;
|
|
case 'textarea':
|
|
$replace = '<textarea name="'.$name.'" placeholder="'.$placeholder.'" '.$attribut.' '.$this->htmlAtt[$index].' >'.$value.'</textarea>';
|
|
break;
|
|
case 'file':
|
|
$replace = '<input type="file" name="'.$name.'" value="'.$value.'" '.$attribut.' '.$this->htmlAtt[$index].$end;
|
|
break;
|
|
case 'submit':
|
|
$replace = '<input type="submit" name="'.$name.'" value="'.$value.'" '.$attribut.' '.$this->htmlAtt[$index].$end;
|
|
break;
|
|
case 'reset':
|
|
$replace = '<input type="reset" name="'.$name.'" value="'.$value.'" '.$attribut.' '.$this->htmlAtt[$index].$end;
|
|
break;
|
|
case 'button':
|
|
$replace = '<input type="button" name="'.$name.'" value="'.$value.'" '.$attribut.' '.$this->htmlAtt[$index].$end;
|
|
break;
|
|
case 'image':
|
|
$replace = '<input type="image" name="'.$name.'" '.$attribut.' '.$this->htmlAtt[$index].$end;
|
|
break;
|
|
case 'range':
|
|
// <input type="range" min="1" max="100" value="50" class="slider" id="myRange">
|
|
$replace = '<input type="range" name="'.$name.'" value="'.$value.'" '.$attribut.' '.$this->htmlAtt[$index].$end;
|
|
break;
|
|
default:
|
|
$this->ErrorTracker(3, 'This type (<b>'.$type.'</b>) is unknown for this formField manager.', 'MxFormField', __FILE__, __LINE__);
|
|
}
|
|
|
|
$this->formField[$index] = $replace;
|
|
}
|
|
|
|
function MxImage($index, $imag, $title = '', $attribut = '', $size = false){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
$end = $this->outputSystem;
|
|
|
|
// if (($ima = '<img src="'.$imag.'"') && ! $size) {
|
|
// $size = @getimagesize($imag);
|
|
// $ima .= ' '.$size[3].'px';
|
|
// }
|
|
|
|
if ($ima = '<img src="'.$imag.'"') {
|
|
// $size = @getimagesize($imag);
|
|
$ima .= ' ';
|
|
}
|
|
|
|
if ($title == 'no') $ima .= ' ';
|
|
elseif ($title) $ima .= ' alt="'.$title.'" title="'.$title.'" ';
|
|
else $ima .= ' alt="no title - source : '.basename($imag).'" ';
|
|
|
|
if ($attribut) $ima .= $attribut;
|
|
$ima .= ' '.$this->htmlAtt[$index].$end;
|
|
|
|
$this->image[$index] = $ima;
|
|
}
|
|
|
|
function MxText($index, $att){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
|
|
$this->text[$index] = $att;
|
|
}
|
|
|
|
function MxAttribut($index, $att){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
$marqueur = '';
|
|
|
|
//Gestion des mailto et des javascripts dans les href
|
|
if (strtolower($this->attributKey[$index]) == 'mailto' || strtolower($this->attributKey[$index]) == 'javascript') $marqueur = ' href="';
|
|
|
|
//Gestion multi-attributs
|
|
if (! ((isset($this->attribut[$index]))? chop($this->attribut[$index]): false) ) {
|
|
if ($marqueur) $this->attribut[$index] = $marqueur.$this->attributKey[$index].':'.$att.'"';
|
|
else $this->attribut[$index] = $this->attributKey[$index].'="'.$att.'"';
|
|
}
|
|
else {
|
|
if (empty($this->attribut[$this->attribut[$index]])) {
|
|
if ($marqueur) $this->attribut[$this->attribut[$index]] = ' '.$marqueur.$this->attributKey[$index].':'.$att.'"';
|
|
else $this->attribut[$this->attribut[$index]] = ' '.$this->attributKey[$index].'="'.$att.'"';
|
|
}
|
|
else {
|
|
if ($marqueur) $this->attribut[$this->attribut[$index]] .= $marqueur.$this->attributKey[$index].':'.$att.'"';
|
|
else $this->attribut[$this->attribut[$index]] .= ' '.$this->attributKey[$index].'="'.$att.'"';
|
|
}
|
|
}
|
|
}
|
|
|
|
function MxSelect($index, $name, $value, $arrayArg, $defaut = '', $multiple = '', $javascript = '', $attributes = '') {
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
$sel = '';
|
|
|
|
if ($multiple && $multiple > 0) {
|
|
$attribut = 'size="'.$multiple.'" multiple="multiple" ';
|
|
$post = '[]';
|
|
}
|
|
else {
|
|
$attribut = '';
|
|
$post = '';
|
|
}
|
|
|
|
//Build of a select tag from an array
|
|
if (is_array($arrayArg)){
|
|
$sel = "\n".'<select name="'.$name.$post.'" '.$attributes.' ';
|
|
if ($attribut) $sel .= $attribut.' ';
|
|
if ($javascript) $sel .= $javascript;
|
|
$sel .= ' '.$this->htmlAtt[$index].' '.">\n";
|
|
|
|
if (isset($defaut) && $defaut) $sel .= "\t".'<option value="#" selected="selected">'.$defaut.'</option>'."\n";
|
|
|
|
$debut = 0;
|
|
$fin = count($arrayArg);
|
|
|
|
reset($arrayArg);
|
|
while (list($cle, $Avalue) = each($arrayArg)){
|
|
$test = 0;
|
|
|
|
//Build of multiple choice select from a value array
|
|
if (is_array($value) && $multiple > 0){
|
|
reset($value);
|
|
while (list($Vcle, $Vvalue) = each($value)){
|
|
|
|
/* correction d'un bug
|
|
les variables devaient être comparées en tant que string */
|
|
if ((string)$cle === (string)$Vvalue && $Vvalue != '') {
|
|
$sel .= "\t".'<option value="'.$cle.'" selected="selected">'.$Avalue.'</option>'."\n";
|
|
$test = 1;
|
|
break;
|
|
}
|
|
}
|
|
if ($test == 0) $sel .= "\t".'<option value="'.$cle.'">'.$Avalue.'</option>'."\n";
|
|
}
|
|
|
|
//Simple select
|
|
else {
|
|
/* correction d'un bug
|
|
les variables devaient être comparées en tant que string */
|
|
if ($value != '' && (string)$cle === (string)$value) $sel .= "\t".'<option value="'.$cle.'" selected="selected">'.$Avalue.'</option>'."\n";
|
|
else $sel .= "\t".'<option value="'.$cle.'">'.$Avalue.'</option>'."\n";
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$this->ErrorTracker(2, 'This function need an Array in fourth argument to build the select <b>'.$index.'</b>.', 'MxSelect', __FILE__, __LINE__);
|
|
$sel = '<select name="'.$name.'">'."\n\t".'<option value="null">No record found</option>'."\n";
|
|
}
|
|
|
|
$sel .= '</select>';
|
|
|
|
$this->select[$index] = $sel;
|
|
}
|
|
|
|
function MxUrl($index, $urlArg, $param = '', $noSid = false, $attribut = '') {
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
|
|
$ok = false;
|
|
|
|
//Ajout des paramètres de sessions en cas de cache ou non
|
|
if ($this->sessionParameter && ! $noSid) {
|
|
if ($this->mXCacheDelay > 0) $urlArg .= '?<mx:session />';
|
|
else $urlArg .= '?'.$this->sessionParameter;
|
|
|
|
$ok = true;
|
|
}
|
|
|
|
//Construction du lien
|
|
if (is_string($param) && $param) {
|
|
$param = explode('&',$param);
|
|
for($i = 0; $i < count($param) && $param[$i]; $i++){
|
|
$cle = explode('=', $param[$i]);
|
|
if (! $this->mXmodRewrite) $urlArg .= ($i == 0 && !$ok) ? '?'.urlencode($cle[0]).'='.urlencode($cle[1]) : '&'.urlencode($cle[0]).'='.urlencode($cle[1]);
|
|
else $urlArg .= '/'.urlencode($cle[0]).'/'.urlencode($cle[1]);
|
|
}
|
|
}
|
|
elseif (is_array($param)){
|
|
reset($param);
|
|
if ($this->mXmodRewrite) {
|
|
while (list($cle, $valeur) = each($param)) {
|
|
$urlArg .= '/'.urlencode($cle).'/'.urlencode($valeur);
|
|
}
|
|
}
|
|
else {
|
|
while (list($cle, $valeur) = each($param)) {
|
|
if (!$ok) {
|
|
$urlArg .= '?'.urlencode($cle).'='.urlencode($valeur);
|
|
$ok = true;
|
|
}
|
|
else $urlArg .= '&'.urlencode($cle).'='.urlencode($valeur);
|
|
}
|
|
}
|
|
}
|
|
elseif ($param) $this->ErrorTracker(3, 'The third argument must be a queryString or an array.', 'MxUrl', __FILE__, __LINE__);
|
|
|
|
/* correction d'un bug mineur de rendu : espace placé avant l'attribut href
|
|
concerne les 2 blocs ci-dessous */
|
|
//Ajout d'éventuels attributs supplémentaires en dynamique
|
|
$lien = ($attribut)? 'href="'.$urlArg.'" '.$attribut : 'href="'.$urlArg.'"';
|
|
|
|
//Gestion multi-attributs
|
|
if (! ((isset($this->attribut[$index]))? chop($this->attribut[$index]): false)) $this->attribut[$index] = 'href="'.$urlArg.'"';
|
|
else {
|
|
if (empty($this->attribut[$this->attribut[$index]])) $this->attribut[$this->attribut[$index]] = 'href="'.$urlArg.'"';
|
|
else $this->attribut[$this->attribut[$index]] .= 'href="'.$urlArg.'"';
|
|
}
|
|
}
|
|
|
|
function MxHidden ($index, $param){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
$end = $this->outputSystem;
|
|
|
|
$hidden = '';
|
|
|
|
if ($this->mXCacheDelay == 0 && $this->sessionParameter) $param .= '&'.$this->sessionParameter;
|
|
|
|
if (is_string($param)) $param = explode('&',$param);
|
|
else $this->ErrorTracker(3,'The second argument must be a queryString.', 'MxHidden', __FILE__, __LINE__);
|
|
|
|
if (! empty($param)){
|
|
for($i = 0; $i < count($param); $i++){
|
|
if ($param[$i]) {
|
|
$cle = explode('=', $param[$i]);
|
|
/* correction de 2 bugs dans la balise hidden */
|
|
/*$hidden .= '<input type="hidden" name="'.$cle[0].'" value="'.$cle[1].'" '.$end."\n";*/
|
|
$hidden .= '<input type="hidden" name="'.htmlspecialchars(urldecode($cle[0])).'" value="'.htmlspecialchars(urldecode($cle[1])).'" '.$this->htmlAtt[$index].$end."\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($this->mXCacheDelay > 0) $hidden .= '<mx:hiddenSession />';
|
|
|
|
$this->hidden[$index] = $hidden;
|
|
}
|
|
|
|
function MxCheckerField($index, $type, $name, $value, $checked = false, $attribut = ''){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
$end = $this->outputSystem;
|
|
|
|
$type = strtolower($type);
|
|
if ($type != "checkbox" && $type != "radio") $this->ErrorTracker(2, 'This type (<b>'.$type.'</b>) is unknown for this CheckerField manager.', 'MxCheckerField', __FILE__, __LINE__);
|
|
|
|
$replace = '<input type="'.$type.'" name="'.$name.'" value="'.$value.'"';
|
|
if ( $checked ) $replace .= ' checked="checked"';
|
|
if ($attribut) $replace .= ' '.$attribut;
|
|
$replace .= ' '.$this->htmlAtt[$index].$end;
|
|
|
|
$this->checker[$index] = $replace;
|
|
}
|
|
|
|
//MX Extender----------------------------------------------------------------------------------------
|
|
function AddMxPlugIn($name, $type, $fonction){
|
|
|
|
if (! $name) $this->ErrorTracker(2, 'You must give a name to identify the plug-in.', 'AddMxPlugIn',__FILE__, __LINE__);
|
|
if (! $type) $this->ErrorTracker(2, 'The type of the plug-in is necessary to instanciate it.', 'AddMxPlugIn', __FILE__, __LINE__);
|
|
if (! $fonction || ! function_exists($fonction)) $this->ErrorManager(3, 'The method addMxPlugin need the name of a function in third argument.', 'AddMxPlugIn',__FILE__, __LINE__);
|
|
|
|
if ($this->ErrorChecker()){
|
|
switch ($type){
|
|
case 'flag':
|
|
for ($i = 0; $i < count($this->flagArray); $i++){
|
|
if ($name == $this->flagArray[$i]) $this->ErrorTracker(2, 'This plug-in (<b>'.$name.'</b>) has got the same pattern as the native pattern of a ModeliXe flag.', 'AddMxPlugIn', __FILE__, __LINE__);
|
|
}
|
|
$this->flagArray[count($this->flagArray)] = $name;
|
|
break;
|
|
case 'attribut':
|
|
for ($i = 0; $i < count($this->attributArray); $i++){
|
|
if ($name == $this->attributArray[$i]) $this->ErrorTracker(2, 'This plug-in (<b>'.$name.'</b>) has got the same pattern as the native pattern of a ModeliXe attribut.', 'AddMxPlugIn', __FILE__, __LINE__);
|
|
}
|
|
$this->attributArray[count($this->attributArray)] = $name;
|
|
break;
|
|
default :
|
|
$this->ErrorTracker(2, 'This type of plug-in (<b>'.$type.'</b>) is unrecognized.', 'AddMxPlugIn', __FILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
$this->$name = array();
|
|
$this->plugInMethods[$name] = $fonction;
|
|
}
|
|
|
|
function SetMxPlugIn($name, $index, $arguments){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
|
|
if (isset($arguments) && ! is_array($arguments)) $this->ErrorTracker(2, 'You must give an array of arguments for the plug-in function.', 'SetMxPlugIn', __FILE__, __LINE__);
|
|
else {
|
|
$tab = &$this->$name;
|
|
$tab[$index] = call_user_func($this->plugInMethods[$name], $arguments);
|
|
}
|
|
}
|
|
|
|
//MX tools -------------------------------------------------------------------------------------------------------------------
|
|
|
|
//Vérifie l'existence d'un bloc
|
|
function IsMxBloc($index){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
|
|
$fat = $this->father[$index];
|
|
if (! $fat && $index != $this->absolutePath) return false;
|
|
else return true;
|
|
}
|
|
|
|
//Vérifie l'existence d'une balise
|
|
function IsMxFlag($index, $type){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
|
|
$tab = $this->$type;
|
|
if (! isset($tab[$index])) return false;
|
|
else return $tab[$index];
|
|
}
|
|
|
|
//Vérifie l'existence d'un attribut
|
|
function IsMxAttribut($index){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
|
|
if (! isset($this->attributKey[$index])) return false;
|
|
else {
|
|
if (preg_match('/;/', $this->attribut[$index])) return $this->attribut[$this->attribut[$index]];
|
|
else return $this->attribut[$index];
|
|
}
|
|
}
|
|
|
|
//Retourne tout le contenu d'un bloc
|
|
function GetMxBloc($index){
|
|
if ($this->adressSystem == 'relative') $index = $this->relativePath.'.'.$index;
|
|
|
|
if ($this->sheetBuilding[$index]) return $this->sheetBuilding[$index];
|
|
else return $this->templateContent[$index];
|
|
}
|
|
|
|
//Construction d'une queryString
|
|
function GetQueryString($keyString, $null = 1){
|
|
$queryString = array();
|
|
|
|
if (is_array($keyString)){
|
|
reset($keyString);
|
|
|
|
while (list($Akey, $value) = each($keyString)){
|
|
if (is_array($value)) {
|
|
while (list($k, $v) = each($value)) {
|
|
array_push($queryString, urlencode($Akey.'['.$k.']').'='.urlencode($v));
|
|
}
|
|
}
|
|
elseif ($null || strlen($value)) array_push($queryString, urlencode($Akey).'='.urlencode($value));
|
|
}
|
|
return implode('&',$queryString);
|
|
}
|
|
else $this->ErrorTracker(3, 'The argument for this function must be an associative array.', 'GetQueryString', __FILE__, __LINE__);
|
|
}
|
|
|
|
//Adressage simplifié
|
|
function WithMxPath($path = '', $origine = ''){
|
|
|
|
if (! $origine) $origine = $this->adressSystem;
|
|
else {
|
|
switch($origine){
|
|
case 'relative':
|
|
break;
|
|
case 'absolute':
|
|
break;
|
|
default:
|
|
$origine = 'relative';
|
|
break;
|
|
}
|
|
}
|
|
|
|
//Si on ne précise pas de path on retourne au path origine
|
|
if (empty($path)){
|
|
$this->relativePath = $this->absolutePath;
|
|
|
|
if ($origine == 'absolute') $this->adressSystem = 'absolute';
|
|
elseif ($origine == 'relative') $this->adressSystem = 'relative';
|
|
}
|
|
|
|
//Sinon, en absolu on se situe dans ce path, en relatif on se situe par rapport au path relatif
|
|
if ($path) {
|
|
if ($origine == 'relative') {
|
|
|
|
//On redescend dans la hiérarchie jusqu'au path mentionné
|
|
if (($test = explode('../', $path)) && count($test) > 1) {
|
|
$path = substr($path, strrpos($path, '/') + 1);
|
|
$this->relativePath = substr($this->relativePath, 0, strlen($this->relativePath) - strlen(strstr($this->relativePath, $path)) - 1);
|
|
if (! $this->relativePath) $this->ErrorTracker(3, 'This path (<b>'.$path.'</b>) does not exist, ModeliXe can\'t build relativePath.', 'WithMxPath', __FILE__, __LINE__);
|
|
}
|
|
|
|
$this->relativePath .= '.'.$path;
|
|
|
|
$this->adressSystem = 'relative';
|
|
}
|
|
elseif ($origine == 'absolute') {
|
|
$this->relativePath = $path;
|
|
$this->adressSystem = 'absolute';
|
|
}
|
|
}
|
|
}
|
|
|
|
//Informations de licence
|
|
function AboutModeliXe($out = ''){
|
|
$texte = "\nLicence et conditions d'utilisations :\n";
|
|
$texte .= 'ModeliXe '.$this->mXVersion."\nModeliXe est distribué sous licence LGPL, merci de laisser cet en-tête, gage et garantie de cette licence.\n";
|
|
$texte .= "ModeliXe est un moteur de template destiné à être utilisé par des applications écrites en PHP.\n";
|
|
$texte .= " \n";
|
|
$texte .= "Copyright(c) 2001-2004 - ANDRE Thierry (aka Théo)\n";
|
|
$texte .= " \n";
|
|
$texte .= "Mainteneur actuel : TRICHARD Rémy (alias Tungsten)\n";
|
|
$texte .= "Pour tout renseignements mailez à modelixe@free.fr ou tungsten180@hotmail.com\n";
|
|
|
|
if ($out) return $texte;
|
|
else print('<pre>'.$texte.'</pre>');
|
|
}
|
|
|
|
//Numéro de version
|
|
function GetMxVersion(){
|
|
return $this->mXVersion;
|
|
}
|
|
|
|
//Rafraichissement
|
|
function MxRefresh($query = ''){
|
|
$this->MxClearCache('this', $query);
|
|
}
|
|
|
|
function MxRefreshAll() {
|
|
$this->MxClearCache();
|
|
}
|
|
|
|
//Mesure de performances
|
|
function GetExecutionTime(){
|
|
$time = explode(' ',microtime());
|
|
$fin = $time[1] + $time[0];
|
|
$this->ExecutionTime = intval(10000 * ((double)$fin - (double)$this->debut)) / 10000;
|
|
|
|
return($this->ExecutionTime);
|
|
}
|
|
|
|
//MX Parsing Engine------------------------------------------------------------------------------------------------------------
|
|
|
|
function MxParsing($doc = '', $path = '', $father = ''){
|
|
$countPath = Array();
|
|
|
|
//Initialisation
|
|
if (! $path) {
|
|
$original = true;
|
|
$path = $this->absolutePath;
|
|
}
|
|
else $original = false;
|
|
|
|
$this->father[$path] = $father;
|
|
$this->IsALoop[$path] = false;
|
|
|
|
//Parsing des balises de bloc, extraction des sous blocs
|
|
$ok = true;
|
|
|
|
switch ($this->flagSystem){
|
|
case 'xml':
|
|
$blocRegexp = '/<mx:bloc(?:[ ]+ref="([^"]+)")?[ ]+id="([^"]+)"[ ]*>/S';
|
|
break;
|
|
case 'classical':
|
|
$blocRegexp = '/{start(?:[ ]+ref="([^"]+)")?[ ]+id="([^"]+)"[ ]*}/S';
|
|
break;
|
|
}
|
|
|
|
if (preg_match_all($blocRegexp, $doc, $inclusion)){
|
|
|
|
for($i = 0; $ok; $i++){
|
|
|
|
//Extraction des différentes informations extraites par la regex
|
|
$id = $inclusion[2][0];
|
|
$ref = $inclusion[1][0];
|
|
$pattern = $inclusion[0][0];
|
|
|
|
//Calcul des limites du bloc traité
|
|
switch ($this->flagSystem){
|
|
case 'xml':
|
|
$regexp = '</mx:bloc id="'.$id.'">';
|
|
break;
|
|
case 'classical':
|
|
$regexp = '{end id="'.$id.'"}';
|
|
break;
|
|
}
|
|
|
|
$startOfIntrons = strpos($doc, $pattern) + strlen($pattern);
|
|
$endOfIntrons = strpos($doc, $regexp);
|
|
$length = $endOfIntrons - $startOfIntrons;
|
|
|
|
if (! $endOfIntrons) $this->ErrorTracker(4, 'The end of the "<b>'.$id.'</b>" bloc is not found, this bloc can\'t be generate. Verify that the end of bloc\'s flag exists and has a good form, like this pattern <b>'.htmlentitiesconv($regexp).'</b>.', 'MxParsing', __FILE__, __LINE__);
|
|
|
|
//On teste si le bloc en cours posséde une référence vers un autre template
|
|
if (! $ref) $this->templateContent[$path.'.'.$id] = substr($doc, $startOfIntrons, $length);
|
|
else {
|
|
if ($this->mXTemplatePath) $ref = $this->mXTemplatePath.$ref;
|
|
$this->templateContent[$path.'.'.$id] = $this->GetMxFile($ref);
|
|
}
|
|
|
|
//Création du pattern du bloc traité
|
|
$this->xPattern['inclusion'][$path.'.'.$id] = '<mx:inclusion id="'.$id.'"/>';
|
|
$this->deleted[$path.'.'.$id] = false;
|
|
$this->replacement[$path.'.'.$id] = false;
|
|
|
|
//Extraction du contenu du bloc pour reconstruire le bloc en cours
|
|
$doc = substr($doc, 0, $startOfIntrons - strlen($pattern)).'<mx:inclusion id="'.$id.'"/>'.substr($doc, $endOfIntrons + strlen($regexp));
|
|
$this->templateContent[$path] = $doc;
|
|
|
|
//Construction de la référence à ce bloc pour la récursivité
|
|
$countPath[$i] = $path.'.'.$id;
|
|
|
|
//Incrémentation du nbre de fils pour le bloc en cours
|
|
if (! empty($this->son[$path][0])) $compt = $this->son[$path][0];
|
|
else {
|
|
$compt = 0;
|
|
$this->son[$path][0] = 0;
|
|
}
|
|
|
|
//Construction de la référence au fils du bloc parsé pour le bloc en cours
|
|
$this->son[$path][++ $compt] = $path.'.'.$id;
|
|
$this->son[$path][0] ++;
|
|
|
|
//Test de fin de boucle
|
|
$ok = preg_match_all($blocRegexp, $doc, $inclusion);
|
|
}
|
|
}
|
|
|
|
//Parsing des balises ModeliXe
|
|
reset($this->flagArray);
|
|
while (list($Akey, $value) = each($this->flagArray)){
|
|
|
|
switch ($this->flagSystem){
|
|
case 'xml':
|
|
$regexp = '/<mx:'.$value.'(?:[ ]+(?:ref|info)="(?:[^"]+)")?[ ]+id="([^"]+)"(([^>])*(?=\/>))\/>/S';
|
|
break;
|
|
case 'classical':
|
|
$regexp = '/{'.$value.'(?:[ ]+(?:ref|info)="(?:[^"]+)")?[ ]+id="([^"]+)"[ ]*(?i:htmlAtt\[([^\]]*)\])?}/S';
|
|
break;
|
|
}
|
|
|
|
if (preg_match_all($regexp, $doc, $flag)){
|
|
for ($i = 0; ; $i++){
|
|
if (empty ($flag[0][$i])) break;
|
|
|
|
//Construction du pattern et des valeurs par défaut de ces balises
|
|
$this->xPattern[$value][$path.'.'.$flag[1][$i]] = $flag[0][$i];
|
|
|
|
//Modification Guillaume Lelarge compatibilité PHP3
|
|
/*<PHP3>
|
|
$ref = $this->$value;
|
|
$ref[$path.'.'.$flag[1][$i]] = ' ';
|
|
$this->$value = $ref;
|
|
$this->htmlAtt[$path.'.'.$flag[1][$i]] = $flag[2][$i];
|
|
</PHP3>*/
|
|
|
|
$ref = &$this->$value;
|
|
$ref[$path.'.'.$flag[1][$i]] = ' ';
|
|
$this->htmlAtt[$path.'.'.$flag[1][$i]] = $flag[2][$i];
|
|
}
|
|
}
|
|
}
|
|
|
|
//Parsing des attributs de ModeliXe
|
|
switch ($this->flagSystem){
|
|
case 'xml':
|
|
$regexp = '/mXattribut="([^"]{3,})"/Si';
|
|
$separateur = ':';
|
|
break;
|
|
case 'classical':
|
|
$regexp = '/{attribut ([^\}]+)}/Si';
|
|
$separateur = '=';
|
|
break;
|
|
}
|
|
|
|
if (preg_match_all($regexp, $doc, $flag)){
|
|
for ($i = 0, $k = 0; ; $i++){
|
|
|
|
if (empty($flag[0][$i])) break;
|
|
|
|
$pattern = $flag[0][$i];
|
|
$motif = $flag[1][$i];
|
|
$k = 0;
|
|
|
|
//Gestion de plusieurs couples de clé-valeurs dans les attributs
|
|
$tabVal = explode(';', $motif);
|
|
for ($j = 0; $j < count($tabVal); $j++) {
|
|
|
|
$tabCle = explode($separateur, trim($tabVal[$j]));
|
|
$patternKey[++ $k] = trim($tabCle[0]);
|
|
$indexValue[$k] = trim($tabCle[1]);
|
|
|
|
//Gestion multi-attributs
|
|
if (count($tabVal) > 1) {
|
|
$this->attribut[$path.'.'.$indexValue[$k]] = $path.'.'.$indexValue[1].';';
|
|
if ($k == 1) $this->xPattern['attribut'][$path.'.'.$indexValue[1].';'] = $pattern;
|
|
}
|
|
else {
|
|
$this->attribut[$path.'.'.$indexValue[$k]] = ' ';
|
|
$this->xPattern['attribut'][$path.'.'.$indexValue[$k]] = $pattern;
|
|
}
|
|
|
|
if ($patternKey[$k] != 'url') $this->attributKey[$path.'.'.$indexValue[$k]] = $patternKey[$k];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
for ($i = 0; $i < count($countPath); $i++) $this->MxParsing($this->templateContent[$countPath[$i]], $countPath[$i], $path);
|
|
}
|
|
|
|
//MX Compression System ------------------------------------------------------------------------------------------------------------------
|
|
|
|
//Vérifie si la compression est possible et son type
|
|
function MxCheckCompress($file){
|
|
if((! $this->mXcompress) || (! extension_loaded("zlib")) || (headers_sent()) || (strlen($file) / 1000 < 8)) return false;
|
|
global $_SERVER;
|
|
|
|
if (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip')) return "x-gzip";
|
|
if (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) return "gzip";
|
|
|
|
return false;
|
|
}
|
|
|
|
//Compression des donnees destinées au navigateur
|
|
function MxSetCompress($filecontent){
|
|
if ($encoding = $this->MxCheckCompress($filecontent)){
|
|
|
|
header('Content-Encoding: '.$encoding);
|
|
$gzfilecontent = "\x1f\x8b\x08\x00\x00\x00\x00\x00";
|
|
$size = strlen($filecontent);
|
|
$crc32 = crc32($filecontent);
|
|
$gzfilecontent .= gzcompress($filecontent, 9);
|
|
$gzfilecontent = substr($gzfilecontent, 0, strlen($gzfilecontent) - 4);
|
|
$gzfilecontent .= pack('V',$crc32);
|
|
$gzfilecontent .= pack('V',$size);
|
|
|
|
return $gzfilecontent;
|
|
}
|
|
else return $filecontent;
|
|
}
|
|
|
|
|
|
//MX Cache system ------------------------------------------------------------------------------------------------------------------
|
|
|
|
//Retourne une clé unique pour les arguments en POST et GET différents des paramètres de session
|
|
function GetMD5UrlKey($query = ''){
|
|
global $_POST, $_GET;
|
|
|
|
if (! $query) $get = $_GET;
|
|
else $get = $query;
|
|
if (! $query) $post = $_POST;
|
|
else $post = $query;
|
|
|
|
//Intégration du nom du fichier php appelant
|
|
$uri = getenv('REQUEST_URI');
|
|
$uri = substr($uri, 0, strpos($uri, '?'));
|
|
|
|
//Suppression des paramètres de session en GET
|
|
$chaine = '';
|
|
$this->DeleteSessionKey($chaine, $get);
|
|
|
|
//Suppression des paramètres de session en POST
|
|
$this->DeleteSessionKey($chaine, $post);
|
|
|
|
return (md5($chaine.$uri));
|
|
}
|
|
|
|
function DeleteSessionKey(&$chaine, $httpvar){
|
|
$param = explode('&', $this->sessionParameter);
|
|
|
|
//Tri des tableaux pour les avoir dans le même ordre
|
|
asort($httpvar);
|
|
asort($param);
|
|
|
|
//pr est un marqueur pour éviter de parcourir toutes les valeurs des param de session si ceux-ci ont déja été tous supprimés
|
|
$pr = 0;
|
|
|
|
//suppression des paramètres de session(get ou post)
|
|
for (reset($httpvar); $cle = key($httpvar); next($httpvar)){
|
|
$ok = false;
|
|
$compt = count($param);
|
|
for ($i = 0; $i < $compt && ($pr != $compt); $i++){
|
|
if (($cleU = explode('=', $param[$i])) && $cleU[0] == $cle) {
|
|
$ok = true;
|
|
$pr ++;
|
|
break;
|
|
}
|
|
}
|
|
if (! $ok) $chaine .= $cle.'='.$httpvar[$cle];
|
|
}
|
|
}
|
|
|
|
//Vidage du cache
|
|
function MxClearCache($fich = '', $query = ''){
|
|
|
|
if (! $open = @opendir($this->mXCachePath)) $this->ErrorTracker(3, 'Can\'t open cache directory (<b>'.$this->mXCachePath.'</b>) to clear old files.', 'MxClearCache', __FILE__, __LINE__);
|
|
else {
|
|
while ($fichier = @readdir($open)){
|
|
|
|
if ($fichier != '.' && $fichier != '..'){
|
|
if (! $fich){
|
|
if (($currentTime = filemtime($this->mXCachePath.$fichier)) && time() - $currentTime > $this->mXCacheDelay) {
|
|
if (! @unlink($this->mXCachePath.$fichier)) $this->ErrorTracker(3, 'Can\'t unlink this file "<b>'.$fichier.'</b>" in cache directory.', 'MxClearCache', __FILE__, __LINE__);
|
|
}
|
|
}
|
|
else {
|
|
//Supprime spécifiquement le fichier du template en cours
|
|
$ana = explode('~', $fichier);
|
|
if ($ana[1] == $this->template) {
|
|
|
|
//Gestion des suppressions spécifiques à une queryString
|
|
if ($query && $this->GetMD5UrlKey($query) == $ana[0]){
|
|
if (! @unlink($this->mXCachePath.$fichier)) $this->ErrorTracker(3, 'Can\'t unlink this file "<b>'.$fichier.'</b>" in cache directory.', 'MxClearCache', __FILE__, __LINE__);
|
|
}
|
|
elseif (! @unlink($this->mXCachePath.$fichier)) $this->ErrorTracker(3, 'Can\'t unlink this file "<b>'.$fichier.'</b>" in cache directory.', 'MxClearCache', __FILE__, __LINE__);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@closedir($open);
|
|
}
|
|
}
|
|
|
|
//Initialisation du cache
|
|
function MxSetCache($filecontent) {
|
|
|
|
$this->MxClearCache('this');
|
|
/* ajout du support des sous-répertoires */
|
|
$this->template = str_replace("/","%2F", $this->template);
|
|
/* correction d'un bug dans la construction du chemin du fichier cache */
|
|
if (! $cache = fopen($this->mXCachePath.$this->mXUrlKey.'~'.$this->template, 'w')) $this->ErrorTracker(4, 'Can\'t open in writing the cache file on "<b>'.$this->mXCachePath.$this->template.'</b>" path.', 'MxSetCache', __FILE__, __LINE__);
|
|
|
|
//Sauvegarde du contenu
|
|
if ($this->ErrorChecker()) {
|
|
if (! $write = fputs($cache, $filecontent)) $this->ErrorTracker(5, 'Can\'t wite the cache file on "<b>'.$this->mXCachePath.$this->mXUrlKey.'~'.$this->template.'</b>" path.', 'MxSetCache', __FILE__, __LINE__);
|
|
@fclose($cache);
|
|
}
|
|
}
|
|
|
|
//Retourne le fichier de cache
|
|
function MxGetCache() {
|
|
/* ajout du support des sous-répertoires */
|
|
$this->template = str_replace("/","%2F", $this->template);
|
|
$cache_file = $this->mXCachePath.$this->mXUrlKey.'~'.$this->template;
|
|
|
|
if (! $open = @fopen($cache_file, 'rb')) $this->ErrorTracker(5, 'Can\'t open the cache file on "<b>'.$cache_file.'</b>" path.', 'MxGetCache');
|
|
if (! $read = @fread($open, filesize($cache_file))) $this->ErrorTracker(5, 'Can\'t read the cache file on "<b>'.$cache_file.'</b>" path.', 'MxGetCache', __FILE__, __LINE__);
|
|
|
|
@fclose($open);
|
|
|
|
//Parsing des paramètres de sessions
|
|
$read = $this->MxSessionParameterParsing($read);
|
|
|
|
//Si on cherche à mesurer les performances de ModeliXe
|
|
if ($this->performanceTracer) {
|
|
$read = str_replace('<mx:performanceTracer />', $this->GetExecutionTime().' [cache]', $read);
|
|
}
|
|
|
|
//Si il y a une gestion de la compression, envoie des en-têtes correspondantes
|
|
$this->ErrorChecker();
|
|
if ($this->mXoutput) return $read;
|
|
else print($this->MxSetCompress($read));
|
|
|
|
die();
|
|
}
|
|
|
|
//Teste si le fichier de cache existe et son échéance
|
|
function MxCheckCache() {
|
|
/* ajout du support des sous-répertoires */
|
|
$this->template = str_replace("/","%2F", $this->template);
|
|
$cache_file = $this->mXCachePath.$this->mXUrlKey.'~'.$this->template;
|
|
|
|
if (@is_file($cache_file)){
|
|
if (($currentTime = filemtime($cache_file)) && (((time() - $currentTime) < $this->mXCacheDelay && filemtime($this->mXTemplatePath.$this->template) < $currentTime))) return true;
|
|
}
|
|
else return false;
|
|
}
|
|
|
|
//MX Template Fusion Engine --------------------------------------------------------------------------------------------------
|
|
function MxSessionParameterParsing($content) {
|
|
$hidden = '';
|
|
|
|
$param = $this->sessionParameter;
|
|
|
|
if ($param){
|
|
$content = str_replace('<mx:session />', $param, $content);
|
|
|
|
$param = explode('&', $this->sessionParameter);
|
|
for($i = 0; $i < count($param); $i++){
|
|
if ($param[$i]) {
|
|
$cle = explode('=', $param[$i]);
|
|
$hidden .= '<input type="hidden" name="'.$cle[0].'" value="'.$cle[1].'" />'."\n";
|
|
}
|
|
}
|
|
|
|
$content = str_replace('<mx:hiddenSession />', $hidden, $content);
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
//Remplace le contenu des templates passés en arguments
|
|
function MxReplace($path){
|
|
|
|
if (! empty($this->sheetBuilding[$path])) $cible = $this->sheetBuilding[$path];
|
|
else $cible = $this->templateContent[$path];
|
|
|
|
//Remplacement de l'ensemble des attributs ModeliXe par les valeurs qui ont été instanciées ou leurs valeurs par défaut
|
|
reset($this->attributArray);
|
|
while (list($cle, $Fkey) = each($this->attributArray)){
|
|
$Farray = &$this->$Fkey;
|
|
|
|
if (is_array($Farray)){
|
|
reset($Farray);
|
|
|
|
while (list($Pkey, $value) = each($Farray)){
|
|
|
|
if ($path == substr($Pkey, 0, strrpos($Pkey, '.'))) {
|
|
if (isset($this->xPattern[$Fkey][$Pkey])){
|
|
$pattern = $this->xPattern[$Fkey][$Pkey];
|
|
$cible = str_replace($pattern, $value, $cible);
|
|
unset($Farray[$Pkey]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Remplacement de l'ensemble des balises ModeliXe par les valeurs qui ont été instanciées ou leurs valeurs par défaut
|
|
reset($this->flagArray);
|
|
while (list($cle, $Fkey) = each($this->flagArray)){
|
|
$Farray = &$this->$Fkey;
|
|
|
|
if (is_array($Farray)){
|
|
reset($Farray);
|
|
|
|
while (list($Pkey, $value) = each($Farray)){
|
|
if ($path == substr($Pkey, 0, strrpos($Pkey, '.'))) {
|
|
if (isset($this->xPattern[$Fkey][$Pkey])){
|
|
$pattern = $this->xPattern[$Fkey][$Pkey];
|
|
$cible = str_replace($pattern, $value, $cible);
|
|
unset($Farray[$Pkey]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $cible;
|
|
}
|
|
|
|
//Construit les blocs et associe les blocs fils aux blocs parents
|
|
function MxBlocBuilder($path = ''){
|
|
$ordre = array();
|
|
$hierarchie = 1;
|
|
|
|
if (! $path) $path = $this->absolutePath;
|
|
$chemin = $path;
|
|
|
|
//Classement de tout les fils de path du plus proche au plus lointain
|
|
$base = count(explode('.', $path));
|
|
$k = 1;
|
|
$l = 1;
|
|
$j = 1;
|
|
|
|
for (; ;){
|
|
|
|
//Si il existe un fils on le prend
|
|
if (! empty($this->son[$chemin][$j])) $fils = $this->son[$chemin][$j];
|
|
else $fils = '';
|
|
|
|
//Si il existe on considère le dernier enregistrement trouvé précédant celui-ci
|
|
if (! empty($ordre[$hierarchie])) $ancien = $ordre[$hierarchie][count($ordre[$hierarchie])];
|
|
else $ancien = false;
|
|
|
|
if ($fils == $ancien) break;
|
|
|
|
//Si il n'y a plus de fils, on passe au noeud suivant
|
|
if (empty($fils)) {
|
|
$j = 1;
|
|
|
|
if (! empty($ordre[$k][$l])) {
|
|
$chemin = $ordre[$k][$l];
|
|
$l ++;
|
|
}
|
|
else {
|
|
$l = 1;
|
|
$k ++;
|
|
|
|
if (! empty($ordre[$k][$l])) $chemin = $ordre[$k][$l ++];
|
|
else break;
|
|
}
|
|
}
|
|
else {
|
|
$j ++;
|
|
|
|
//Si le fils n'a pas été détruit on le considére
|
|
if ($this->templateContent[$fils]) {
|
|
|
|
//hiérarchie compte le nombre de blocs à partir du bloc de base
|
|
$hierarchie = count(explode('.', $fils)) - $base;
|
|
|
|
if (empty($ordre[$hierarchie])) $ordre[$hierarchie] = array();
|
|
$ordre[$hierarchie][count($ordre[$hierarchie]) + 1] = $fils;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Insertion des fils les plus lointains dans les fils les plus proches jusqu'au path
|
|
for ($i = count($ordre); $i > 0; $i --){
|
|
|
|
for ($j = 1; $j <= count($ordre[$i]); $j++){
|
|
|
|
$fils = $ordre[$i][$j];
|
|
$pattern = $this->xPattern['inclusion'][$fils];
|
|
$pere = $this->father[$ordre[$i][$j]];
|
|
|
|
//Insertion du bloc fils dans le père
|
|
if ($pere == $path && $this->IsALoop[$path]) {
|
|
|
|
if ($this->IsALoop[$fils]) {
|
|
|
|
if ($this->deleted[$fils]) {
|
|
$rem = '';
|
|
$this->deleted[$fils] = false;
|
|
}
|
|
else $rem = $this->loop[$fils];
|
|
|
|
$this->loop[$pere] = str_replace($pattern, $rem, $this->loop[$pere]);
|
|
$this->loop[$fils] = '';
|
|
}
|
|
else {
|
|
|
|
if ($this->deleted[$fils]) {
|
|
$rem = '';
|
|
$this->deleted[$fils] = false;
|
|
}
|
|
else $rem = $this->MxReplace($fils);
|
|
|
|
$this->loop[$pere] = str_replace($pattern, $rem, $this->loop[$pere]);
|
|
$this->sheetBuilding[$fils] = '';
|
|
}
|
|
}
|
|
else {
|
|
|
|
if (! empty($this->sheetBuilding[$pere])) $source = $this->sheetBuilding[$pere];
|
|
else $source = $this->templateContent[$pere];
|
|
|
|
if ($this->IsALoop[$fils]) {
|
|
|
|
if ($this->deleted[$fils]) {
|
|
$rem = '';
|
|
$this->deleted[$fils] = false;
|
|
}
|
|
else $rem = $this->loop[$fils];
|
|
|
|
$this->sheetBuilding[$pere] = str_replace($pattern, $rem, $source);
|
|
$this->loop[$fils] = '';
|
|
}
|
|
else {
|
|
|
|
if ($this->deleted[$fils]) {
|
|
$rem = '';
|
|
$this->deleted[$fils] = false;
|
|
}
|
|
else $rem = $this->MxReplace($fils);
|
|
|
|
$this->sheetBuilding[$pere] = str_replace($pattern, $rem, $source);
|
|
$this->sheetBuilding[$fils] = '';
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//Associe les boucles
|
|
function MxLoopBuilder($path = ''){
|
|
if (! $path) $path = $this->absolutePath;
|
|
|
|
$father = $this->father[$path];
|
|
$pattern = $this->xPattern['inclusion'][$path];
|
|
|
|
//On saute les blocs détruits
|
|
if ($pattern){
|
|
$this->IsALoop[$path] = true;
|
|
if (empty($this->loop[$path])) $this->loop[$path] = '';
|
|
|
|
//Gestion des blocs remplacés temporairement
|
|
if ($this->replacement[$path]) {
|
|
$this->loop[$path] .= $this->MxReplace($path);
|
|
$this->replacement[$path] = false;
|
|
$this->sheetBuilding[$path] = '';
|
|
}
|
|
|
|
//Gestion des boucles classiques
|
|
else {
|
|
$this->sheetBuilding[$path] = '';
|
|
if (empty($this->loop[$path])) $this->loop[$path] = '';
|
|
$this->loop[$path] .= $this->MxReplace($path);
|
|
}
|
|
}
|
|
|
|
//Insertion des fils de $path dans $path
|
|
$this->MxBlocBuilder($path);
|
|
}
|
|
|
|
//Mx Output -------------------------------------------------------------------------------------------------------------------
|
|
|
|
//Sortie du fichier HTML généré
|
|
function MxWrite ($out = ''){
|
|
/* correction pour activer $retour = $page->MxWrite('out'); */
|
|
if ($out) $this->mXoutput = true;
|
|
|
|
if (! $this->mXsetting) $this->ErrorTracker(5, 'You d\'ont intialize ModeliXe with setModeliXe method, there is no data to write.', 'MxWrite', __FILE__, __LINE__);
|
|
|
|
//Assemblage de l'ensemble des blocs fils
|
|
$this->MxBlocBuilder();
|
|
|
|
if ($this->mXsignature) $entete = '<!--[ModeliXe '.$this->mXVersion.'] -- '.(($this->isTemplateFile)? '[TemplateFile : '.$this->mXTemplatePath.$this->template.']' : '[Template : '.$this->template.']').' -- [date '.date('j/m/Y H:i:s')."]-->\n";
|
|
else $entete = '';
|
|
|
|
if ($this->ErrorChecker()) {
|
|
$filecontent = (($entete)? str_replace('<head>', '<head>'."\n".$entete,$filecontent = $this->MxReplace($this->absolutePath)) : $filecontent = $this->MxReplace($this->absolutePath));
|
|
|
|
//Remplacement des balises de paramètres
|
|
if ($this->mXParameterFile) $filecontent = $this->GetParameterParsing($filecontent);
|
|
|
|
//Mise en cache de la page générée sans les paramètres de sessions
|
|
if ($this->mXCacheDelay > 0) {
|
|
$this->MxSetCache($filecontent);
|
|
|
|
//Parsing des paramètres de sessions
|
|
$filecontent = $this->MxSessionParameterParsing($filecontent);
|
|
}
|
|
|
|
//Si on cherche à mesurer les performances de ModeliXe
|
|
if ($this->performanceTracer) {
|
|
$filecontent = str_replace('<mx:performanceTracer />', $this->GetExecutionTime(), $filecontent);
|
|
}
|
|
|
|
// rajout personnel : version de ModeliXe
|
|
$filecontent = str_replace('<mx:version />', $this->mXVersion, $filecontent);
|
|
|
|
if ($this->mXoutput) return $filecontent;
|
|
else print($this->MxSetCompress($filecontent));
|
|
}
|
|
}
|
|
}
|
|
?>
|