renvoie un graphique avec les données connues * * * @package eflore-projets * @author Jean-Pascal MILCENT * @author Mathilde SALTHUN-LASSALLE * @license GPL v3 * @license CECILL v2 * @version 1.0 * @copyright 1999-2011 Tela Botanica (accueil@tela-botanica.org) */ abstract class CommunGraphiques extends Commun{ protected $parametres = array(); protected $ressources = array(); protected $Bdd; protected $config; protected $cache; protected $metadonnees; protected $version; protected $serviceNom = 'Graphiques'; protected $graduations_id = array(); protected $champs_ontologiques = array(); protected $nomGraphique = array(); protected $table = ''; protected $requete_condition = ""; protected $requete_champs; protected $convertisseur; protected $cheminGraphBase; protected $valeurs_en_pourcentage = array(); protected $dom; protected $largeurSVG = "500"; protected $hauteurSVG; protected $valeurs_champs; public function consulter($ressources, $parametres) { $this->ressources = $ressources; $this->parametres = $parametres; $this->verifierParametres(); $this->initialiserConfiguration(); $resultats = ''; $this->traiterRessources(); $requete = $this->assemblerLaRequete(); $resultat = $this->resultat = $this->Bdd->recupererTous($requete); $versionResultat = $this->obtenirResultat($resultat); return $versionResultat; } //+--------------------------initialisation de paramètres -------------------------------------------+ private function initialiserConfiguration() { $conteneur = new Conteneur(); $this->Bdd = $conteneur->getBdd(); $this->config = $conteneur->getParametre('Graphiques'); $this->convertisseur = $this->config['convertisseur']; $this->graduations_id = $this->getParametreTableau('graduations_id'); $this->champs_ontologiques = $this->getParametreTableau('champs_ontologiques'); $this->cheminGraphBase = $this->config['chemin']; $cacheOptions = array('mise_en_cache' => $this->config['cache_miseEnCache'], 'stockage_chemin' => $this->config['cache_stockageChemin'], 'duree_de_vie' => $this->config['cache_dureeDeVie']); $this->cache = $conteneur->getCacheSimple($cacheOptions); $this->definirVersion(); $this->definirFormat(); $this->definirTable($this->version); } abstract function definirTable($version); private function getParametreTableau($cle) { $tableau = array(); $parametre = Config::get($cle); if (empty($parametre) === false) { $tableauPartiel = explode(',', $parametre); $tableauPartiel = array_map('trim', $tableauPartiel); foreach ($tableauPartiel as $champ) { if (strpos($champ, '=') !== false && strlen($champ) >= 3) { list($cle, $val) = explode('=', $champ); $tableau[trim($cle)] = trim($val); } else { $tableau[] = trim($champ); } } } return $tableau; } //+--------------------------traitement ressources ou paramètres -------------------------------------------+ //+---- paramètres ----+ private function verifierParametres() { if (isset($this->parametres)) { $parametres_dispo = array('retour', 'retour.format', 'version.projet'); $parametres = array_keys($this->parametres); foreach ($parametres as $param) { if (!in_array($param, $parametres_dispo)) { $erreur = "Erreur : Le paramètre $param est inconnu."; $code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE; throw new Exception($erreur, $code); } } } } //on n'affiche qu'une version de graphique à la fois ( la dernière ou celle demandée ) private function definirVersion() { $this->chargerVersions(); if (!isset($this->parametres['version.projet']) ) { $this->version = $this->metadonnees[0]['version']; } elseif ($this->parametres['version.projet'] == '+') { $this->version = $this->metadonnees[0]['version']; } else { if($this->verifierVersion($this->parametres['version.projet'])) { $this->version = $this->parametres['version.projet']; }else { $erreur = "Erreur : La version est inconnue."; $code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE; throw new Exception($erreur, $code); } } } private function verifierVersion($version){ $retour = false; foreach ($this->metadonnees as $vers) { if ($vers['version'] == $version ) { $retour = true; } } return $retour; } private function definirFormat() { if (isset($this->parametres['retour.format']) ){ if (preg_match("/^[0-9]+$/", $this->parametres['retour.format'])){ if ($this->parametres['retour.format'] > 0) { $this->largeurSVG = $this->parametres['retour.format']; } else { $erreur = "Erreur : valeur pour retour.format négative ou égale à 0."; $code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE; throw new Exception($erreur, $code); } }else { $erreur = "Erreur : valeur inconnue. Entrez la largeur voulue (en pixels) pour le paramètre retour.format."; $code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE; throw new Exception($erreur, $code); } } if (!isset($this->parametres['retour']) ){ $this->parametres['retour'] = 'image/svg+xml'; }else { if (( $this->parametres['retour'] != 'image/svg+xml')&& ( $this->parametres['retour'] != 'image/png')){ $erreur = "Erreur : valeur inconnue. Choisissez le format de retour pour le paramètre retour : image/svg%2Bxml ou image/png."; $code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE; throw new Exception($erreur, $code); } } } private function chargerVersions() { $requete = "SELECT version ". "FROM ".Config::get('bdd_table_meta')." ". "ORDER BY date_creation DESC "; $resultats = $this->Bdd->recupererTous($requete); if (!is_array($resultats) || count($resultats) <= 0) { $message = "Les méta-données n'ont pu être chargée pour la ressource demandée"; $code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE; throw new Exception($message, $code); } $this->metadonnees = $resultats; } //+----- ressources -----+ public function traiterRessources() { if(isset($this->ressources)) { $this->traiterTypeGraphique(); $this->traiterReferentielEtNum(); } else { $e = 'Erreur dans l\'url de votre requête :
ressources insuffisantes.'; throw new Exception( $e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE); } } abstract function traiterReferentielEtNum(); abstract function traiterTypeGraphique(); //+--------------------------FONCTIONS D'ASSEMBLAGE DE LA REQUETE-------------------------------------------+ public function assemblerLaRequete() { $requete = ' SELECT '.$this->requete_champs.' FROM '.$this->table.' '.$this->retournerRequeteCondition(); return $requete; } public function retournerRequeteCondition() { $condition = ''; if ($this->requete_condition !== "") { $condition = ' WHERE '.implode(' AND ', $this->requete_condition); } return $condition; } //+-------------------------- formatage du résultat -------------------------------------------+ public function obtenirResultat($resultat) { if ($resultat == ""){ $message = 'La requête SQL formée comporte une erreur!'; $code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE; throw new Exception($message, $code); }elseif ($resultat) { if ((count($this->ressources)) != 0) { //$Atraiter = array_filter($resultat[0],function($var){return ($var != '');}); foreach ($resultat[0] as $champs => $valeur) { if ($valeur !== '') { $Atraiter[$champs] = $valeur; } } if (!empty($Atraiter)) { $this->traiterValeursEcologiques($Atraiter); $svg = $this->genererSVG(); $resultat = new ResultatService(); $resultat->corps = ($this->parametres['retour'] == 'image/png') ? $this->convertirEnPNG($svg) : $svg; $resultat->mime = $this->parametres['retour']; } else { $resultat = null; } } } else { $resultat = null; } return $resultat; } //+----- modification svg -----+ public function traiterValeursEcologiques($valeur){ $this->valeurs_champs = $valeur; foreach($this->valeurs_champs as $cle => $val){ if (preg_match("/ve_humidite_edaph/", $cle)) { $this->valeurs_en_pourcentage[$cle] = round($val/13,1); } elseif (preg_match("/ve_salinite/", $cle)) { $this->valeurs_en_pourcentage[$cle] = round(($val+1)/11,1); } else { $this->valeurs_en_pourcentage[$cle] = round($val/10,1); } } } public function donnerHauteur($ancienne_largeur, $ancienne_hauteur) { $nouvelle_largeur = $this->largeurSVG; $ancienne_largeur = str_replace('px','',$ancienne_largeur); $ancienne_hauteur = str_replace('px','',$ancienne_hauteur); $rapport = $nouvelle_largeur / $ancienne_largeur ; $nouvelle_hauteur = $ancienne_hauteur * $rapport; $this->hauteurSVG = $nouvelle_hauteur; } public function ajusterFormatSVG(){ $svg = $this->dom->getElementsByTagName("svg")->item(0); $largeur = $svg->getAttribute('width'); $hauteur = $svg->getAttribute('height'); $this->donnerHauteur($largeur , $hauteur); $svg->setAttribute('width',round($this->largeurSVG).'px'); $svg->setAttribute('height',round($this->hauteurSVG).'px'); } public function genererSVG(){ $svg = null; $this->dom = new DOMDocument('1.0', 'UTF-8'); $this->dom->validateOnParse = true; $fichierSvg = $this->cheminGraphBase."".$this->nomGraphique.".svg"; $this->dom->load($fichierSvg); $this->changerValeursSVG(); $svg = $this->dom->saveXML(); return $svg; } abstract function changerValeursSVG(); public function recupererOntologies($valeur, $champs){ $url = $this->ajouterHref('ontologies',$this->champs_ontologiques[$champs].':'.urlencode(urlencode($valeur))); try { $val = $this->getBdd()->recuperer(sprintf( "SELECT a.nom FROM baseflor_ontologies a LEFT JOIN baseflor_ontologies b ON a.id = b.id LEFT JOIN baseflor_ontologies c ON b.classe_id = c.id WHERE". " b.code = BINARY '%s' AND c.code = BINARY '%s' LIMIT 0, 100", $valeur, $this->champs_ontologiques[$champs]), Bdd::MODE_OBJET); } catch (Exception $e) { $val = ""; } return $val; } public function traiterIntermediaires($valeurTexte,$champsOntologie, $champsTable){ if (preg_match("/(?:I|i)nterm(?:é|e)diaire(?:s)*/", $valeurTexte )) { $prec = $this->recupererOntologies(($this->valeurs_champs[$champsTable]-1), $champsOntologie ); $suiv = $this->recupererOntologies(($this->valeurs_champs[$champsTable]+1), $champsOntologie ); $valeurTexte = "Intermédiaires entre $prec->nom et $suiv->nom "; } return $valeurTexte; } /// +---- convertir png ----+ public function convertirEnPNG($svg) { $png = null; if (isset($this->convertisseur)) { if ($this->convertisseur == 'imagick') { if (extension_loaded('imagick')) { $png = $this->convertirEnPNGAvecImageMagick($svg); } else { $message = "Impossible de générer l'image sur le serveur. Extension ImageMagick absente."; $code = RestServeur::HTTP_CODE_ERREUR; throw new Exception($message, $code); } } else if ($this->convertisseur == 'rsvg') { $png = $this->convertirGraphiqueEnPNGAvecRsvg($svg); } else { $message = "Le convertisseur indiqué '{$this->convertisseur}' ne fait pas partie de la liste ". "des convertisseurs disponibles : imagick, rsvg."; $code = RestServeur::HTTP_CODE_ERREUR; throw new Exception($message, $code); } } else { $message = "Veuillez indiquer le convertisseur de svg à utiliser pour le service."; $code = RestServeur::HTTP_CODE_ERREUR; throw new Exception($message, $code); } return $png; } public function convertirEnPNGAvecImageMagick($svg) { $convertisseur = new Imagick(); $convertisseur->setBackgroundColor(new ImagickPixel('#F8F8F8')); $convertisseur->readImageBlob($svg); $convertisseur->setImageFormat('png32'); $convertisseur->resizeImage($this->largeurSVG,$this->hauteurSVG, imagick::FILTER_LANCZOS, 0, true); $png = $convertisseur->getImageBlob(); $convertisseur->clear(); $convertisseur->destroy(); return $png; } public function convertirGraphiqueEnPNGAvecRsvg($svg) { $idFichier = $this->getIdFichier(); $fichierPng = $this->config['cache_stockageChemin'].$idFichier.'.png'; $fichierSvg = $this->config['cache_stockageChemin'].$idFichier.'.svg'; file_put_contents($fichierSvg, $svg); $commande = "rsvg-convert $fichierSvg -w ".$this->largeurSVG ." -h ".$this->hauteurSVG ." -o $fichierPng"; //echo $commande; exit; $rsvg = exec($commande); $this->indexerGraphiqueFichierPng($fichierPng); $png = file_get_contents($fichierPng); return $png; } public function indexerGraphiqueFichierPng($fichierPng) { $img = imagecreatefrompng($fichierPng); imagetruecolortopalette($img, false, 32); imagepng($img, $fichierPng, 9, PNG_ALL_FILTERS); } public function getIdFichier(){ $idfichier = str_replace(".","-",$this->ressources[1]); $idfichier = str_replace(':','-',$idfichier); $idfichier .= "-".$this->ressources[0]; return $idfichier; } } ?>