1: <?php
2: // declare(encoding='UTF-8');
3: /**
4: * Script est une classe abstraite qui doit être implémenté par les classes éxecutant des scripts en ligne de commande.
5: *
6: * @category PHP 5.2
7: * @package Framework
8: * @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
9: * @author Delphine CAUQUIL <delphine@tela-botanica.org>
10: * @copyright Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
11: * @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL-v3
12: * @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL-v2
13: * @since 0.3
14: * @version $Id: Script.php 299 2011-01-18 14:03:46Z jpm $
15: * @link /doc/framework/
16: */
17:
18: abstract class Script {
19: /** Niveau de message de type LOG */
20: const MSG_LOG = 0;
21: /** Niveau de message de type ERREUR */
22: const MSG_ERREUR = 1;
23: /** Niveau de message de type AVERTISSEMENT */
24: const MSG_AVERTISSEMENT = 2;
25: /** Niveau de message de type INFORMATION */
26: const MSG_INFO = 3;
27:
28: /** Inititulé des différents types de message. */
29: private static $msg_niveaux_txt = array('LOG', 'ERREUR','AVERTISSEMENT', 'INFO');
30:
31: /**
32: * Le nom du script tel que passé dans la ligne de commande.
33: * @var string
34: */
35: private $script_nom = null;
36:
37: /**
38: * Paramêtres par défaut disponibles pour la ligne de commande
39: * le tableau se construit de la forme suivante :
40: * - clé = nom du paramêtre '-foo'
41: * - value = contient un nouveau tableau composé de cette façon :
42: * - booléen: true si le paramêtre est obligatoire
43: * - booléen ou var : true si le paramêtre nécessite un valeur à sa suite ou la valeur par défaut
44: * - string: description du contenu du paramêtre
45: * Les paramêtres optionels devraient être déclaré à la fin du tableau.
46: * Le dernier parametre du tableau peut avoir la valeur '...',
47: * il contiendra alors l'ensemble des paramêtres suivant trouvés sur la ligne de commande.
48: * @var array
49: */
50: private $parametres_autorises_defaut = array(
51: '-a' => array(true, true, 'Action à réaliser'),
52: '-v' => array(false, '1', 'Mode verbeux : 1 ou 2'));
53:
54: /**
55: * Paramêtres autorisés par le script.
56: * le tableau est de la forme suivante :
57: * - clé = nom du paramêtre '-foo'
58: * - value = contient un nouveau tableau composé de cette façon :
59: * - booléen: true si le paramêtre est obligatoire
60: * - booléen ou var : true si le paramêtre nécessite un valeur à sa suite ou la valeur par défaut
61: * - string: description du contenu du paramêtre
62: * Les paramêtres optionels devraient être déclaré à la fin du tableau.
63: * Le dernier parametre du tableau peut avoir la valeur '...',
64: * il contiendra alors l'ensemble des paramêtres suivant trouvés sur la ligne de commande.
65: * @var array
66: */
67: protected $parametres_autorises = null;
68:
69: /**
70: * Contient les valeurs des paramêtres récupérés de la ligne de commande :
71: * le tableau se construit de la forme suivnate :
72: * - clé = nom du paramêtre '-foo'
73: * - valeur = la valeur récupérée sur la ligne de commande
74: * @var array
75: */
76: private $parametres_cli = null;
77:
78: /**
79: * Contient le tableau des paramètres disponible après vérification :
80: * le tableau est de la forme suivante :
81: * - clé = nom du paramêtre '-foo'
82: * - valeur = la valeur récupérée sur la ligne de commande
83: * @var array
84: */
85: protected $parametres = null;
86:
87: /** Tableau associatif permettant de stocker l'avancement dans une boucle.
88: * La clé est un md5 du message à afficher au démarrage de la boucle.
89: * @var array
90: */
91: private static $avancement = array();
92:
93: /** Tableau des noms des paramètres à définir dans le fichier de config car obligatoirement nécessaire à cette classe.*/
94: private static $parametres_obligatoires = array('chemin_modules', 'log_script');
95:
96: public function __construct($script_nom, $parametres_cli) {
97: $this->script_nom = $script_nom;
98: $this->parametres_cli = $parametres_cli;
99:
100: Config::verifierPresenceParametres(self::$parametres_obligatoires);
101:
102: $fichier_ini_script = $this->getScriptChemin().'config.ini';
103: Config::charger($fichier_ini_script);
104:
105: $this->chargerParametresAutorises();
106: $this->chargerParametres();
107: }
108:
109: private static function getMsgNiveauTxt($niveau) {
110: return self::$msg_niveaux_txt[$niveau];
111: }
112:
113: protected function getScriptNom() {
114: return $this->script_nom;
115: }
116:
117: protected function getScriptChemin($doit_exister = true) {
118: $chemin = Config::get('chemin_modules').$this->getScriptNom().DS;
119: if (!file_exists($chemin) && $doit_exister) {
120: trigger_error("Erreur: le module '".$this->getScriptNom()."' n'existe pas ($chemin)\n", E_USER_ERROR);
121: }
122: return $chemin;
123: }
124:
125: protected function getParametre($parametre) {
126: $retour = false;
127: if (!is_null($parametre)) {
128: $parametre = ltrim($parametre, '-');
129:
130: if (isset($this->parametres[$parametre])) {
131: $retour = $this->parametres[$parametre];
132: } else {
133: trigger_error("Erreur: la ligne de commande ne contenait pas le paramêtre '$parametre'\n", E_USER_WARNING);
134: }
135: }
136: return $retour;
137: }
138:
139: abstract public function executer();
140:
141: private function chargerParametresAutorises() {
142: foreach ($this->parametres_autorises_defaut as $c => $v) {
143: if (isset($this->parametres_autorises[$c])) {
144: trigger_error("Erreur: le script '".$this->getScriptNom()."' ne peut définir le paramêtre '$c' car il existe déjà\n", E_USER_ERROR);
145: } else {
146: $this->parametres_autorises[$c] = $v;
147: }
148: }
149: }
150:
151: private function chargerParametres() {
152: $parametres_cli = $this->parametres_cli;
153:
154: // Récupération des paramêtresgetMsgNiveauTxt
155: foreach ($this->parametres_autorises as $p_nom => $p_val) {
156: if (count($parametres_cli) == 0) {
157: if ($p_val[0]) {
158: trigger_error("Erreur: paramêtre manquant '".$p_nom."' \n", E_USER_WARNING);
159: }
160: }
161: if ($p_nom == '...') {
162: $this->parametres['...'] = array();
163: foreach ($parametres_cli as $arg) {
164: $this->parametres['...'][] = $arg;
165: }
166: $parametres_cli = array();
167: break;
168: } else {
169: if (isset($parametres_cli[$p_nom])) {
170: // Attribution de la valeur issue de la ligne de commande
171: $this->parametres[ltrim($p_nom, '-')] = $parametres_cli[$p_nom];
172: unset($parametres_cli[$p_nom]);
173: } else {
174: // Attribution de la valeur par défaut
175: if ($p_val[1] !== true) {
176: $this->parametres[ltrim($p_nom, '-')] = $p_val[1];
177: unset($parametres_cli[$p_nom]);
178: }
179: }
180: }
181: }
182:
183: // Gestion de l'excédant de paramêtres
184: if (count($parametres_cli)) {
185: trigger_error("Erreur: trop de paramêtres\n", E_USER_ERROR);
186: }
187: }
188:
189: /**
190: * Affiche un message d'erreur formaté.
191: * Si le paramétre de verbosité (-v) vaut 1 ou plus, le message est écrit dans le fichier de log et afficher dans la console.
192: *
193: * @param string le message d'erreur avec des %s.
194: * @param array le tableau des paramêtres à insérer dans le message d'erreur.
195: * @return void.
196: */
197: protected function traiterErreur($message, $tab_arguments = array()) {
198: $this->traiterMessage($message, $tab_arguments, self::MSG_ERREUR);
199: }
200:
201: /**
202: * Affiche un message d'avertissement formaté.
203: * Si le paramétre de verbosité (-v) vaut 1, le message est écrit dans le fichier de log.
204: * Si le paramétre de verbosité (-v) vaut 2 ou plus, le message est écrit dans le fichier de log et afficher dans la console.
205: *
206: * @param string le message d'erreur avec des %s.
207: * @param array le tableau des paramêtres à insérer dans le message d'erreur.
208: * @return void.
209: */
210: protected function traiterAvertissement($message, $tab_arguments = array()) {
211: $this->traiterMessage($message, $tab_arguments, self::MSG_AVERTISSEMENT);
212: }
213:
214: /**
215: * Retourne un message d'information formaté.
216: * Si le paramétre de verbosité (-v) vaut 1 ou 2 , le message est écrit dans le fichier de log.
217: * Si le paramétre de verbosité (-v) vaut 3 ou plus, le message est écrit dans le fichier de log et afficher dans la console.
218: *
219: * @param string le message d'information avec des %s.
220: * @param array le tableau des paramêtres à insérer dans le message d'erreur.
221: * @return void.
222: */
223: protected function traiterInfo($message, $tab_arguments = array()) {
224: $this->traiterMessage($message, $tab_arguments, self::MSG_INFO);
225: }
226:
227: /**
228: * Retourne un message formaté en le stockant dans un fichier de log si nécessaire.
229: *
230: * @param string le message d'erreur avec des %s.
231: * @param array le tableau des paramêtres à insérer dans le message d'erreur.
232: * @param int le niveau de verbosité à dépasser pour afficher les messages.
233: * @return void.
234: */
235: private function traiterMessage($message, $tab_arguments, $niveau = self::MSG_LOG) {
236: $log = $this->formaterMsg($message, $tab_arguments, $niveau);
237: if ($this->getParametre('v') > ($niveau - 1)) {
238: echo $log;
239: if (Config::get('log_script')) {
240: // TODO : lancer le log
241: }
242: }
243: }
244:
245: /**
246: * Retourne un message d'information formaté.
247: *
248: * @param string le message d'information avec des %s.
249: * @param array le tableau des paramêtres à insérer dans le message d'erreur.
250: * @return string le message d'erreur formaté.
251: */
252: protected function formaterMsg($message, $tab_arguments = array(), $niveau = null) {
253: $texte = vsprintf($message, $tab_arguments);
254: $prefixe = date('Y-m-j_H:i:s', time());
255: $prefixe .= is_null($niveau) ? ' : ' : ' - '.self::getMsgNiveauTxt($niveau).' : ';
256: $log = $prefixe.$texte."\n";
257: return $log;
258: }
259:
260: /**
261: * Utiliser cette méthode dans une boucle pour afficher un message suivi du nombre de tour de boucle effectué.
262: * Vous devrez vous même gérer le retour à la ligne à la sortie de la boucle.
263: *
264: * @param string le message d'information.
265: * @param int le nombre de départ à afficher.
266: * @return void le message est affiché dans la console.
267: */
268: protected function afficherAvancement($message, $depart = 0) {
269: if (! isset(self::$avancement[$message])) {
270: self::$avancement[$message] = $depart;
271: echo "$message : ";
272:
273: $actuel =& self::$avancement[$message];
274: echo $actuel++;
275: } else {
276: $actuel =& self::$avancement[$message];
277:
278: // Cas du passage de 99 (= 2 caractères) à 100 (= 3 caractères)
279: $passage = 0;
280: if (strlen((string) ($actuel - 1)) < strlen((string) ($actuel))) {
281: $passage = 1;
282: }
283:
284: echo str_repeat(chr(8), (strlen((string) $actuel) - $passage));
285: echo $actuel++;
286: }
287: }
288: }
289: ?>