* @license GPL v3 * @license CECILL v2 * @version $Id$ * @copyright 2013 Tela Botanica (accueil@tela-botanica.org) * */ class MoissonnageCartes { const MIME_MAP = "text/html"; const MIME_PNG = "image/png"; const METHODE_TELECHARGEMENT = "telecharger"; const METHODE_AFFICHAGE = "afficher"; private $ressources; private $parametres; private $referentiel = ''; private $taxon = null; private $sources = array(); private $format = 0; private $retour = self::MIME_MAP; private $methode_livraison = self::METHODE_AFFICHAGE; private $erreurs = array(); public function consulter($ressources, $parametres) { $this->parametres = $parametres; $this->ressources = $ressources; $resultat = null; $this->chargerClassesSousDossier(); if ($this->analyserRessources() == true) { $resultat = $this->formerLegende(); } else { $this->traiterParametres(); $resultat = $this->formerCarte(); if($this->methode_livraison == self::METHODE_TELECHARGEMENT) { $this->telechargerCarte($resultat->corps); } } return $resultat; } private function analyserRessources() { $ok = false; if (isset($this->ressources[0]) && $this->ressources[0] == 'legende') { $ok = true; } return $ok; } private function formerLegende() { $legende = new LegendeCartes(); $resultat = $legende->obtenirLegende(); return $resultat; } private function chargerClassesSousDossier() { $this->verifierExistenceDossier("cartes"); $nomDossier = dirname(__FILE__).DS."cartes"; $dossier = opendir($nomDossier); $fichiersAInclure = array(); while ($fichier = readdir($dossier)) { if (filetype($nomDossier.DS.$fichier) == 'file') { $fichiersAInclure[] = $nomDossier.DS.$fichier; } } $fichiersAInclure = array_reverse($fichiersAInclure); foreach ($fichiersAInclure as $fichier) { include_once($fichier); } } private function verifierExistenceDossier($nomDossier) { $dossier = dirname(__FILE__).DS.$nomDossier; if (!file_exists($dossier) || !is_dir($dossier)) { $message = "Problème rencontré lors de la génération de la carte : des ressources ". "nécessaires au fonctionnement du service n'ont pas été localisées sur le serveur.\n"; throw new Exception($message); } } private function verifierExistenceFichier($nomFichier) { if (!file_exists($nomFichier)) { $message = "Problème rencontré lors de la génération de la carte : des ressources ". "nécessaires au fonctionnement du service n'ont pas été localisées sur le serveur.\n"; throw new Exception($message); } } private function traiterParametres() { $this->verifierReferentielEtTaxon(); $this->verifierParametreSource(); $this->verifierParametreFormat(); $this->verifierParametreRetour(); $this->verifierParametreMethodeLivraison(); if (count($this->erreurs) > 0) { $this->renvoyerErreurs(); } } private function verifierParametreFormat() { if (!isset($this->parametres['format'])) { $this->erreurs[] = "Le paramètre format (dimensions) de l'image n'a pas été indiqué dans l'URL du service."; } elseif (preg_match('/^[1-9]\d{2}$/', $this->parametres['format']) != 1) { $this->erreurs[] = "La valeur du paramètre format n'est pas acceptée par le service. ". "Une largeur valide doit être un nombre entier compris entre 100 et 999."; } else { $this->format = $this->parametres['format']; } } private function verifierParametreRetour() { $typesMime = array(self::MIME_MAP, self::MIME_PNG); if (!isset($this->parametres['retour'])) { $this->erreurs[] = "Le paramètre type de retour de l'image n'a pas été indiqué dans l'URL du service."; } elseif (!in_array($this->parametres['retour'], $typesMime)) { $this->erreurs[] = "Le format de retour ".$this->parametres['retour']." n'est pas acceptée par le service. ". " Seuls les types MIME suivants sont gérés : ".implode(',', $typesMime); } else { $this->retour = $this->parametres['retour']; } } private function verifierParametreMethodeLivraison() { $typesMethodeLivraison = array(self::METHODE_AFFICHAGE, self::METHODE_TELECHARGEMENT); if (isset($this->parametres['methode']) && !in_array($this->parametres['methode'], $typesMethodeLivraison)) { $this->erreurs[] = "Le format de methode de livraison ".$this->parametres['methode']." n'est pas acceptée par le service. ". " Seuls les methodes suivantes sont gérés : ".implode(',', $typesMethodeLivraison); } elseif(isset($this->parametres['methode']) && in_array($this->parametres['methode'], $typesMethodeLivraison)) { $this->methode_livraison = $this->parametres['methode']; } } private function verifierParametreSource() { $sourcesDisponibles = explode(',', trim(Config::get('sourcesDonnees'))); if (isset($this->parametres['source'])) { $sourcesParametre = explode(',', trim($this->parametres['source'])); foreach ($sourcesParametre as $source) { if (!in_array($source, $sourcesDisponibles)) { $this->erreurs[] = "La source de données $source n'est pas disponible pour ce service. ". "Les sources suivantes sont utilisables : ".implode(',', $sourcesDisponibles)."."; } else { $this->sources[] = $source; } } } else { $this->sources = $sourcesDisponibles; } } private function verifierReferentielEtTaxon() { if (!$this->estReferentielDisponible()) { $this->erreurs[] = "Le référentiel ".$this->parametres['referentiel']." n'a pas été trouvé. ". "La liste des référentiels disponibles pour ce service sont : ".Config::get('referentielsDispo'); } else { $this->referentiel = $this->parametres['referentiel']; $taxon = $this->recupererInformationsTaxon(); if (is_null($taxon)) { $this->erreurs[] = "Le taxon d'espèce que vous avez demandé n'a pas été trouvé dans le référentiel."; } else { $this->taxon = $taxon; } } } private function renvoyerErreurs() { $message = "Les erreurs suivantes ont été rencontrées : \n".implode('\n', $this->erreurs); throw new Exception($message, RestServeur::HTTP_CODE_MAUVAISE_REQUETE); } private function estReferentielDisponible() { $referentielsDispo = explode(',', Config::get('referentielsDispo')); $estDisponible = (isset($this->parametres['referentiel']) && in_array($this->parametres['referentiel'], $referentielsDispo)); return $estDisponible; } private function recupererInformationsTaxon() { $taxon = null; if (isset($this->parametres['num_taxon'])) { $numTaxon = $this->parametres['num_taxon']; $nomTable = $this->recupererNomTableReferentiel(); $bdd = new Bdd(); $requete = "SELECT num_nom, num_nom_retenu, nom_sci, nom_complet, rang, num_taxonomique FROM {$nomTable} ". "WHERE num_taxonomique={$numTaxon} ORDER BY If(num_nom=num_nom_retenu,0,1) LIMIT 0,1"; $taxon = $bdd->recuperer($requete); if ($taxon === false) { $taxon = null; } } return $taxon; } private function recupererNomTableReferentiel() { $tablesReferentiel = explode(',', Config::get('bdd_table_referentiel')); $nomTable = ''; foreach ($tablesReferentiel as $table) { if (strstr($table, $this->referentiel) !== false) { $nomTable = $table; } } return $nomTable; } private function formerCarte() { $suffixe = 'france_moissonnage'; // le fichier png avec les départements est illisible en petit format // dans ce cas là un template plus simple est utilisé (sans les départements) if($this->format < 300 && $this->retour == self::MIME_PNG) { $suffixe = $suffixe."_sans_departements"; } $nomFichierSVG = Config::get('chemin')."{$suffixe}.svg"; $this->verifierExistenceFichier($nomFichierSVG); $formateur = new FormateurSVG($nomFichierSVG, $this->sources, $this->retour, $this->format); $formateur->formaterCarte($this->taxon); $resultat = new ResultatService(); $resultat->corps = $formateur->renvoyerCarte(); $resultat->mime = $this->retour; return $resultat; } private function telechargerCarte($fichier) { if (function_exists('mb_strlen')) { $taille = mb_strlen($fichier, '8bit'); } else { $taille = strlen($fichier); } $extension = ($this->retour == "text/html") ? 'html' : 'png'; header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="carte.'.$extension.'"'); header('Content-Transfer-Encoding: binary'); header('Connection: Keep-Alive'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: '.$taille); } } ?>