Subversion Repositories Applications.framework

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
467 jpm 1
<?php
2
// declare(encoding='UTF-8');
3
/**
4
 * Classe de gestion des exceptions.
5
 * C'est un Singleton.
6
 *
7
 * @category	PHP 5.2
8
 * @package	Framework
9
 * @author		Aurélien PERONNET <aurelien@tela-botanica.org>
10
 * @author		Jean-Pascal MILCENT <jmp@tela-botanica.org>
11
 * @copyright	Copyright (c) 2009, Tela Botanica (accueil@tela-botanica.org)
12
 * @license	http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
13
 * @license	http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
14
 * @version	$Id: GestionnaireException.php 342 2011-06-06 13:58:53Z jpm $$
15
 * @link		/doc/framework/
16
 *
17
 */
18
class GestionnaireException {
19
 
20
	const MODE_CLI = 'cli';
21
 
22
	/** Liste des exceptions enregistrées */
23
	private static $exceptions = array();
24
 
25
	/** Détermine si l'on affiche ou non le contexte */
26
	private static $contexte = false;
27
 
28
	 /** Détermine si l'on loggue ou non les erreurs */
29
	private static $logger = false;
30
 
31
	/** Détermine si l'affichage des erreurs est forcé (true) ou pas (false) à la destruction de la classe */
32
	private static $afficher = false;
33
 
34
	/** Definit si php est lancé en ligne de commande ou en mode serveur */
35
	private static $mode = null ;
36
 
37
	/** Initialise le Gestionnaire d'exceptions et d'erreur sans tenir comptes des paramêtres de config. */
38
	public static function initialiser() {
39
		self::$mode = php_sapi_name();
40
		// Désactivation des balises HTML dans les messages d'erreur de PHP en mode ligne de commande
41
		if (self::$mode == self::MODE_CLI) {
42
			ini_set('html_errors', 0);
43
		}
44
 
45
		set_exception_handler(array(get_class(),'gererException'));
46
		set_error_handler(array(get_class(),'gererErreur'));
47
	}
48
 
49
	/** Configure le Gestionnaire d'exceptions et d'erreur à partir des paramêtres de config. */
50
	public static function configurer() {
51
		self::$contexte = Config::get('fw_debogage_contexte');
52
		self::$logger = Config::get('fw_log_debogage');
53
		self::$afficher = Config::get('fw_debogage');
54
	}
55
 
56
	/**
57
	 * Renvoie le nombre d'exceptions et d'erreurs levées.
58
	 * @see getExceptions() pour obtenir les exceptions formatées.
59
	 * @since 0.3
60
	 * @return int le nombre d'exception actuellement levées
61
	 */
62
	public static function getExceptionsNbre() {
63
		return count(self::$exceptions);
64
	}
65
 
66
	/**
67
	 * Renvoie le booleen définissant si l'on affiche le contexte ou non
68
	 * @return bool true si on affiche le contexte sinon false.
69
	 */
70
	public static function getContexte() {
71
		return self::$contexte;
72
	}
73
 
74
	/**
75
	 * Definit si l'on veut afficher le contexte ou non
76
	 * @param bool true si on veut afficher le contexte, false sinon, par défaut vaut false
77
	 */
78
	public static function setContexte($contexte) {
79
		self::$contexte = $contexte;
80
	}
81
 
82
	/**
83
	 * Fonction de gestion des exceptions, remplace le handler par défaut.
84
	 * Si une boucle génère de multiple exception (ou erreur) identique une seule sera stockée.
85
	 * @param Exception $e l'exception à traiter
86
	 */
87
	public static function gererException(Exception $e) {
88
		$cle = hash('md5', $e->getMessage().'-'.$e->getFile().'-'.$e->getLine());
89
		if (!isset(self::$exceptions[$cle])) {
90
			self::$exceptions[$cle] = $e;
91
			self::loggerException($e);
92
		}
93
	}
94
 
95
	/**
96
	 * Gère les erreurs en les convertissant en exceptions (remplace la fonction gestion d'erreurs native de php)
97
	 * @param int $niveau le niveau de l'erreur
98
	 * @param string $message le message associé à l'erreur
99
	 * @param string $fichier le nom du fichier où l'erreur s'est produite
100
	 * @param int $ligne la ligne où l'erreur s'est produite
101
	 * @param string $contexte le contexte associé à l'erreur
102
	 */
103
	public static function gererErreur($niveau,  $message,  $fichier,  $ligne,  $contexte){
104
		// Si un rapport d'erreur existe, création d'une exception
105
		if (error_reporting() != 0) {
106
			$e = new ErrorException($message, 0, $niveau, $fichier, $ligne);
107
			self::gererException($e);
108
		}
109
		return null;
110
	}
111
 
112
	/**
113
	 * Renvoie les exceptions au format (X)HTML ou bien au format texte suivant le mode d'utilisation de PHP.
114
	 * @since 0.3
115
	 * @deprecated
116
	 * @see getExceptionsFormatees()
117
	 * @return string les exceptions formatées en texte ou (X)HTML.
118
	 */
119
	public static function getExceptions() {
120
		return self::getExceptionsFormatees();
121
	}
122
 
123
	/**
124
	 * Renvoie les exceptions au format (X)HTML ou bien au format texte suivant le mode d'utilisation de PHP.
125
	 * @since 0.3
126
	 * @return string les exceptions formatées en texte ou (X)HTML.
127
	 */
128
	public static function getExceptionsFormatees() {
129
		$retour = '';
130
		if (self::getExceptionsNbre() > 0) {
131
			foreach (self::$exceptions as $cle => $e) {
132
				switch (self::$mode) {
133
					case self::MODE_CLI :
134
						$retour .= self::formaterExceptionTxt($e);
135
						break;
136
					default:
137
						$retour .= self::formaterExceptionXhtml($e);
138
				}
139
				// Nous vidons le tableau des exceptions au fur et à mesure pour éviter le réaffichage avec le destructeur.
140
				unset(self::$exceptions[$cle]);
141
			}
142
		}
143
		return $retour;
144
	}
145
 
146
	/**
147
	 * Renvoie le tableau d'objets Exception générées par le script PHP triées du niveau de sévérité le plus élevé au moins élevé.
148
	 * Format du tableau :
149
	 * array{sévérité_1 = array{Exception1, Exception2, Exception3,...}, sévérité_1 =  array{Exception1, Exception2, ...}, ...};
150
	 * ATTENTION : si vous utilisez cette méthode, c'est à vous de gérer l'affichage des Exceptions. Le gestionnaire d'exception
151
	 * n'enverra plus rien au navigateur ou à la console.
152
	 * @since 0.3
153
	 * @return array le tableau trié d'objet Exception.
154
	 */
155
	public static function getExceptionsTriees() {
156
		$retour = array();
157
		if (self::getExceptionsNbre() > 0) {
158
			foreach (self::$exceptions as $cle => $e) {
159
				$retour[$e->getSeverity()][] = $e;
160
				// Nous vidons le tableau des exceptions au fur et à mesure pour éviter le réaffichage avec le destructeur.
161
				unset(self::$exceptions[$cle]);
162
			}
163
			ksort($retour);
164
		}
165
		return $retour;
166
	}
167
 
168
	/**
169
	 * Logue une exception donnée sous une forme lisible si self::logger vaut true.
170
	 * @param Exception	$e l'exception à logger
171
	 */
172
	private static function loggerException(Exception $e) {
173
		if (self::$logger) {
174
			$message = self::formaterExceptionTxt($e);
175
			Log::ajouterEntree('erreurs', $message);
176
		}
177
	}
178
 
179
	/**
180
	 * Formate en texte une exception passée en paramètre.
181
	 * @since 0.3
182
	 * @param Exception l'exception à formater.
183
	 */
184
	public static function formaterExceptionTxt(Exception $e) {
185
		$message = '';
186
		$message .= $e->getMessage()."\n";
187
		$message .= 'Fichier : '.$e->getFile()."\n";
188
		$message .= 'Ligne : '.$e->getLine()."\n";
189
		if (self::getContexte()) {
190
			$message .= 'Contexte : '."\n".print_r($e->getTraceAsString(), true)."\n";
191
		}
192
		$message .= "\n";
193
		return $message;
194
	}
195
 
196
	/**
197
	 * Formate en (X)HTML une exception passée en paramètre.
198
	 * @since 0.3
199
	 * @param Exception l'exception à formater.
200
	 */
201
	public static function formaterExceptionXhtml(Exception $e) {
202
		$message = '';
203
		$message .= '<div class="debogage">'."\n";
204
		$message .= $e->getMessage()."\n";
205
		$message .= '<span class="debogage_fichier">'.'Fichier : '.$e->getFile().'</span>'."\n";
206
		$message .= '<span class="debogage_ligne">'.'Ligne : '.$e->getLine().'</span>'."\n";
207
		if (self::getContexte()) {
208
			$message .= '<pre>'."\n";
209
			$message .= '<strong>Contexte : </strong>'."\n".print_r($e->getTraceAsString(), true)."\n";
210
			$message .= '</pre>'."\n";
211
		}
212
		$message .= '</div>'."\n";
213
		return $message;
214
	}
215
 
216
	/**
217
	 * Lors de la destruction de la classe si des exceptions n'ont pas été affichées, et si le débogage est à true, elles sont
218
	 * affichées.
219
	 */
220
	public function __destruct() {
221
		// Si des erreurs n'ont pas été affichée nous forçons leur affichage
222
		if (self::$afficher && self::getExceptionsNbre() > 0) {
223
			echo self::getExceptionsFormatees();
224
		}
225
	}
226
 
227
}
228
?>