Subversion Repositories eFlore/Applications.cel

Rev

Rev 488 | Rev 504 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
416 aurelien 1
<?php
2
/**
3
 * Classe mère abstraite contenant les méthodes génériques des services.
4
 * Encodage en entrée : utf8
5
 * Encodage en sortie : utf8
6
 *
7
 * @author Jean-Pascal MILCENT <jpm@clapas.org>
8
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
9
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
10
 * @version $Id$
11
 * @copyright © 2010, Jean-Pascal MILCENT
12
 */
13
abstract class Cel {
14
 
15
	public $config;
489 jpm 16
	public $parametres;
416 aurelien 17
	protected $bdd;
18
	protected $messages = array();
19
	protected $debug = array();
20
 
21
	public function __construct($config) {
22
		// Tableau contenant la config de Jrest
23
		$this->config = $config;
24
 
25
		// Réglages de PHP
26
		setlocale(LC_ALL, $this->config['settings']['locale']);
27
		date_default_timezone_set($this->config['settings']['fuseauHoraire']);
28
 
29
		// Connection à la base de données
30
		$this->bdd = $this->connecterPDO($this->config, 'database_cel');
31
 
32
		// Nettoyage du _GET (sécurité)
33
		$this->recupererParametresUrl();
34
		$this->definirParametresUrlParDefaut();
35
 
36
		// Définition de variable générale dans la config
37
		$this->config['settings']['baseURLAbsoluDyn'] = 'http://'.$_SERVER['SERVER_NAME'].$this->config['settings']['baseURL'].'%s';
38
	}
39
 
40
	//+----------------------------------------------------------------------------------------------------------------+
41
	// GESTION de la BASE de DONNÉES
42
 
43
	private function connecterPDO($config, $base = 'database') {
44
        $cfg = $config[$base];
477 delphine 45
        // ATTENTION : la connexin à la bdd peut échouer si l'host vaut localhost. Utiliser 127.0.0.1 à la place.
416 aurelien 46
		$dsn = $cfg['phptype'].':dbname='.$cfg['database'].';host='.$cfg['hostspec'];
47
		try {
477 delphine 48
    		// Création de la connexion en UTF-8 à la BDD
49
			$PDO = new PDO($dsn, $cfg['username'], $cfg['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"));
416 aurelien 50
		} catch (PDOException $e) {
51
    		echo 'La connexion à la base de donnée via PDO a échouée : ' . $e->getMessage();
52
		}
53
		// Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché)
54
		$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
55
        return $PDO;
56
	}
57
 
58
	protected function executerRequete($requete, $retour = 'All', $mode = PDO::FETCH_ASSOC) {
59
		try {
60
			switch ($retour) {
61
				case 'All' :
62
					$resultat = $this->bdd->query($requete)->fetchAll($mode);
63
					break;
64
				case 'Column' :
65
					$resultat = $this->bdd->query($requete)->fetchColumn();
66
					break;
67
				default:
68
					$resultat = false;
69
					$this->messages[] = "Le type de retour '$retour' est inconnu.";
70
			}
71
			if ($resultat === false) {
72
				$this->messages[] = "La requête a retourné aucun résultat.";
73
			}
74
		} catch (PDOException $e) {
75
			$this->messages[] = sprintf($this->getTxt('sql_erreur_requete'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete);
76
		}
77
		return $resultat;
78
	}
79
 
80
	protected function getTxt($id) {
81
		$sortie = '';
82
		switch ($id) {
83
			case 'sql_erreur' : $sortie = 'Requête echec. Fichier : "%s". Ligne : "%s". Message : %s'; break;
84
			case 'sql_erreur_requete' : $sortie = "Requête echec.\nFichier : %s.\nLigne : %s.\nMessage : %s.\nRequête : %s"; break;
85
			default : $sortie = $id;
86
		}
87
		return $sortie;
88
	}
89
 
90
	//+----------------------------------------------------------------------------------------------------------------+
91
	// TRAITEMENT des URLs et des PARAMÊTRES
92
 
93
	private function recupererParametresUrl() {
94
		if (isset($_GET)) {
95
			$get_params = array('orderby', 'distinct', 'start', 'limit', 'formatRetour');
96
			foreach ($get_params as $get) {
97
				if (isset($_GET[$get])) {
98
					$verifier = array('NULL', "\n", "\r", "\\", "'", '"', "\x00", "\x1a", ';');
99
					$_GET[$get] = strip_tags(str_replace($verifier, '', $_GET[$get]));
100
					if ($_GET[$get] != '') {
101
						if (!isset($this->$get)) {
102
							$this->$get = $_GET[$get];
103
						} else {
104
							$e = "Impossible d'ajouter l'attribut $get à la classe du service car elle possède déjà un attribut nommé : $get";
105
							trigger_error($e, E_USER_WARNING);
106
						}
107
					} else {
108
						$_GET[$get] = null;
109
					}
110
				}
111
			}
112
		}
113
	}
114
 
115
	private function definirParametresUrlParDefaut() {
116
		if (!isset($this->start)) {
117
			$this->start = 0;
118
		}
119
		if (!isset($this->limit)) {
120
			$this->limit = 150;
121
		}
122
	}
123
 
124
	protected function traiterParametres($params_attendu, $params, $pourBDD = true) {
125
		$sortie = array();
126
		foreach ($params_attendu as $num => $nom) {
127
			if (isset($params[$num]) && $params[$num] != '*') {
128
				if ($pourBDD) {
129
					$params[$num] = $this->bdd->quote($params[$num]);
130
				}
131
				$sortie[$nom] = $params[$num];
132
			}
133
		}
134
		return $sortie;
135
	}
136
 
137
	protected function traiterNomMethodeGet($nom) {
138
		$methode = 'get';
139
		$methode .= str_replace(' ', '', ucwords(str_replace('-', ' ', strtolower($nom))));
140
		return $methode;
141
	}
142
 
143
	//+----------------------------------------------------------------------------------------------------------------+
144
	// GESTION de l'ENVOIE au NAVIGATEUR
145
 
146
	protected function envoyerJson($variable, $donnees = null, $encodage = 'utf-8') {
147
		$contenu = "var $variable = ".json_encode($donnees);
148
		$this->envoyer($contenu, 'text/html', $encodage);
149
	}
489 jpm 150
 
151
	protected function envoyerJsonp($variable, $donnees = null, $encodage = 'utf-8') {
152
		$contenu = $_GET['callback'].'('.json_encode($donnees).');';
153
		$this->envoyer($contenu, 'text/html', $encodage);
154
	}
416 aurelien 155
 
156
	protected function envoyer($donnees = null, $mime = 'text/html', $encodage = 'utf-8', $json = false) {
157
		// Traitements des messages d'erreurs et données
158
		if (count($this->messages) != 0) {
159
			header('HTTP/1.1 500 Internal Server Error');
160
			$mime = 'text/html';
161
			$encodage = 'utf-8';
162
			$json = true;
163
			$sortie = $this->messages;
164
		} else {
165
			$sortie = $donnees;
166
			if (is_null($donnees)) {
167
				$sortie = 'OK';
168
			}
169
		}
170
 
171
		// Gestion de l'envoie du déboguage
172
		$this->envoyerDebogage();
173
 
174
		// Encodage au format et JSON et envoie sur la sortie standard
175
		$contenu = $json ? json_encode($sortie) : $sortie;
176
		$this->envoyerContenu($encodage, $mime, $contenu);
177
	}
178
 
179
	private function envoyerDebogage() {
180
		if (!is_array($this->debug)) {
181
			$this->debug[] = $this->debug;
182
		}
183
		if (count($this->debug) != 0) {
184
			foreach ($this->debug as $cle => $val) {
185
				if (is_array($val)) {
186
					$this->debug[$cle] = print_r($val, true);
187
				}
188
			}
189
			header('X-DebugJrest-Data:'.json_encode($this->debug));
190
		}
191
	}
192
 
193
	private function envoyerContenu($encodage, $mime, $contenu) {
194
		if (!is_null($mime) && !is_null($encodage)) {
195
			header("Content-Type: $mime; charset=$encodage");
196
		} else if (!is_null($mime) && is_null($encodage)) {
197
			header("Content-Type: $mime");
198
		}
199
		print $contenu;
200
	}
201
 
202
	private function envoyerAuth($message_accueil, $message_echec) {
203
		header('HTTP/1.0 401 Unauthorized');
204
		header('WWW-Authenticate: Basic realm="'.mb_convert_encoding($message_accueil, 'ISO-8859-1', 'UTF-8').'"');
205
		header('Content-type: text/plain; charset=UTF-8');
206
		print $message_echec;
207
		exit(0);
208
	}
209
 
210
	//+----------------------------------------------------------------------------------------------------------------+
211
	// GESTION DU DAO
212
 
213
	protected function getDao() {
214
		if (isset($this->dao)) {
215
			return $this->dao;
216
		} else {
217
			$e = "Le DAO n'a pas été initialisé. Utiliser la méthode initialiserDao().";
218
			trigger_error($e, E_USER_WARNING);
219
		}
220
	}
221
 
222
	protected function initialiserDao($url_services_distant) {
223
		if (is_null($this->dao)) {
224
			$this->dao = new CelDao($url_services_distant);
225
		} else {
226
			$this->dao->url_jrest = $url_services_distant;
227
		}
228
	}
229
 
230
	//+----------------------------------------------------------------------------------------------------------------+
231
	// GESTION DE L'IDENTIFICATION
232
 
233
	public function authentifier() {
234
		$message_accueil = "Veuillez vous identifier avec votre compte Tela Botanica.";
235
		$message_echec = "Accès limité aux administrateurs du CEL.\n".
236
			"Votre tentative d'identification a échouée.\n".
237
			"Actualiser la page pour essayer à nouveau.";
238
		if (!isset($_SERVER['PHP_AUTH_USER'])) {
239
			$this->envoyerAuth($message_accueil, $message_echec);
240
		} else {
241
			if ($this->etreAutorise($_SERVER['PHP_AUTH_USER']) == false) {
242
				$this->envoyerAuth($message_accueil, $message_echec);
243
			}
244
		}
245
		return true;
246
	}
247
 
248
	public function etreAutorise($identifiant) {
249
		$this->initialiserDao('http://www.tela-botanica.org/client/annuaire_nouveau/actuelle/jrest/');
250
		$mdp = md5($_SERVER['PHP_AUTH_PW']);
251
		$url = $this->getDao()->url_jrest."TestLoginMdp/$identifiant/$mdp";
252
		$json = $this->getDao()->envoyerRequeteConsultation($url);
253
		$existe = json_decode($json);
254
		$autorisation = false;
255
		if ($existe == true && $this->etreAdminCel($identifiant)) {
256
			$autorisation = true;
257
		}
258
		return $autorisation;
259
	}
260
 
261
	public function etreAdminCel($courriel) {
262
		$admins = $this->config['jrest_admin']['admin'];
263
		$courriels_autorises = explode(',', $admins);
264
 
265
		$autorisation = (in_array($courriel, $courriels_autorises)) ? true : false ;
266
		return $autorisation;
267
	}
268
 
269
	//+----------------------------------------------------------------------------------------------------------------+
270
	// GESTION DE MÉTHODES COMMUNES ENTRE LES SERVICES
271
 
272
	protected function encoderMotCle($mot_cle) {
273
		return md5(mb_strtolower($mot_cle));
274
	}
275
 
474 jpm 276
	protected function tronquerCourriel($courriel) {
277
		$courriel = preg_replace('/[^@]+$/i', '...', $courriel);
278
		return $courriel;
279
	}
280
 
488 jpm 281
	protected function nettoyerTableau(Array $tableau) {
474 jpm 282
		foreach ($tableau as $cle => $valeur) {
283
			if (is_array($valeur)) {
284
				$valeur = $this->nettoyerTableau($valeur);
285
			} else {
286
				$valeur = $this->nettoyerTexte($valeur);
287
			}
288
			$tableau[$cle] = $valeur;
289
		}
290
		return $tableau;
291
	}
292
 
293
	protected function nettoyerTexte($txt) {
294
		$txt = preg_replace('/&(?!(a-z+|#0-9+|#x0-9a-f+);)/i', '&amp;', $txt);
295
		$txt = preg_replace('/000null/i', '', $txt);
296
		return $txt;
297
	}
298
 
416 aurelien 299
	//+----------------------------------------------------------------------------------------------------------------+
300
	// GESTION DES SQUELETTES PHP
301
 
302
	/**
303
	 * Méthode prenant en paramètre un chemin de fichier squelette et un tableau associatif de données,
304
	 * en extrait les variables, charge le squelette et retourne le résultat des deux combinés.
305
	 *
306
	 * @param String $fichier	le chemin du fichier du squelette
307
	 * @param Array  $donnees	un tableau associatif contenant les variables a injecter dans le squelette.
308
	 *
309
	 * @return boolean false si le squelette n'existe pas, sinon la chaine résultat.
310
	 */
311
	public static function traiterSquelettePhp($fichier, Array $donnees = array()) {
312
		$sortie = false;
313
		if (file_exists($fichier)) {
314
			// Extraction des variables du tableau de données
315
			extract($donnees);
316
			// Démarage de la bufferisation de sortie
317
			ob_start();
318
			// Si les tags courts sont activés
319
			if ((bool) @ini_get('short_open_tag') === true) {
320
				// Simple inclusion du squelette
321
				include $fichier;
322
			} else {
323
				// Sinon, remplacement des tags courts par la syntaxe classique avec echo
324
				$html_et_code_php = self::traiterTagsCourts($fichier);
325
				// Pour évaluer du php mélangé dans du html il est nécessaire de fermer la balise php ouverte par eval
326
				$html_et_code_php = '?>'.$html_et_code_php;
327
				// Interprétation du html et du php dans le buffer
328
				echo eval($html_et_code_php);
329
			}
330
			// Récupèration du contenu du buffer
331
			$sortie = ob_get_contents();
332
			// Suppression du buffer
333
			@ob_end_clean();
334
		} else {
335
			$msg = "Le fichier du squelette '$fichier' n'existe pas.";
336
			trigger_error($msg, E_USER_WARNING);
337
		}
338
		// Retourne le contenu
339
		return $sortie;
340
	}
341
 
342
	/**
343
	 * Fonction chargeant le contenu du squelette et remplaçant les tags court php (<?= ...) par un tag long avec echo.
344
	 *
345
	 * @param String $chemin_squelette le chemin du fichier du squelette
346
	 *
347
	 * @return string le contenu du fichier du squelette php avec les tags courts remplacés.
348
	 */
349
	private static function traiterTagsCourts($chemin_squelette) {
350
		$contenu = file_get_contents($chemin_squelette);
351
		// Remplacement de tags courts par un tag long avec echo
352
		$contenu = str_replace('<?=', '<?php echo ',  $contenu);
353
		// Ajout systématique d'un point virgule avant la fermeture php
354
		$contenu = preg_replace("/;*\s*\?>/", "; ?>", $contenu);
355
		return $contenu;
356
	}
357
}