Subversion Repositories eFlore/Projets.eflore-projets

Rev

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

Rev Author Line No. Line
106 aurelien 1
<?php
2
class Images {
3
 
4
	private $Bdd;
5
	private $formats_supportes = array('jpeg');
6
	private $format_retour_demande = 'jpeg';
7
	private $format_image_demande = 'M';
8
	private $num_nom_demande = null;
9
	private $ref_tax_demande = 'bdtfx';
10
 
11
	private $pattern_ref_tax_nn_composes = '/(([a-zA-Z]:((([0-9])+,)*([0-9])+));)*([a-zA-Z]:((([0-9])+,)*([0-9])+))*/i';
12
 
13
	public function consulter($ressources, $parametres) {
14
		$this->bdd_cel = Config::get('bdd_nom');
15
		$parametres = $this->traiterParametres();
16
 
17
		try {
18
			$this->verifierErreurs($parametres);
19
			$this->affecterParametres($parametres);
20
			$id_image_a_renvoyer = $this->obtenirImageAuHasardPourNumNom($this->ref_tax_demande, $this->num_nom_demande);
21
			$this->traiterRetour($id_image_a_renvoyer);
22
		} catch (Exception $e) {
23
			$header = $this->renvoyerHeaderAssocie($e->getCode());
24
			$erreurs = $e->getMessage();
25
 
26
			header($header);
27
			$this->envoyerTexteSimple($erreurs);
28
			exit;
29
		}
30
	}
31
 
32
	protected function traiterParametres() {
33
		$parametres_bruts = array();
34
		if (!empty($_SERVER['QUERY_STRING'])) {
35
			$paires = explode('&', $_SERVER['QUERY_STRING']);
36
			foreach ($paires as $paire) {
37
				$nv = explode('=', $paire);
38
				$nom = urldecode($nv[0]);
39
				$valeur = urldecode($nv[1]);
40
				$parametres_bruts[$nom] = $valeur;
41
			}
42
			$parametres_bruts = $this->nettoyerParametres($parametres_bruts);
43
		}
44
		return $parametres_bruts;
45
	}
46
 
47
	private function nettoyerParametres(Array $parametres) {
48
		// Pas besoin d'utiliser urldecode car déjà fait par php pour les clés et valeur de $_GET
49
		if (isset($parametres) && count($parametres) > 0) {
50
			foreach ($parametres as $cle => $valeur) {
51
				$verifier = array('NULL', "\n", "\r", "\\", "'", '"', "\x00", "\x1a", ';');
52
				$parametres[$cle] = strip_tags(str_replace($verifier, '', $valeur));
53
			}
54
		}
55
		return $parametres;
56
	}
57
 
58
	private function verifierErreurs($parametres) {
59
		$erreurs = false;
60
 
61
		if (!isset($parametres['masque.nn'])) {
62
			$erreurs .= 'Le paramètre masque.nn est obligatoire '."\n";
63
		} else {
64
			if(!preg_match($this->pattern_ref_tax_nn_composes, $parametres['masque.nn'])) {
65
				$erreurs .= 'Le paramètre masque.nn est mal formé '."\n";
66
			}
67
		}
68
 
69
		if (isset($parametres['retour']) && !$this->retourEstSupporte($parametres['retour'])) {
70
			$erreurs .= 'Le type de retour '.$parametres['retour'].' n\'est pas supporté  '."\n";
71
		}
72
 
73
		if (isset($parametres['retour.format']) && !$this->formatEstSupporte($parametres['retour.format'])) {
74
			$erreurs .= 'Le type de format '.$parametres['retour.format'].' n\'est pas supporté  '."\n";
75
		}
76
 
77
		if($erreurs != '') {
78
			throw new Exception($erreurs, "400");
79
		}
80
	}
81
 
82
	private function retourEstSupporte($retour = 'image/jpeg') {
83
		return in_array($retour, $this->formats_supportes);
84
	}
85
 
86
	private function formatEstSupporte($format = 'M') {
87
 
88
		$format_supporte = true;
89
		// cas du format déjà existant (S, M, L etc...)
90
		$format_supporte = $this->estUnFormatDejaCree($format);
91
 
92
		return $format_supporte;
93
	}
94
 
95
	private function estUnFormatDejaCree($format = 'M') {
96
		$formats = $this->getFormats();
97
		$format_supporte = isset($formats['format_'.$format]) ? true : false;
98
 
99
		return $format_supporte;
100
	}
101
 
102
	private function getFormats() {
103
		$formats = array();
104
 
105
		foreach (Config::get('formats_images') as $param_config => $valeur) {
106
			$formats[$param_config] = $valeur;
107
		}
108
 
109
		return $formats;
110
	}
111
 
112
	private function affecterParametres($parametres) {
113
		// cette fonction est appelée en considérant que les vérifications d'erreurs ont été passées
114
		// avec succès
115
		$this->analyserMasqueNumNom($parametres['masque.nn']);
116
		if(isset($parametres['retour'])) {
117
			$this->format_retour_demande =  $parametres['retour'] ;
118
		}
119
		if(isset($parametres['retour.format'])) {
120
			$this->format_image_demande = $parametres['retour.format'];
121
		}
122
	}
123
 
124
		private function analyserMasqueNumNom($masque_num_nom) {
125
		// cette fonction est appelée en considérant que le masque num nom est valide
126
			// cas du numero sans référentiel : ref tax par defaut
127
		if(is_numeric($masque_num_nom)) {
128
			$this->num_nom_demande = $masque_num_nom;
129
		} else {
130
		// ceci contient potentiellement des formes ref_tax1:nn1,nn2;ref_tax2:nn3,nn4
131
		$composants_masques = explode(';', $masque_num_nom);
132
		if (count($composants_masques) > 0) {
133
				foreach($composants_masques as $composant_ref_nn) {
134
					$ref_nn = explode(':', $composant_ref_nn);
135
					$this->ref_tax_demande[$composant_ref_nn[0]] = explode(',', $composant_ref_nn[1]);
136
				}
137
			}
138
		}
139
	}
140
 
141
	private function obtenirImageAuHasardPourNumNom($ref_tax, $num_nom) {
142
		//TODO: modifier la requete lors du passage à la nouvelle base de données pour faire quelque chose
143
		// du numéro nomenclatural + modifier les champs appelés pour le nouveau format
144
		$requete = 	'SELECT  cim.ci_id_image as id_image '.
145
							'FROM cel_obs_images AS coi '.
146
							'LEFT JOIN cel_inventory AS ci '.
147
								'ON (coi.coi_ce_observation = ci.ordre AND coi.coi_ce_utilisateur = ci.identifiant) '.
148
							'LEFT JOIN cel_images AS cim '.
149
								'ON (coi.coi_ce_image = cim.ci_id_image AND coi.coi_ce_utilisateur = cim.ci_ce_utilisateur) '.
150
							'WHERE ci.transmission = 1 '.
151
							'	AND num_nom_sel = '.$this->getBdd()->proteger($num_nom).
152
							'	AND ci.identifiant = cim.ci_ce_utilisateur ';
153
 
154
		$resultat_images = $this->getBdd()->recupererTous($requete);
155
 
156
		if (!is_array($resultat_images) || count($resultat_images) <= 0) {
157
			$erreur = 'Aucune image ne correspond au numéro numenclatural '.$ref_tax.':'.$num_nom."\n";
158
			throw new Exception("404");
159
		}
160
 
161
		$id_image_hasard = $resultat_images[array_rand($resultat_images)]['id_image'];
162
		return $id_image_hasard;
163
	}
164
 
165
	private function traiterRetour($id_image_a_renvoyer) {
166
		switch($this->format_retour_demande) {
167
			case 'jpeg':
168
				$this->renvoyerImageExistanteOuGeneree($id_image_a_renvoyer, $this->format_image_demande);
169
				break;
170
 
171
			default:
172
				$this->renvoyerImageExistanteOuGeneree($id_image_a_renvoyer, 'image/jpeg');
173
			break;
174
		}
175
	}
176
 
177
	private function renvoyerImageExistanteOuGeneree($id_image_a_renvoyer, $format = 'M') {
178
		if ($this->estUnFormatDejaCree($format)) {
179
			$this->renvoyerImageExistante($id_image_a_renvoyer, $format);
180
		} else {
181
			throw new Exception("La génération de formats à la demande n'est pas encore implémentée", "501");
182
		}
183
	}
184
 
185
	private function renvoyerImageExistante($id_image, $format = 'M') {
186
		$chemin = $this->functionObtenirCheminImagePourFormat($id_image, $format);
187
		if(file_exists($chemin)) {
188
			header("HTTP/1.0 200 OK");
189
			header("Content-type: image/jpeg");
190
			echo file_get_contents($chemin);
191
			exit;
192
		} else {
193
			throw new Exception("L\'image demandée est introuvable sur le serveur", "404");
194
		}
195
	}
196
 
197
	public function functionObtenirCheminImagePourFormat($id_image, $format) {
198
		$nom = $this->convertirIdBddVersNomFichier($id_image, $format);
199
		$dossier = $this->obtenirDossierPourFormat($id_image,$format);
200
 
201
		return $dossier.'/'.$nom;
202
	}
203
 
204
	private function obtenirDossierPourFormat($id, $format) {
205
		$chemin_base = Config::get('chemin_images');
206
 
207
		$chemin_sur_serveur = $chemin_base;
208
 
209
		$id = sprintf('%09s', $id);
210
		$id = wordwrap($id, 3 , '_', true);
211
 
212
		list($dossierNiveau1, $dossierNiveau2) = explode('_', $id);
213
 
214
		$chemin_sur_serveur_final = $chemin_sur_serveur.'/'.$dossierNiveau1.'/'.$dossierNiveau2.'/'.$format;
215
 
216
		return $chemin_sur_serveur_final;
217
	}
218
 
219
	public function convertirIdBddVersNomFichier($id, $format, $extension = 'jpg') {
220
		// creation du format original
221
		$id_avec_zeros = sprintf('%09s', $id) ;
222
		$id_avec_zeros_underscores = wordwrap($id_avec_zeros, 3 , '_', true) ;
223
 
224
		$nom_fichier = $id_avec_zeros_underscores.'_'.$format.'.'.$extension;
225
 
226
		return $nom_fichier;
227
	}
228
 
229
	private function envoyerTexteSimple($chaine) {
230
		header("Content-type: text/plain");
231
		echo $chaine;
232
	}
233
 
234
	private function renvoyerHeaderAssocie($code) {
235
		switch ($code) {
236
			case '501':
237
				$header = "HTTP/1.0 501 Not Implemented";
238
			break;
239
 
240
			case '500':
241
				$header = "HTTP/1.0 500 Internal Server Error";
242
			break;
243
 
244
			case '404':
245
				$header = "HTTP/1.0 404 Not Found";
246
			break;
247
 
248
			case '400':
249
				$header = "HTTP/1.0 400 Bad Request";
250
			break;
251
 
252
			case '200':
253
				$header = "HTTP/1.0 200 OK";
254
			break;
255
 
256
			default:
257
			break;
258
		}
259
	}
260
 
261
	/**
262
	* Méthode de connection à la base de données sur demande.
263
	* Tous les services web n'ont pas besoin de s'y connecter.
264
	*/
265
	protected function getBdd() {
266
		if (! isset($this->Bdd)) {
267
			$this->Bdd = new Bdd();
268
		}
269
		return $this->Bdd;
270
	}
271
}
272
?>