New file |
0,0 → 1,305 |
<?php |
|
|
/** |
* Classe commune a tous les services de ce projet qui va analyser et rechercher des erreurs |
* sur les valeurs passees en parametres lors d'un appel a ces web services. |
* |
* Les parametres suivants sont traites : |
* - zoom : le niveau de zoom sur la carte (API cartographique client) |
* On va verifier que c'est un nombre entier compris entre une valeur minimale et une valeur maximale |
* |
* - bbox : rectangle dont les bords delimitent en coordonnees l'espace de recherche de donnees spatiales |
* L'ordre des valeurs est le suivant : ouest, sud, est, nord |
* On va verifier que c'est une serie de quatre nombre decimaux delimites par des virgules |
* et compris dans l'espace representant le monde a partir du systeme de projection WGS84 (EPSG:4326) |
* |
* - longitude et latitude : representent les coordonnees d'un point dans l'espace |
* On va verifier que ces coordonnees soient valides dans le systeme de projection utilise |
* |
* - referentiel : referentiel taxonomique a utiliser. On peut passer aussi bien en parametres |
* son nom court que son nom complet (incluant le numero de version) |
* On va verifier la disponibilite du referentiel pour ce service |
* |
* - num_taxon : numero taxonomique d'une espece |
* On va rechercher sa presence dans les referentiels disponibles |
* (les informations principales sur ce taxon seront renvoyees) |
* |
* - dept : une liste de numeros de departements separees entre eux par des virgules |
* On va verifier que chaque numero est un nombre entier et represente un code de departement valide |
* |
* - auteur : l'auteur de l'observation |
* |
* La fonction principale de verification des parametres va parcourir tous les parametres, et verifier |
* pour chacun d'eux la validite de leurs valeurs. Dans le cas ou une valeur anormale est detectee |
* ou qu'elle se trouve en dehors de l'intervalle des resultats acceptes, une liste de messages d'erreur |
* sera generee et mise a jour. |
* |
* Le resultat final de la verfication peut entrainer deux cas d'utilisation possibles. Si des messages |
* d'erreurs ont ete generes durant la verification, ils sont regroupes en un seul message pour lever |
* une exception qui sera interpretee par la classe appelante. Dans le cas ou la verification n'a rien |
* rencontre d'anormal, une fonction renverra la liste des parametres valides utilisables |
* pour des recherches de donnees pour la suite du traitement pour le service. |
* |
* @package framework-0.3 |
* @author Alexandre GALIBERT <alexandre.galibert@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright 2013 Tela Botanica (accueil@tela-botanica.org) |
* |
*/ |
|
class VerificateurParametres { |
|
private $parametres = array(); |
private $validation = null; |
private $erreurs = array(); |
|
private $bboxMonde = null; |
|
|
public function __construct($parametres) { |
foreach ($parametres as $nomParametre => $valeur) { |
if ($nomParametre != 'source') { |
$this->parametres[$nomParametre] = $valeur; |
} |
} |
$this->bboxMonde = array( |
'ouest' => floatval(Config::get('carte.limite_ouest')), |
'est' => floatval(Config::get('carte.limite_est')), |
'sud' => floatval(Config::get('carte.limite_sud')), |
'nord' => floatval(Config::get('carte.limite_nord')) |
); |
$this->validation = new StdClass(); |
} |
|
public function verifierParametres() { |
foreach ($this->parametres as $nomParametre => $valeur) { |
switch ($nomParametre) { |
case 'zoom' : $this->traiterParametreZoom($valeur); |
break; |
case 'bbox' : $this->traiterParametreBbox($valeur); |
break; |
case 'longitude' : |
case 'latitude' : $this->traiterParametresCoordonnees($this->parametres['longitude'], |
$this->parametres['latitude']); |
break; |
case 'dept' : $this->traiterParametreDepartement($valeur); |
break; |
case 'auteur' : $this->traiterParametreAuteur($valeur); |
break; |
case 'referentiel' : $this->traiterParametreReferentiel($valeur); |
break; |
case 'num_taxon' : $this->traiterParametreTaxon($valeur); |
break; |
// autres parametres ==> les ignorer |
default : break; |
} |
} |
$this->verifierPresenceParametreSpatial(); |
} |
|
private function ajouterErreur($messageErreur) { |
$this->erreurs[] = $messageErreur; |
} |
|
public function renvoyerResultatVerification() { |
return $this->validation; |
} |
|
public function contienterreurs() { |
return count($this->erreurs); |
} |
|
public function leverException() { |
$messagesErreur = "Les erreurs suivantes ont été rencontrées : \n". |
implode("\n", $this->erreurs); |
throw new Exception($messagesErreur, RestServeur::HTTP_CODE_MAUVAISE_REQUETE); |
} |
|
|
|
// ------------------------------------------------------------------------- // |
// Fonctions de verification de parametres et detection de valeurs anormales // |
// ------------------------------------------------------------------------- // |
|
private function traiterParametreZoom($zoom) { |
$zoom = intval($zoom); |
$mondeZoom = array( |
'min' => intval(Config::get('carte.zoom_minimal')), |
'max' => intval(Config::get('carte.zoom_maximal')) |
); |
if ($zoom < $mondeZoom['min'] || $zoom > $mondeZoom['max']) { |
$message = 'Niveau de zoom non reconnu par le service. Il doit être compris entre '. |
$mondeZoom['min'].' et '.$mondeZoom['max']; |
$this->ajouterErreur($message); |
} else { |
$this->validation->zoom = $zoom; |
} |
} |
|
private function traiterParametreBbox($bbox) { |
// verifier que la chaine de caracteres $bbox est une serie de chaque nombre decimaux |
// separes entre eux par une virgule |
if (preg_match('/^(-?\d{1,3}(.\d+)?,){3}(-?\d{1,3}(.\d+)?)$/', $bbox) == 0) { |
$message = "Format de saisie des coordonnees de la bounding box non valide. Le service ". |
"n'accepte seulement qu'une serie de 4 nombre décimaux séparés par des virgules."; |
$this->ajouterErreur($message); |
} else { |
$coordonnees = explode(',', $bbox); |
// index du tableau des coordonnees : ouest/sud/est/nord |
$nomsIndexBbox = array("ouest", "sud", "est", "nord"); |
$bbox = array(); |
for ($i = 0; $i < count($coordonnees); $i ++) { |
$bbox[$nomsIndexBbox[$i]] = $coordonnees[$i]; |
} |
// verifier que les coordonnees de chaque bord de la bbox sont valides |
if ($this->estUneBboxValide($bbox)) { |
$this->validation->bbox = $bbox; |
} else { |
$message = "Certaines coordonnées de la bounding box sont situés en dehors des limites ". |
"de notre monde"; |
$this->ajouterErreur($message); |
} |
} |
} |
|
private function estUneBboxValide($bbox) { |
$monde = $this->bboxMonde; |
return (floatval($bbox['ouest']) >= $monde['ouest'] && floatval($bbox['ouest']) <= $monde['est'] |
&& floatval($bbox['est']) >= $monde['ouest'] && floatval($bbox['est']) <= $monde['est'] |
&& floatval($bbox['nord']) >= $monde['sud'] && floatval($bbox['nord']) <= $monde['nord'] |
&& floatval($bbox['sud']) >= $monde['sud'] && floatval($bbox['sud']) <= $monde['nord']); |
} |
|
private function traiterParametresCoordonnees($longitude, $latitude) { |
if ($this->sontDesCoordonneesValides($longitude, $latitude)) { |
$this->validation->latitude = $latitude; |
$this->validation->longitude = $longitude; |
} else { |
$message = "Les coordonnees du point passées en parametres sont en dehors des limites de ". |
"notre monde"; |
$this->ajouterErreur($message); |
} |
} |
|
private function sontDesCoordonneesValides($longitude, $latitude) { |
$monde = $this->bboxMonde; |
return (floatval($longitude) >= $monde['ouest'] && floatval($longitude) <= $monde['est'] |
&& floatval($latitude) >= $monde['sud'] && floatval($latitude) <= $monde['nord']); |
} |
|
private function traiterParametreDepartement($numeroDepartement) { |
if ($numeroDepartement != '*') { |
$departements = explode(',', trim($numeroDepartement)); |
foreach ($departements as $departement) { |
if($this->estUnCodeDepartementValide($departement)) { |
$this->validation->departement[] = $departement; |
} else { |
$message = "Code de département non valide"; |
$this->ajouterErreur($message); |
} |
} |
} |
} |
|
private function estUnCodeDepartementValide($departement) { |
// expression reguliere pour verifier que c'est un nombre entier a 2 ou 3 chiffres |
$estUnDepartementValide = true; |
if (preg_match('/^\d{2,3}$/', $departement) != 1) { |
$estUnDepartementValide = false; |
} else { |
if ((intval($departement) < 1 || intval($departement) > 95) |
&& (intval($departement) < 971 || intval($departement) > 978)) { |
$estUnDepartementValide = false; |
} |
} |
return $estUnDepartementValide; |
} |
|
private function traiterParametreAuteur($auteur) { |
if ($auteur != '*') { |
$this->validation->auteur = trim($auteur); |
} |
} |
|
private function traiterParametreReferentiel($referentiel) { |
if (!isset($this->validation->referentiel) && $referentiel != '*') { |
$referentielAUtiliser = $this->affecterNomCompletReferentiel($referentiel); |
if (is_null($referentielAUtiliser)) { |
$message = "Le référentiel demandé n'est pas reconnu par le service."; |
$this->ajouterErreur($message); |
} else { |
$this->validation->referentiel = $referentielAUtiliser; |
} |
} |
} |
|
private function affecterNomCompletReferentiel($referentiel) { |
$referentielAUtiliser = null; |
$listeReferentiels = Referentiel::recupererListeReferentielsDisponibles(); |
foreach ($listeReferentiels as $nomReferentiel) { |
$nomCourtReferentiel = current(explode('_', $nomReferentiel)); |
if ($referentiel == $nomCourtReferentiel || $referentiel == $nomReferentiel) { |
$referentielAUtiliser = $nomReferentiel; |
break; |
} |
} |
return $referentielAUtiliser; |
} |
|
private function traiterParametreTaxon($numeroTaxon) { |
if ($numeroTaxon != '*') { |
$taxon = null; |
if (isset($this->validation->referentiel)) { |
$taxon = $this->renvoyerTaxonDansReferentiel($numeroTaxon, $this->validation->referentiel); |
} else { |
// parcours de tous les referentiels jusqu'a retrouver le taxon dans sa liste |
$taxon = $this->rechercherTaxonDansReferentiels($numeroTaxon); |
} |
|
if (is_null($taxon)) { |
$message = "Le numéro de taxon n'a pas permis de retrouver le taxon associé."; |
$this->ajouterErreur($message); |
} else { |
$this->validation->taxon = $taxon; |
$this->validation->referentiel = $taxon['referentiel']; |
} |
} |
} |
|
private function rechercherTaxonDansReferentiels($numeroTaxon) { |
$taxon = null; |
$listeReferentiels = Referentiel::recupererListeReferentielsDisponibles(); |
foreach ($listeReferentiels as $nomReferentiel) { |
$taxon = $this->renvoyerTaxonDansReferentiel($numeroTaxon, $nomReferentiel); |
if (!is_null($taxon)) { |
break; |
} |
} |
return $taxon; |
} |
|
private function renvoyerTaxonDansReferentiel($numeroTaxon, $nomReferentiel) { |
$referentiel = new Referentiel($nomReferentiel); |
$referentiel->chargerTaxon($numeroTaxon); |
$taxon = $referentiel->renvoyerTaxon(); |
return $taxon; |
} |
|
private function verifierPresenceParametreSpatial() { |
$presenceParametreSpatial = false; |
if (isset($this->parametres['bbox']) |
|| (isset($this->parametres['longitude']) && isset($this->parametres['latitude']))) { |
$presenceParametreSpatial = true; |
} |
if ($presenceParametreSpatial == false) { |
$message = "Aucune coordonnée n'a été saisie"; |
$this->ajouterErreur($message); |
} |
} |
|
} |
|
?> |