Subversion Repositories eFlore/Applications.moissonnage

Rev

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

Rev Author Line No. Line
26 alex 1
<?php
2
 
3
 
4
/**
5
 * Classe commune a tous les services de ce projet qui va analyser et rechercher des erreurs
6
 * sur les valeurs passees en parametres lors d'un appel a ces web services.
7
 *
8
 * Les parametres suivants sont traites :
9
 *   - zoom : le niveau de zoom sur la carte (API cartographique client)
10
 *     On va verifier que c'est un nombre entier compris entre une valeur minimale et une valeur maximale
11
 *
12
 *   - bbox : rectangle dont les bords delimitent en coordonnees l'espace de recherche de donnees spatiales
13
 *     L'ordre des valeurs est le suivant : ouest, sud, est, nord
14
 *     On va verifier que c'est une serie de quatre nombre decimaux delimites par des virgules
15
 *     et compris dans l'espace representant le monde a partir du systeme de projection WGS84 (EPSG:4326)
16
 *
17
 *   - longitude et latitude : representent les coordonnees d'un point dans l'espace
18
 *     On va verifier que ces coordonnees soient valides dans le systeme de projection utilise
19
 *
20
 *   - referentiel : referentiel taxonomique a utiliser. On peut passer aussi bien en parametres
21
 *     son nom court que son nom complet (incluant le numero de version)
22
 *     On va verifier la disponibilite du referentiel pour ce service
23
 *
24
 *   - num_taxon : numero taxonomique d'une espece
25
 *     On va rechercher sa presence dans les referentiels disponibles
26
 *     (les informations principales sur ce taxon seront renvoyees)
27
 *
28
 *   - dept : une liste de numeros de departements separees entre eux par des virgules
29
 *     On va verifier que chaque numero est un nombre entier et represente un code de departement valide
30
 *
31
 *   - auteur : l'auteur de l'observation
32
 *
33
 * La fonction principale de verification des parametres va parcourir tous les parametres, et verifier
34
 * pour chacun d'eux la validite de leurs valeurs. Dans le cas ou une valeur anormale est detectee
35
 * ou qu'elle se trouve en dehors de l'intervalle des resultats acceptes, une liste de messages d'erreur
36
 * sera generee et mise a jour.
37
 *
38
 * Le resultat final de la verfication peut entrainer deux cas d'utilisation possibles. Si des messages
39
 * d'erreurs ont ete generes durant la verification, ils sont regroupes en un seul message pour lever
40
 * une exception qui sera interpretee par la classe appelante. Dans le cas ou la verification n'a rien
41
 * rencontre d'anormal, une fonction renverra la liste des parametres valides utilisables
42
 * pour des recherches de donnees pour la suite du traitement pour le service.
43
 *
44
 * @package framework-0.3
45
 * @author Alexandre GALIBERT <alexandre.galibert@tela-botanica.org>
46
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
47
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
48
 * @version $Id$
49
 * @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
50
 *
51
 */
52
 
