<?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)); } } } ?>