New file |
0,0 → 1,522 |
<?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; |
static $cache_ontologies = array(); |
|
|
public function consulter($ressources, $parametres) { |
$this->ressources = $ressources; |
$this->parametres = $parametres; |
$this->service = '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/#champ |
if (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'éditeur |
foreach ($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étails |
if ($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; |
} |
if(array_key_exists($url, self::$cache_ontologies)) { |
return self::$cache_ontologies[$url]; |
} |
$signification = $this->consulterHref($url); |
if (isset($signification->$nom)) { |
$res = $signification->$nom; |
} else { |
$nom = 'nom.fr'; |
$res = $signification->$nom; |
} |
self::$cache_ontologies[$url] = $res; |
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']; |
} |
} |