Rev 239 | Rev 837 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*** Description :* Classe MetaDonnees.php fournit des informations sur le projet.* Le but étant de fournir un ensemble minimal d'information comprenant :* la version, la langue, le nom, le créateur et l'éditeur du projet.* Si l'url finit par /meta-donnees on retourne une liste de termes (seulement les 100 premières par défaut).* L'url peut contenir des paramètres optionnels passés après le ? : /meta-donnees?param1=val1¶m2=val2&...** Les paramètres de requête disponibles sont : masque, , recherche,* distinct, retour.format, navigation.depart et navigation.limite.** Encodage en entrée : utf8* Encodage en sortie : utf8* @package framework-v3* @author Jennifer Dhé <jennifer.dhe@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 1.0* @copyright 1999-${year} Tela Botanica (accueil@tela-botanica.org)*/class MetaDonnees extends Commun {protected $requete_champ = '*';protected $requete_condition = null;protected $retour_format = 'max';protected $table_retour = array();protected $format_reponse = 'metaDonnees';protected $table_ressources;public function consulter($ressources, $parametres) {$this->ressources = $ressources;$this->parametres = $parametres;$this->serviceNom = 'meta-donnees';$resultats = '';// on traite en premier la version dans le cas ou un langage est demandé pr une version$this->traiterVersionProjet();$this->traiterParametres($parametres);$this->traiterRessources($ressources);if ($this->corps_http == '' && $this->entete_http == '') {$requete_meta = $this->assemblerLaRequete();$resultat_meta = $this->getBdd()->recupererTous($requete_meta);$resultats = $this->formerResultat($resultat_meta, $requete_meta);}return $resultats;}public function formerResultat($resultat_meta, $requete_meta) {if ($resultat_meta == '') {$e = 'La requête formée comporte une erreur!';$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE,$e);Debug::printr($requete);} elseif ($resultat_meta) {$resultat_formate = $this->retournerResultatFormate($resultat_meta);} else {$m = "Données introuvables dans la base $this->table";$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $m);Debug::printr($requete_meta);}return $resultat_formate;}//--------------------FONCTIONS TRAITEMENT DES PARAMETRES---------------------------------------------------------------public function traiterParametres($parametres) {if (isset($parametres) && !empty($parametres)) {foreach ($parametres as $param => $val) {switch ($param) {case 'version.projet' : $this->ajouterFiltreVersion($val); break;case 'retour.langue' : $this->rechercherLangueDispo($val); break;case 'retour.format' : $this->retour_format = $val; break;default :$e = 'Erreur dans les paramètres de recherche de votre requête : </br> Le paramètre " '.$param.' " n\'existe pas.';$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);break;}}}}/** Détermine quelles métadonnées doivent etre retournées :* - "*" : (/#projet/* /meta-donnees) Renvoi les meta-données de toutes les versions du projet* - "numero de la version" : (/#projet/2.00/meta-donnees) Renvoi les meta-données de la version 2.00 du projet* - non renseignée : (/#projet/meta-donnees) Renvoi les meta-données de la dernière version du projet* Cette info est stockée dans par la classe RestServeur dans la variable $ressources ($ressources[0])*/public function ajouterFiltreVersion($val) {if (preg_match('/(?:[0-9]+(?:_|[.])[0-9]+|[*]| )/', $val)) {$this->version_projet = ($val == ' ') ? '+' : $val;}switch ($this->version_projet) {case '+' :$this->requete_condition[] = 'version = (SELECT MAX(version) FROM '.Config::get('bdd_table_meta').')';break;case '*' :break;default :if (is_numeric($this->version_projet)) {$versions_dispo = $this->rechercherVersionsDispos();if (in_array($val, $versions_dispo)) {$this->requete_condition[] = 'version = '.$this->getBdd()->proteger($val);} else {$e = 'La version demandée n\'existe pas actuellement. </br>Les versions disponibles sont : '.implode(', ', $versions_dispo);$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);}}break;}}/*** Vérifie que le numéro de la version passée en paramètre correspond à une version existante.* Si oui remplit la condition de la requete SQL*/public function rechercherVersionsDispos() {$val = str_replace('_', '.', $this->version_projet);$req_version = 'SELECT version FROM '.Config::get('bdd_table_meta');$res_version = $this->getBdd()->recupererTous($req_version);foreach ($res_version as $version) {$versions_dispo[] = $version['version'];}return $versions_dispo;}/** Vérifie que les meta-donnees existe dans la langue passée en paramètre, Si oui remplit la condition de la requete SQL */public function rechercherLangueDispo($val) {//on recherche les langues_meta disponibles pour la version demandée : (d'ou ajout de la condition)$req_langue = 'SELECT langue_meta FROM '.Config::get('bdd_table_meta').$this->formerRequeteCondition();$res_langue = $this->getBdd()->recupererTous($req_langue);foreach ($res_langue as $langue) {$langue_dispo[] = $langue['langue_meta'];}if (in_array($val, $langue_dispo)) {$this->requete_condition[] = 'langue_meta = '.$this->getBdd()->proteger($val);} else {$e = 'La langue demandée n\'existe pas actuellement. </br>Les langues disponibles sont : '.implode($langue_dispo);$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);}}//----------------------FONCTIONS TRAITEMENT DES RESSOURCES-------------------------------------------------------------public function traiterRessources($ressources) {// /meta-donnees (liste des meta-données. Toutes les info de la table sont affichées) ou /meta-donnees/#champif (isset($ressources) && !empty($ressources)) {$this->table_ressources = $ressources;if (isset($ressources) && !empty($ressources)) {$this->format_reponse = 'metaDonnees/champ';}}}//------------------------------Fonction d'assemblage de la requete------------------------------------------------------public function assemblerLaRequete() {$req = 'SELECT '.$this->requete_champ.' FROM '.Config::get('bdd_table_meta').$this->formerRequeteCondition();return $req;}public function formerRequeteCondition() {$condition = '';if ($this->requete_condition != null) {$condition = ' WHERE '.implode(' AND ', $this->requete_condition);}return $condition;}//--------------------------------------Fonction de formatage des resultats ---------------------------------------------public function retournerResultatFormate($resultat) {switch ($this->format_reponse) {case 'metaDonnees/champ' : $reponse = $this->formaterMetaDonneesChamp($resultat); break;case 'metaDonnees' : $reponse = $this->formaterMetaDonnees($resultat); break;default : break;}return $reponse;}//--------------------------------------Fonction de formatage des resultats de /metaDonnees/----------------------------public function formaterMetaDonnees($resultat) {foreach ($resultat as $version) {foreach ($version as $key => $val) {if ($val != '') {$this->afficherDonnees($key, $val);}}if ($this->retour_format == 'max' && $this->version_projet == '*') {$this->table_retour['href'] = Config::get('url_service_base').Config::get('nom_projet').'/'.$version['version'].'/'.$this->serviceNom;}$table[] = $this->table_retour;$this->table_retour = array();}return $table;}public function afficherDonnees($key, $valeur) {if ($valeur != '') {$tab = array();if ($this->retour_format == 'min') {if (in_array($key, array('editeur','createurs', 'contributeurs','couverture_spatiale','couverture_temporelle'))) {//Pour les données comprenant plusieurs infos (...=...,...=...;...)$tab = $this->recupererTableauResultat($valeur);$this->afficherConcatenationValeur($key, $tab);} else {$this->table_retour[$key] = trim($valeur);}} else {if (in_array($key, array('editeur','createurs', 'contributeurs','couverture_spatiale','couverture_temporelle','langue','langue_meta'))) {$tab = $this->recupererTableauResultat($valeur);$this->afficherConcatenationValeur($key, $tab);$this->afficherDonneesMax($key,$valeur,$tab);} else {$this->table_retour[$key] = trim($valeur);}}}}/*** Recupère à partir de la valeur du champ les différentes informations séparées par ';' (stocke ds un tableau)* pour éditeurs, créateurs, contributeurs,...* (ex : nom=Tela Botanica,guid=urn:lsid:tela-botanica.org,courriel=accueil@tela-botanica.org,...*/public function recupererTableauResultat($val) {$tab = array();$num_entite = 0;// découpe chaque participant$tab_entites = explode(';', $val);foreach ($tab_entites as $entite) {$tab[$num_entite] = array();if ($entite != '') { // découpe les informations du participant$entite_detail = explode(',', $entite);foreach ($entite_detail as $detail) {if ($detail != '') {if (preg_match('/^([^=]+)=([^=]*)$/', $detail, $match)) {$tab[$num_entite][$match[1]] = $match[2];} else {$tab[$num_entite][] = $detail;}}}}$num_entite++;}return $tab;}/** Retourne :* - le nom de l'editeur* - les coordonnées de l'éditeur sous la forme [latitude]N,[longitude]S [datum]* - la couverture temporelle sous la forme xxxx à xxxx* - la concaténation des noms pour les contributeurs et les créateurs (machin chouette, truc bidule...)* - la liste des liste des couvertures spatiales (le nom et pas le code) (France, allemagne..) */public function afficherConcatenationValeur($champ, $tab) {if (strrpos($champ, '.coordonnees') !== false) {if (isset($tab[0]['latitude']) && isset($tab[0]['longitude']) && isset($tab[0]['datum'])) {$this->table_retour[$champ] = $tab[0]['latitude'].' N, '.$tab[0]['longitude'].' S ['.$tab[0]['datum'].']';}} else {$concat = '';foreach ($tab as $entite) {foreach ($entite as $key => $val) {if ($champ == 'couverture_spatiale') {$concat .= ', '.$this->ajouterSignification($champ, $val);} else {if (strrpos($key, '.prenom') !== false) {$concat .= ', '.$val;} elseif (strrpos($key, 'nom') !== false) {$concat .= ' '.$val;break;}}}}$res = trim($concat, ',');$res = trim($res);if ($champ == 'couverture_temporelle') $res = str_replace(' ', ' à ',$res);$this->table_retour[$champ] = $res;}}public function afficherDonneesMax($champ,$valeur,$tab) {switch ($champ) {case 'couverture_temporelle' : $this->afficherInfosPrecises($champ, 'start,end', $valeur, $tab); break;case 'langue' : $this->afficherInfosPrecises($champ,'signification,code,href', $valeur); break;case 'langue_meta' : $this->afficherInfosPrecises($champ,'signification,code,href', $valeur); break;case 'couverture_spatiale' : $this->afficherInfosPrecises($champ, 'details', $valeur, $tab); break;case 'createurs' : $this->afficherInfosPrecises($champ, 'details', $valeur, $tab); break;case 'contributeurs' : $this->afficherInfosPrecises($champ, 'details', $valeur, $tab); break;case 'editeur' : $this->afficherEditeur($champ, $tab); break;default : $this->table_retour[$champ] = $valeur; break;}}public function afficherEditeur($key, $tab) {// infos générales sur l'éditeurforeach ($tab[0] as $k => $val) {if ((strrpos($k, 'contact.') === false) && (strrpos($k, '.wgs84') === false)) {$this->table_retour[$key.'.'.$k] = $val;}}//on récupère dans un premier temps les tableaux des coordonnées.$table_coordonnees = $this->recupererTableCoordonnees($tab);//on affiche les informations sur les coordonnees : concaténation + détailsif ($table_coordonnees[0] != array()) {$this->afficherConcatenationValeur($key.'.coordonnees', $table_coordonnees);if (isset($table_coordonnees[0]['datum'])) {$this->afficherInfosPrecises($key.'.coordonnees.datum','signification,code,href',$table_coordonnees[0]['datum'],$table_coordonnees);}}$table_contact = $this->recupererTableContact($tab);//on affiche le premier contact en dehors de la table de détail:if ($table_contact[0] != array()) {$this->table_retour[$key.'.contact'] = '';foreach ($table_contact as $info => $valeur) {$this->table_retour[$key.'.contact'] .= $valeur['contact.prenom']." ".$valeur['contact.nom'];}//on affiche les détails des autres contacts :$this->afficherTableDetails($key.'.contact', $table_contact);}}public function afficherInfosPrecises($champ, $pts, $val, $tab = null) {//permet d'afficher les informations précises telles que les .details, .start, .end...$pts = explode(',', $pts);foreach ($pts as $pt) {switch ($pt) {case 'start' :if (isset($this->table_retour[$champ.'.start'])) {$this->table_retour[$champ.'.start'] = $tab['start'];}break;case 'end' :if (isset($this->table_retour[$champ.'.end'])) {$this->table_retour[$champ.'.end'] = $tab['end'];}break;case 'code' :$this->table_retour[$champ.'.code'] = $val;break;case 'href' :$this->table_retour[$champ.'.href'] = $this->ajouterHrefAutreProjet($champ, '', $val);break;case 'signification' :$this->table_retour[$champ] = $this->ajouterSignification($champ, $val);break;case 'details' :if ($champ == 'couverture_spatiale') {$this->afficherCouvertureSpatiale($champ, $tab);} else {$this->afficherTableDetails($champ, $tab);}break;default :$this->table_retour[$champ.'.'.$pt] = $tab[$pt];}}}public function afficherCouvertureSpatiale($key, $tab) {$res = $this->table_retour;$this->table_retour = array();foreach ($tab as $iso) {foreach ($iso as $val) {$this->afficherInfosPrecises($key, 'signification,code,href',$val);$res[$key.'.detail'][] = $this->table_retour;$this->table_retour = array();}}$this->table_retour = $res;}public function afficherTableDetails($champ, $tab) {$res = $this->table_retour;$this->table_retour = array();foreach ($tab as $num_entite => $entite) { // $t et $type valent p ou o$t = '';$type = '.';foreach ($entite as $key => $infos) {list($type, $info) = explode('.', trim($key));if ($type == 'contact') $type = 'p';if ($type != $t) { // cherche et ajoute la signification du type$this->afficherInfosPrecises('type', 'signification,code,href', trim($type));foreach ($this->table_retour as $k => $val) {$res[$champ.'.details'][$num_entite][$type.'.'.$k] = $val;}$table_retour = array();$this->table_retour = array(); // rempli par afficherInfosPrecises$t = $type;}$res[$champ.'.details'][$num_entite][$key] = $infos;}}$this->table_retour = $res;}public function ajouterSignification($champ, $val, $nom = 'nom') {$url = $this->ajouterHrefAutreProjet($champ, '', $val);if (in_array($champ, array('langue', 'langue_meta', 'couverture_spatiale'))) {$url .= '/'.$nom;}$signification = $this->consulterHref($url);if (isset($signification->$nom)) {$res = $signification->$nom;} else {$nom = 'nom.fr';$res = $signification->$nom;}return $res ;}public function recupererTableContact(&$tab) {$res = array();foreach ($tab[0] as $key => $val) {if (strrpos($key, 'contact.') !== false) {while (array_key_exists($key, $res)) { $key = ' '.$key; }$res[$key] = $val;unset($tab[0][$key]); //suppression des premiers contacts qui seront affichés après}}$resultat[0] = $res;return $resultat;}public function recupererTableCoordonnees(&$tab) {$res = array();foreach ($tab[0] as $key => $val) {if (strrpos($key, 'latitude') !== false || strrpos($key, 'longitude') !== false) {list ($coord, $datum) = explode('.', $key);$res[$coord] = $val;$res['datum'] = $datum;}}$resultat[0] = $res;return $resultat;}//-------------------------------------Fonction de formatage des resultats de /metaDonnees/#champs+champs----------------public function formaterMetaDonneesChamp($resultat) {$this->recupererNomChamp(Config::get('bdd_table_meta'));//On récupère dans un premier temps toutes les données existantes puis on pioche les champs recherchés$table_Meta = $this->formaterMetaDonnees($resultat);foreach ($table_Meta as $version) {//on affiche les informations par defaut : la version, la langue_meta et le guid :$this->afficherVersionLangueMetaGuid($version);$tab_ress = explode(' ', $this->table_ressources[0]);foreach ($tab_ress as $champ) {//on recupere le radical pour comparaison avec les nom des champs de la bdd :$this->afficherChampRecherche($champ, $version);}$table[] = $this->table_retour;$this->table_retour = array();}return $table;}public function afficherChampRecherche(&$champ, &$version) {preg_match('/^([^.]+)(?:[.][^.]+)?$/', $champ, $match);if (preg_match('/(.+)[.][*]$/', $champ, $match_2)) {$this->afficherPointEtoile($match_2, $version, $champ);} elseif (array_key_exists($champ, $version)) {$this->table_retour[$champ] = $version[$champ];} elseif (in_array($match[1], $this->champs_table)) {//si le champ est vide dans cette version on retourne null (comparaison avec les champs existants)$this->table_retour[$champ] = null;} else {$champs = implode('</li><li>', array_keys($version));$e = 'Erreur dans votre requête : </br> Le champ "'.$champ.'" n\'existe pas'.'. Les champs disponibles sont : <li>'.$champs.'</li>';$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);}}public function afficherPointEtoile($match, $version, $ressource) {$existe = false;foreach ($version as $key => $valeur) {if (strrpos($key, $match[1].'.') !== false) {$this->table_retour[$key] = $valeur;$existe = true;}}if (!$existe) {$champs = implode('</li><li>', array_keys($version));$e = 'Erreur dans votre requête : </br> Le champ " '.$ressource.' " n\'existe pas dans la version '.$version['version'].'. Les champs disponibles sont : <li>'.$champs.'</li>';$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);}}public function afficherVersionLangueMetaGuid(&$version) {$this->table_retour['version'] = $version['version'];$this->table_retour['langue_meta'] = $version['langue_meta'];$this->table_retour['guid'] = $version['guid'];}}?>