53
class VerificateurParametres {
54
 
55
	private $parametres = array();
56
	private $validation = null;
57
	private $erreurs = array();
58
 
59
	private $bboxMonde = null;
60
 
61
 
62
	public function __construct($parametres) {
63
		foreach ($parametres as $nomParametre => $valeur) {
64
			if ($nomParametre != 'source') {
65
				$this->parametres[$nomParametre] = $valeur;
66
			}
67
		}
68
		$this->bboxMonde = array(
69
			'ouest' => floatval(Config::get('carte.limite_ouest')),
70
			'est'   => floatval(Config::get('carte.limite_est')),
71
			'sud'   => floatval(Config::get('carte.limite_sud')),
72
			'nord'  => floatval(Config::get('carte.limite_nord'))
73
		);
74
		$this->validation = new StdClass();
75
	}
76
 
77
	public function verifierParametres() {
78
		foreach ($this->parametres as $nomParametre => $valeur) {
79
			switch ($nomParametre) {
80
				case 'zoom' : $this->traiterParametreZoom($valeur);
81
					break;
82
				case 'bbox' : $this->traiterParametreBbox($valeur);
83
					break;
84
				case 'longitude' :
85
				case 'latitude'  : $this->traiterParametresCoordonnees($this->parametres['longitude'],
86
					$this->parametres['latitude']);
87
					break;
88
				case 'dept' : $this->traiterParametreDepartement($valeur);
89
					break;
90
				case 'auteur' : $this->traiterParametreAuteur($valeur);
91
					break;
92
				case 'referentiel' : $this->traiterParametreReferentiel($valeur);
93
					break;
94
				case 'num_taxon' : $this->traiterParametreTaxon($valeur);
95
					break;
96
				// autres parametres ==> les ignorer
97
				default : break;
98
			}
99
		}
100
		$this->verifierPresenceParametreSpatial();
101
	}
102
 
103
	private function ajouterErreur($messageErreur) {
104
		$this->erreurs[] = $messageErreur;
105
	}
106
 
107
	public function renvoyerResultatVerification() {
108
		return $this->validation;
109
	}
110
 
111
	public function contienterreurs() {
112
		return count($this->erreurs);
113
	}
114
 
115
	public function leverException() {
116
		$messagesErreur = "Les erreurs suivantes ont été rencontrées : \n".
117
			implode("\n", $this->erreurs);
118
		throw new Exception($messagesErreur, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
119
	}
120
 
121
 
122
 
123
	// ------------------------------------------------------------------------- //
124
	// Fonctions de verification de parametres et detection de valeurs anormales //
125
	// ------------------------------------------------------------------------- //
126
 
127
	private function traiterParametreZoom($zoom) {
128
		$zoom = intval($zoom);
129
		$mondeZoom = array(
130
				'min' => intval(Config::get('carte.zoom_minimal')),
131
				'max' => intval(Config::get('carte.zoom_maximal'))
132
		);
133
		if ($zoom < $mondeZoom['min'] || $zoom > $mondeZoom['max']) {
134
			$message = 'Niveau de zoom non reconnu par le service. Il doit être compris entre '.
135
				$mondeZoom['min'].' et '.$mondeZoom['max'];
136
			$this->ajouterErreur($message);
137
		} else {
138
			$this->validation->zoom = $zoom;
139
		}
140
	}
141
 
142
	private function traiterParametreBbox($bbox) {
143
		// verifier que la chaine de caracteres $bbox est une serie de chaque nombre decimaux
144
		// separes entre eux par une virgule
145
		if (preg_match('/^(-?\d{1,3}(.\d+)?,){3}(-?\d{1,3}(.\d+)?)$/', $bbox) == 0) {
146
			$message = "Format de saisie des coordonnees de la bounding box non valide.  Le service ".
147
				"n'accepte seulement qu'une serie de 4 nombre décimaux séparés par des virgules.";
148
			$this->ajouterErreur($message);
149
		} else {
150
			$coordonnees = explode(',', $bbox);
151
			// index du tableau des coordonnees : ouest/sud/est/nord
152
			$nomsIndexBbox = array("ouest", "sud", "est", "nord");
153
			$bbox = array();
154
			for ($i = 0; $i < count($coordonnees); $i ++) {
155
				$bbox[$nomsIndexBbox[$i]] = $coordonnees[$i];
156
			}
157
			// verifier que les coordonnees de chaque bord de la bbox sont valides
158
			if ($this->estUneBboxValide($bbox)) {
159
				$this->validation->bbox = $bbox;
160
			} else {
161
				$message = "Certaines coordonnées de la bounding box sont situés en dehors des limites ".
162
					"de notre monde";
163
				$this->ajouterErreur($message);
164
			}
165
		}
166
	}
167
 
168
	private function estUneBboxValide($bbox) {
169
		$monde = $this->bboxMonde;
170
		return (floatval($bbox['ouest']) >= $monde['ouest']  && floatval($bbox['ouest']) <= $monde['est']
171
		&& floatval($bbox['est'])   >= $monde['ouest']  && floatval($bbox['est'])   <= $monde['est']
172
		&& floatval($bbox['nord'])  >= $monde['sud']    && floatval($bbox['nord'])  <= $monde['nord']
173
		&& floatval($bbox['sud'])   >= $monde['sud']    && floatval($bbox['sud'])   <= $monde['nord']);
174
	}
175
 
176
	private function traiterParametresCoordonnees($longitude, $latitude) {
177
		if ($this->sontDesCoordonneesValides($longitude, $latitude)) {
178
			$this->validation->latitude = $latitude;
179
			$this->validation->longitude = $longitude;
180
		} else {
181
			$message = "Les coordonnees du point passées en parametres sont en dehors des limites de ".
182
				"notre monde";
183
			$this->ajouterErreur($message);
184
		}
185
	}
186
 
187
	private function sontDesCoordonneesValides($longitude, $latitude) {
188
		$monde = $this->bboxMonde;
189
		return (floatval($longitude) >= $monde['ouest'] && floatval($longitude) <= $monde['est']
190
			&& floatval($latitude)  >= $monde['sud']   && floatval($latitude)  <= $monde['nord']);
191
	}
192
 
193
	private function traiterParametreDepartement($numeroDepartement) {
194
		if ($numeroDepartement != '*') {
195
			$departements = explode(',', trim($numeroDepartement));
196
			foreach ($departements as $departement) {
197
				if($this->estUnCodeDepartementValide($departement)) {
198
					$this->validation->departement[] = $departement;
199
				} else {
200
					$message = "Code de département non valide";
201
					$this->ajouterErreur($message);
202
				}
203
			}
204
		}
205
	}
206
 
207
	private function estUnCodeDepartementValide($departement) {
208
		// expression reguliere pour verifier que c'est un nombre entier a 2 ou 3 chiffres
209
		$estUnDepartementValide = true;
210
		if (preg_match('/^\d{2,3}$/', $departement) != 1) {
211
			$estUnDepartementValide = false;
212
		} else {
213
			if ((intval($departement) < 1 || intval($departement) > 95)
214
				&& (intval($departement) < 971 || intval($departement) > 978)) {
215
				$estUnDepartementValide = false;
216
			}
217
		}
218
		return $estUnDepartementValide;
219
	}
220
 
221
	private function traiterParametreAuteur($auteur) {
222
		if ($auteur != '*') {
223
			$this->validation->auteur = trim($auteur);
224
		}
225
	}
226
 
227
	private function traiterParametreReferentiel($referentiel)  {
228
		if (!isset($this->validation->referentiel) && $referentiel != '*') {
229
			$referentielAUtiliser = $this->affecterNomCompletReferentiel($referentiel);
230
			if (is_null($referentielAUtiliser)) {
231
				$message = "Le référentiel demandé n'est pas reconnu par le service.";
232
				$this->ajouterErreur($message);
233
			} else {
234
				$this->validation->referentiel = $referentielAUtiliser;
235
			}
236
		}
237
	}
238
 
239
	private function affecterNomCompletReferentiel($referentiel) {
240
		$referentielAUtiliser = null;
241
		$listeReferentiels = Referentiel::recupererListeReferentielsDisponibles();
242
		foreach ($listeReferentiels as $nomReferentiel) {
243
			$nomCourtReferentiel = current(explode('_', $nomReferentiel));
244
			if ($referentiel == $nomCourtReferentiel || $referentiel == $nomReferentiel) {
245
				$referentielAUtiliser = $nomReferentiel;
246
				break;
247
			}
248
		}
249
		return $referentielAUtiliser;
250
	}
251
 
252
	private function traiterParametreTaxon($numeroTaxon) {
253
		if ($numeroTaxon != '*') {
254
			$taxon = null;
255
			if (isset($this->validation->referentiel)) {
256
				$taxon = $this->renvoyerTaxonDansReferentiel($numeroTaxon, $this->validation->referentiel);
257
			} else {
258
				// parcours de tous les referentiels jusqu'a retrouver le taxon dans sa liste
259
				$taxon = $this->rechercherTaxonDansReferentiels($numeroTaxon);
260
			}
261
 
262
			if (is_null($taxon)) {
263
				$message = "Le numéro de taxon n'a pas permis de retrouver le taxon associé.";
264
				$this->ajouterErreur($message);
265
			} else {
266
				$this->validation->taxon = $taxon;
267
				$this->validation->referentiel = $taxon['referentiel'];
268
			}
269
		}
270
	}
271
 
272
	private function rechercherTaxonDansReferentiels($numeroTaxon) {
273
		$taxon = null;
274
		$listeReferentiels = Referentiel::recupererListeReferentielsDisponibles();
275
		foreach ($listeReferentiels as $nomReferentiel) {
276
			$taxon = $this->renvoyerTaxonDansReferentiel($numeroTaxon, $nomReferentiel);
277
			if (!is_null($taxon)) {
278
				break;
279
			}
280
		}
281
		return $taxon;
282
	}
283
 
284
	private function renvoyerTaxonDansReferentiel($numeroTaxon, $nomReferentiel) {
285
		$referentiel = new Referentiel($nomReferentiel);
286
		$referentiel->chargerTaxon($numeroTaxon);
287
		$taxon = $referentiel->renvoyerTaxon();
288
		return $taxon;
289
	}
290
 
291
	private function verifierPresenceParametreSpatial() {
292
		$presenceParametreSpatial = false;
293
		if (isset($this->parametres['bbox'])
294
			|| (isset($this->parametres['longitude']) && isset($this->parametres['latitude']))) {
295
			$presenceParametreSpatial = true;
296
		}
297
		if ($presenceParametreSpatial == false) {
298
			$message = "Aucune coordonnée n'a été saisie";
299
			$this->ajouterErreur($message);
300
		}
301
	}
302
 
303
}
304
 
305
?>