New file |
0,0 → 1,575 |
<?php |
// Encodage : UTF-8 |
// +-------------------------------------------------------------------------------------------------------------------+ |
/** |
* ScriptCommande |
* |
* Description : classe abstraite des scripts |
* Fichier d'origine jelix-scripts par Jouanneau Laurent |
* copyright 2005-2007 Jouanneau laurent |
* link http://www.jelix.org |
* |
//Auteur original : |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Tela-Botanica 1999-2008 |
* @licence GPL v3 & CeCILL v2 |
* @version $Id: ScriptCommande.class.php 1948 2009-09-03 14:12:02Z Jean-Pascal MILCENT $ |
*/ |
// +-------------------------------------------------------------------------------------------------------------------+ |
// TODO : supprimer les classe getStaticIni(), getStaticParam() et getStaticNom(). Utiliser une seule méthode qui gère les deux méthodes d'appel. |
/** |
* classe representant une commande |
*/ |
abstract class ScriptCommande { |
|
public $nom; |
public $parametres; |
|
|
/** |
* Paramêtres disponible pour la ligne de commande |
* le tableau se construit de la forme suivnate : |
* - clé = nom du paramêtre '-foo' |
* - value = contient un nouveau tableau composé de cette façaon : |
* - booléen: true si le paramêtre est obligatoire |
* - booléen ou var : true si le paramêtre nécessite un valeur à sa suite ou la valeur par défaut |
* - string: description du contenu du paramêtre |
* Les paramêtres optionels devraient être déclaré à la fin du tableau. |
* Le dernier parametre du tableau peut avoir la valeur '...', |
* il contiendra alors l'ensemble des paramêtres suivant trouvés sur la ligne de commande. |
* @var array |
*/ |
private $_parametres_autorises = array( '-p' => array(true, true, 'Projet, le nom utiliser pour le fichier ini'), |
'-a' => array(true, true, 'Action à réaliser'), |
'-v' => array(false, '1', 'Mode verbeux : 1 ou 2'), |
'-t' => array(false, '', 'Test sur un nombre de ligne...')); |
/** |
* Contient les valeurs des paramêtres récupérés de la ligne de commande : |
* le tableau se construit de la forme suivnate : |
* - clé = nom du paramêtre '-foo' |
* - valeur = la valeur récupérée sur la ligne de commande |
* @var array |
*/ |
private $_parametres; |
|
private static $_static_nom; |
private static $_static_parametres; |
private static $_static_ini; |
private static $log = ''; |
private static $log_fichier; |
private static $log_resource; |
private static $log_fichier_ecraser = false; |
|
public $syntaxhelp = ''; |
public $help = 'Aucune aide pour cette commande'; |
|
function __construct($commande_nom) { |
$this->setNom($commande_nom); |
} |
|
public function __destruct() { |
if (isset(self::$log_resource)) { |
if (fclose(self::$log_resource)) { |
self::$log_resource = null; |
} |
} |
} |
|
public function getNom() { |
return $this->nom; |
} |
|
public static function getStaticNom() { |
return self::$_static_nom; |
} |
|
private function setNom($script_nom) { |
$this->nom = $script_nom; |
self::$_static_nom = $script_nom; |
} |
|
public static function getLog() { |
return self::$log; |
} |
|
public static function setLog($l) { |
self::$log .= $l; |
} |
|
public function initialiser($plc) { |
// Récupération des paramêtres autorisés par le script |
$this->setParamAutorises($this->parametres); |
|
// Vérification et récupération des paramêtres de la ligne de commande |
if ($parametres = $this->verifierParametres($plc, $this->getParamAutorises())) { |
$this->setParam($parametres); |
} |
|
// Tableaux des emplacements des fichiers ini à rechercher et à charger dans l'ordre du tableau |
$projet_prefixe = ''; |
if (preg_match('/^([^_]+)/', $this->getParam('p'), $match)) { |
$projet_prefixe = $match[1]; |
} |
$tab_fichiers_ini = array( ES_CHEMIN_CONFIG.'bdd.ini', // Paramêtres de la base de données |
ES_CHEMIN_CONFIG.'commun.ini', // Paramêtres communs aux différents projets |
ES_CHEMIN_CONFIG.$this->getParam('p').'.ini',// Ancien emplacement du fichier ini du projet, dans le dossier configuration global |
$this->getModuleChemin().$this->getParam('p').'.ini', |
$this->getModuleChemin().DS.'configurations'.DS.$this->getParam('p').'.ini'); |
|
// Chargement des fichiers ini généraux |
for ($i = 0; $i < 2 ; $i++) { |
if (!$this->parserFichierIni($tab_fichiers_ini[$i])) { |
$e = "Le fichier $tab_fichiers_ini[$i] est introuvable\n"; |
trigger_error($e, E_USER_WARNING); |
} |
} |
// Chargement du fichier ini du projet |
$erreur_ini_projet = true; |
for ($i = 2; $i < 7 ; $i++) { |
if ($this->parserFichierIni($tab_fichiers_ini[$i])) { |
$erreur_ini_projet = false; |
} |
} |
if ($erreur_ini_projet) { |
$e = "Le fichier .ini du projet est introuvable : \n".$tab_fichiers_ini[2]."\n".$tab_fichiers_ini[3]."\n"; |
trigger_error($e, E_USER_WARNING); |
} |
} |
|
abstract public function executer(); |
|
protected function getModuleChemin($shouldexist = true) { |
$chemin = ES_CHEMIN_MODULE.$this->getNom().DS; |
if (!file_exists($chemin) && $shouldexist) { |
trigger_error("Erreur: le module '".$this->getNom()."' n'existe pas ($chemin)\n", E_USER_ERROR); |
} |
return $chemin; |
} |
|
private function verifierParametres($p_ligne, $p_autorise) { |
|
//print_r($p_ligne); |
// Récupération des paramêtres |
foreach ($p_autorise as $p_nom => $p_val) { |
if (count($p_ligne) == 0) { |
if ($p_val[0]) { |
trigger_error("Erreur: paramêtre manquant '".$p_nom."' \n", E_USER_WARNING); |
} |
} |
if ($p_nom == '...') { |
$parametres['...'] = array(); |
foreach($p_ligne as $arg) { |
$parametres['...'][] = $arg; |
} |
$p_ligne = array(); |
break; |
} else { |
if (isset($p_ligne[$p_nom])) { |
// Attribution de la valeur issue de la ligne de commande |
$parametres[ltrim($p_nom, '-')] = $p_ligne[$p_nom]; |
unset($p_ligne[$p_nom]); |
} else { |
// Attribution de la valeur par défaut |
if ($p_val[1] !== true) { |
$parametres[ltrim($p_nom, '-')] = $p_val[1]; |
} |
} |
} |
} |
|
// Gestion de l'excédant de paramêtres |
if (count($p_ligne)) { |
trigger_error("Erreur: trop de paramêtres\n", E_USER_ERROR); |
} |
|
return $parametres; |
} |
|
protected function setParamAutorises($param) { |
if (!is_null($param)) { |
foreach ($param as $c => $v) { |
if (isset($this->_parametres_autorises[$c])) { |
trigger_error("Erreur: le module '".$this->getNom()."' ne peut définir le paramêtre '$c' car il existe déjà\n", E_USER_ERROR); |
} else { |
$this->_parametres_autorises[$c] = $v; |
} |
} |
} |
} |
|
protected function getParamAutorises($param = null) { |
|
if (!is_null($param)) { |
if (isset($this->_parametres_autorises['-'.$param])) { |
return $this->_parametres_autorises['-'.$param]; |
} else if (isset($this->_parametres_autorises[$param])) { |
return $this->_parametres_autorises[$param]; |
} else { |
trigger_error("Erreur: le module '".$this->getNom()."' n'a pas défini le paramêtre '$param'\n", E_USER_WARNING); |
return false; |
} |
} else { |
return $this->_parametres_autorises; |
} |
} |
|
protected function setParam($params = array(), $val = null) { |
|
if (is_array($params)) { |
$this->_parametres = $params; |
self::$_static_parametres = $params; |
} else if (!is_array($params) && !is_null($val)) { |
$this->_parametres[$params] = $val; |
self::$_static_parametres[$params] = $val; |
} else { |
return false; |
} |
} |
|
protected function getParam($param = null) { |
|
if (!is_null($param)) { |
if (isset($this->_parametres['-'.$param])) { |
return $this->_parametres['-'.$param]; |
} else if (isset($this->_parametres[$param])) { |
return $this->_parametres[$param]; |
} else { |
trigger_error("Erreur: la ligne de commande ne contenait pas le paramêtre '$param'\n", E_USER_WARNING); |
return false; |
} |
} else { |
return $this->_parametres; |
} |
} |
|
protected static function getStaticParam($param = null) { |
|
if (!is_null($param)) { |
if (isset(self::$_static_parametres['-'.$param])) { |
return self::$_static_parametres['-'.$param]; |
} else if (isset(self::$_static_parametres[$param])) { |
return self::$_static_parametres[$param]; |
} else { |
trigger_error("Erreur: la ligne de commande ne contenait pas le paramêtre '$param'\n", E_USER_WARNING); |
return false; |
} |
} else { |
return self::$_static_parametres; |
} |
} |
|
protected function getIni($nom) { |
if (isset($this->_ini[$nom])) { |
return $this->_ini[$nom]; |
} else { |
return false; |
} |
} |
|
protected static function getStaticIni($nom) { |
if (isset(self::$_static_ini[$nom])) { |
return self::$_static_ini[$nom]; |
} else { |
return false; |
} |
} |
|
protected function parserFichierIni($fichier_ini) { |
if (file_exists($fichier_ini)) { |
$aso_ini = parse_ini_file($fichier_ini); |
foreach ($aso_ini as $cle => $val) { |
if (preg_match('/^php:(.+)$/', $val, $correspondances)) { |
eval('$this->$cle = '.$correspondances[1].';'); |
eval('$this->_ini[$cle] = '.$correspondances[1].';'); |
} else if (preg_match('/^php-static:(.+)$/', $val, $correspondances)) { |
eval('self::$'.$cle.' = '.$correspondances[1].';'); |
eval('$this->_ini[$cle] = '.$correspondances[1].';'); |
} else { |
// Ancienne forme : compatibilité avec les anciens scripts... |
$this->$cle = $val; |
// Nouvelle forme : utilisation de la méthode getInit(). |
$this->_ini[$cle] = $val; |
} |
} |
self::$_static_ini = $this->_ini; |
return true; |
} else { |
return false; |
} |
} |
|
// Log Resource |
/** |
* Lit la valeur de l'attribut Log Resource. |
* Utilise le motif de conception (= design pattern) Singleton. |
* |
* @access public |
* @param string le préfixe du nom de fichier à créer. |
* @return string retourne le Log Resource. |
*/ |
public static function getLogResource() { |
if (!isset(self::$log_resource)) { |
if (file_exists(self::getLogFichier()) && !self::$log_fichier_ecraser) { |
// Ouvre en écriture seule ; place le pointeur de fichier à la fin du fichier. Si le fichier |
// n'existe pas, on tente de le créer. |
self::$log_resource = fopen(self::getLogFichier(), 'a'); |
} else { |
//Ouvre en écriture seule ; place le pointeur de fichier au début du fichier et réduit la taille |
// du fichier à 0. Si le fichier n'existe pas, on tente de le créer. |
self::$log_resource = fopen(self::getLogFichier(), 'w'); |
$entete_utf8 = "\xEF\xBB\xBF"; |
if (!fwrite(self::$log_resource, $entete_utf8)) { |
echo "Erreur écriture dans le fichier de log lors de l'ajout de l'entête UTF8.\n"; |
} |
} |
} |
return self::$log_resource; |
} |
|
// Log Fichier |
/** |
* Lit la valeur de l'attribut Log Fichier. |
* Utilise le motif de conception (= design pattern) Singleton. |
* |
* @access public |
* @return string retourne le nom du fichier de log. |
*/ |
public static function getLogFichier() { |
if (!isset(self::$log_fichier)) { |
if (self::getStaticIni('projet_nom') && self::getStaticIni('version') && self::getStaticIni('sous_version')) { |
$fichier = self::getStaticIni('projet_nom').'_'. |
self::getStaticNom().'_'. |
self::getStaticParam('a').'_'. |
'v'.self::getStaticIni('version').'_'.self::getStaticIni('sous_version'); |
} else { |
$fichier = self::getStaticNom().'_'.self::getStaticParam('a'); |
} |
|
if (!self::$log_fichier_ecraser) { |
$fichier .= '_'.date('Y-m-j_H:i:s', time()); |
} |
$fichier .= '.log'; |
// Ajout du chemin vers le fichier de log et stockage dans variable static |
self::$log_fichier = self::getStaticIni('log_chemin').$fichier; |
} |
return self::$log_fichier; |
} |
|
/** |
* Retourne un message d'avertissement formaté. |
* |
* @param string le message d'erreur avec des %s. |
* @param array le tableau des paramêtres à insérer dans le message d'erreur. |
* @param int le niveau de verbosité à dépasser pour afficher les messages. |
* @return string le message d'erreur formaté. |
*/ |
private function traiterMessage($message, $tab_arguments = array(), $niveau = 0) { |
// Nous ajoutons dans le texte les infos provenant de la BDD (déjà encodées en UTF-8). |
$texte = vsprintf($message, $tab_arguments); |
if ($this->getParam('v') >= $niveau) { |
$prefixe = ''; |
if ($this->getIni('projet_nom') && $this->getIni('version') && $this->getIni('sous_version')) { |
$prefixe = $this->getIni('projet_nom').'v'.$this->getIni('version').'.'.$this->getIni('sous_version').'. '; |
} else { |
$prefixe = date('Y-m-j_H:i:s', time()).' - '.Script::getCode($niveau).' : '; |
} |
$log = $prefixe.$texte."\n"; |
echo $log; |
self::setLog($log); |
|
if (!fwrite($this->getLogResource(), $log)) { |
trigger_error('Erreur écriture dans le fichier de log.'."\n", E_USER_WARNING); |
} |
} |
return "\t".$texte."\n"; |
} |
|
/** |
* Retourne un message d'erreur après avoir écrit le message danns le fichier de log. |
* Si le mode verbeux est inactivé, écrit le message dans le fichier de log. |
* Si le mode verbeux de niveau 1 ou plus est activé, écrit le message dans le fichier de log et dans la console. |
* |
* @param string le message d'erreur avec des %s. |
* @param array le tableau des paramêtres à insérer dans le message d'erreur. |
* @return string le message d'erreur formaté. |
*/ |
protected function traiterErreur($message, $tab_arguments = array()) { |
$niveau = Script::ERREUR; |
return $this->traiterMessage($message, $tab_arguments, $niveau); |
} |
|
/** |
* Retourne un message d'avertissement formaté. |
* Si le mode verbeux de niveau 1 est activé, écrit le message dans le fichier de log. |
* Si le mode verbeux de niveau 2 est activé, écrit le message dans le fichier de log et dans la console. |
* |
* @param string le message d'erreur avec des %s. |
* @param array le tableau des paramêtres à insérer dans le message d'erreur. |
* @return string le message d'erreur formaté. |
*/ |
protected function traiterAttention($message, $tab_arguments = array()) { |
$niveau = Script::AVERTISSEMENT; |
return $this->traiterMessage($message, $tab_arguments, $niveau); |
} |
|
/** |
* Retourne un message d'information formaté. |
* Si le mode verbeux de niveau 2 est activé, écrit le message dans le fichier de log. |
* Si le mode verbeux de niveau 3 est activé, écrit le message dans le fichier de log et dans la console. |
* |
* @param string le message d'information avec des %s. |
* @param array le tableau des paramêtres à insérer dans le message d'erreur. |
* @param int le niveau de verbosité à dépasser pour afficher les messages. |
* @return string le message d'erreur formaté. |
*/ |
protected function afficher($message, $tab_arguments = array(), $niveau = null) { |
if (is_null($niveau)) { |
$niveau = Script::INFO; |
} |
$msg = $this->traiterMessage($message, $tab_arguments, $niveau); |
return $msg ; |
} |
|
/** |
* Méthode prenant en paramètre un chemin de fichier squelette et un tableau associatif de données, |
* en extrait les variables, charge le squelette et retourne le résultat des deux combinés. |
* |
* @param String $fichier le chemin du fichier du squelette |
* @param Array $donnees un tableau associatif contenant les variables a injecter dans le squelette. |
* |
* @return boolean false si le squelette n'existe pas, sinon la chaine résultat. |
*/ |
public static function traiterSquelettePhp($fichier, Array $donnees = array()) { |
$sortie = false; |
if (file_exists($fichier)) { |
// Extraction des variables du tableau de données |
extract($donnees); |
// Démarage de la bufferisation de sortie |
ob_start(); |
// Si les tags courts sont activés |
if ((bool) @ini_get('short_open_tag') === true) { |
// Simple inclusion du squelette |
include $fichier; |
} else { |
// Sinon, remplacement des tags courts par la syntaxe classique avec echo |
$html_et_code_php = self::traiterTagsCourts($fichier); |
// Pour évaluer du php mélangé dans du html il est nécessaire de fermer la balise php ouverte par eval |
$html_et_code_php = '?>'.$html_et_code_php; |
// Interprétation du html et du php dans le buffer |
echo eval($html_et_code_php); |
} |
// Récupèration du contenu du buffer |
$sortie = ob_get_contents(); |
// Suppression du buffer |
@ob_end_clean(); |
} else { |
$msg = "Le fichier du squelette '$fichier' n'existe pas."; |
trigger_error($msg, E_USER_WARNING); |
} |
// Retourne le contenu |
return $sortie; |
} |
|
/** |
* Fonction chargeant le contenu du squelette et remplaçant les tags court php (<?= ...) par un tag long avec echo. |
* |
* @param String $chemin_squelette le chemin du fichier du squelette |
* |
* @return string le contenu du fichier du squelette php avec les tags courts remplacés. |
*/ |
private static function traiterTagsCourts($chemin_squelette) { |
$contenu = file_get_contents($chemin_squelette); |
// Remplacement de tags courts par un tag long avec echo |
$contenu = str_replace('<?=', '<?php echo ', $contenu); |
// Ajout systématique d'un point virgule avant la fermeture php |
$contenu = preg_replace("/;*\s*\?>/", "; ?>", $contenu); |
return $contenu; |
} |
|
/** |
* Créer et stocke du contenu dans un fichier. |
* |
* @param string le chemin et le nom du fichier. |
* @param string le contenu à stocker dans le fichier. |
* @return string le message d'erreur formaté. |
*/ |
protected function creerFichier($fichier, $contenu, $compression = false) { |
$e = null; |
if ($compression) { |
// Ajout de l'extension gz |
if (substr($fichier, -3) != '.gz') { |
$fichier = $fichier.'.gz'; |
} |
// Début de l'écriture du fichier compressé |
if ($resource = gzopen($fichier, 'w9')) { |
if (!gzwrite($resource, $contenu)) { |
$e = "Le contenu texte n'a pas pu être écrit dans le fichier compressé '$fichier'."; |
} |
if (!gzclose($resource)) { |
$e = "Le fichier compressé '$fichier' n'a pas pu être fermé."; |
} |
} else { |
$e = "Le fichier compressé '$fichier' n'a pas pu être ouvert."; |
} |
} else { |
if ($resource = fopen($fichier, 'w')) { |
if (!fwrite($resource, $contenu)) { |
$e = "Le contenu texte n'a pas pu être écrit dans le fichier '$fichier'."; |
} |
if (!fclose($resource)) { |
$e = "Le fichier '$fichier' n'a pas pu être fermé."; |
} |
} else { |
$e = "Le fichier '$fichier' n'a pas pu être ouvert."; |
} |
} |
if (is_null($e)) { |
return true; |
} else { |
trigger_error($e, E_USER_WARNING); |
return false; |
} |
} |
|
/** |
* Méthode permettant d'encoder de l'iso-8859-15 vers utf-8 un tableau de variables. |
* |
* @param mixed la chaine ou le tableau à encoder en utf-8 depuis l'iso-8859-15. |
* @param string l'encodage d'origine si ce n'est pas ISO-8859-15. |
* @return mixed la chaine ou le tableau encodé en utf-8. |
* @access protected |
*/ |
protected function encoderUtf8( &$val, $encodage = 'ISO-8859-15') { |
//echo print_r($val, true)."\n"; |
if (is_array($val)) { |
foreach ($val as $c => $v) { |
$val[$c] = $this->encoderUtf8($v); |
} |
} else { |
// Nous vérifions si nous avons un bon encodage UTF-8 |
if (!is_numeric($val) && !empty($val) && !$this->detecterUtf8($val)) { |
// Les nombres, les valeurs vides et ce qui est déjà en UTF-8 ne sont pas encodés. |
$val = mb_convert_encoding($val, 'UTF-8', $encodage); |
} |
} |
return $val; |
} |
|
/** |
* Méthode permettant de détecter réellement l'encodage utf8. |
* mb_detect_encoding plante si la chaine de caractère se termine par un caractère accentué. |
* Provient de PHPDIG. |
* |
* @param string la chaine à vérifier. |
* @return bool true si c'est de l'utf8, sinon false. |
* @access private |
*/ |
private function detecterUtf8($str) { |
if ($str === mb_convert_encoding(mb_convert_encoding($str, 'UTF-32', 'UTF-8'), 'UTF-8', 'UTF-32')) { |
return true; |
} else { |
return false; |
} |
} |
} |
?> |