/branches/v5.8-aspergeraie/services/modules/0.1/commun/Commun.php |
---|
New file |
0,0 → 1,594 |
<?php |
/** |
* Classe Commun.php est une classe abstraite qui contient les méthodes de base communes à tous les |
* sous-services des projets. |
* |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* @package eflore-projets |
* @author Jennifer DHÉ <jennifer.dhe@tela-botanica.org> |
* @author Delphine CAUQUIL <delphine@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@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-2011 Tela Botanica (accueil@tela-botanica.org) |
*/ |
abstract class Commun { |
/** Objet Bdd. */ |
private $Bdd = null; |
/** Objet Rest Client. */ |
private $RestClient = null; |
/** Contients les paramètres. Doit remplacer table_param. */ |
protected $parametres = array(); |
/** Contients les ressources. Doit remplacer table_ressources. */ |
protected $ressources = array(); |
/** Le nom du service courrant. */ |
protected $serviceNom = null; |
//Classe commune à tous les services web d'un projet. Contient par exemple les fonctions permettant de |
//renvoyer la réponse http... |
protected $entete_http; // Entete de la réponse correspondant au code de réponse de la requete http */ |
protected $corps_http; // Tableau de résultat à retourner au format json ou la description de l'erreur si elle existe */ |
protected $service; // Nom du service appelé |
/** Stocke la version du projet demandée dans la requete |
* - "*" : (/#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 */ |
protected $version_projet = '+'; |
protected $table_version; //Stocke les noms des tables de toutes les versions du projet disponibles |
/** tableau contenant tous les champs d'une table (est rempli par la fonction Commun::recupererNomChamp($table)) */ |
protected $champs_table = array(); |
private static $tri_multi_dimension = array(); |
private static $tri_type = ''; |
public function __construct($config = null) { |
$this->config = is_null($config) ? Config::get($this->serviceNom) : $config; |
} |
public function consulter($ressources, $parametres) { |
$this->ressources = $ressources; |
$this->parametres = $parametres; |
$this->chargerNomDuService(); |
$this->traiterParametres(); |
$this->traiterVersionProjet(); |
$resultats = ''; |
foreach ($this->table_version as $version) { |
$this->table = $version; //on stocke le nom de la table correspondant à la version du projet en cours |
$this->recupererNomChamp($this->table); //on récupère les noms des champs disponibles (Ds Commun.php) |
$this->traiterRessources(); //dans CommunNomsTaxons.php |
$requete = $this->assemblerLaRequete();// dans Noms ou Taxons... |
$resultat = $this->getBdd()->recupererTous($requete . ' -- ' . __FILE__ . ':' . __LINE__ . ' (' .$this->table . ')'); |
$versionResultat = $this->traiterResultat($resultat, $version, $requete); |
if (count($this->table_version) > 1) { |
$resultats[$version] = $versionResultat; |
} else { |
$resultats = $versionResultat; |
} |
} |
return $resultats; |
} |
private function chargerNomDuService() { |
$this->serviceNom = get_class($this); |
} |
public function traiterResultat($resultat, $version) { |
$versionResultat = null; |
if ($resultat == '') { |
//cas ou la requete comporte des erreurs |
$message = 'La requête SQL formée comporte une erreur!'; |
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE; |
throw new Exception($message, $code); |
} elseif ($resultat) { |
$versionResultat = $this->retournerResultatFormate($resultat, $version); |
} else { |
$message = 'Les données recherchées sont introuvables.'; |
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE; |
throw new Exception($message, $code); |
} |
return $versionResultat; |
} |
//+------------------------------------------------------------------------------------------------------+ |
// Méthodes concernant les paramètres |
/** |
* Permet de récupérer une liste des noms des champs de la table passée en paramètre |
* @param $table : Nom de la table dont on souhaite connaitre les champs |
*/ |
public function recupererNomChamp($table) { |
$resultat = @$this->getBdd()->recupererTous('SHOW FIELDS FROM '.$table); |
if (!$resultat) { |
$m = "La table recherchée n'existe pas"; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $m); |
} |
foreach ($resultat as $info) $this->champs_table[] = $info['Field']; |
} |
/** |
* Fonction permettant de creer la table dont le nom est passé en paramètre (champs_api, champs_bdtfx, |
* correspondance_champs...). Les données de chaque table sont présentes dans le fichier de configuration config.ini |
* @param String $table : Peut contenir plusieurs nom de table dont on souhaite récupérer les données : table,table,table. |
* Ex : recupererTableConfig('champs_api,champs_bdtfx') |
*/ |
public function recupererTableConfig($table) { |
$tables = explode(',', $table); |
foreach ($tables as $tab) { |
$tableau = explode(',', Config::get($tab)); |
$tableau = array_map('trim', $tableau); |
foreach ($tableau as $champ) { |
list($code, $rang) = explode('=', $champ); |
$tab_tampon[$code] = $rang; |
} |
$this->$tab = $tab_tampon; |
$tab_tampon = array(); |
} |
} |
public function renvoyerErreur($entete, $message) { |
throw new Exception($message, $entete); |
} |
/** |
* Permet de remplir la variable version_projet et de retirer cette donnée du tableau des ressources |
* @param $ressources |
*/ |
public function traiterVersionProjet() { |
if (isset($this->parametres['version.projet'])) { |
if (preg_match('/^[0-9]+(?:[._][0-9]+|)$/', $this->parametres['version.projet'])) { |
$this->version_projet = $this->parametres['version.projet']; |
$this->version_projet = 'v'.str_replace('.', '_', $this->version_projet); |
} else { |
$this->version_projet = $this->parametres['version.projet']; |
} |
} |
//si la liste des noms est demandée pr toutes les versions, on affiche seulement la dernière version : |
if ($this->version_projet == '*' && $this->ressources == array()) { |
$message = "L'affichage de plusieurs versions ne fonctionne que pour les ressources de type /ressources/#id"; |
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE; |
throw new Exception($message, $code); |
} |
//on recupère les versions du projet disponible dans la table des meta-donnees (utilisation service MetaDonnees) |
$table_num_version = $this->recupererVersionDisponible(); |
//on recupere la liste des noms des tables de la bdd correspondant aux differentes versions du projet en fct de la ou les versions demandées |
$this->recupererListeNomTablePrChaqueVersion($table_num_version); |
} |
/** |
* Recupération des versions disponibles par appel du service metaDonnees |
* Verification de l'existance du service recherché dans la requete (si précisé : hors *) |
* @return array : tableau contenant le numéro de chaque version disponible |
*/ |
public function recupererVersionDisponible() { |
$versions_dispo = ''; |
$req_version = 'SELECT version FROM '.Config::get('bdd_table_meta'); |
$res_version = $this->getBdd()->recupererTous($req_version); |
if ($res_version == '') { //cas ou la requete comporte des erreurs |
$e = "La requête SQL de versionnage formée comporte une erreur : $req_version"; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e); |
} elseif ($res_version) { |
foreach ($res_version as $version) { |
$versions_dispo[] = $version['version']; |
} |
} else { |
$m = 'Versions introuvables dans la table des méta-données'; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $m); |
} |
return $versions_dispo; |
} |
public function recupererListeNomTablePrChaqueVersion($table_num_version) { |
switch ($this->serviceNom) { |
case 'Ontologies' : |
$prefixe_table = 'bdd_table_ontologies'; |
break; |
default: |
$prefixe_table = 'bdd_table'; |
} |
switch ($this->version_projet) { |
case '+' : |
$derniere_version = $table_num_version[count($table_num_version) - 1]; |
$this->table_version[] = Config::get($prefixe_table).'_v'.str_replace('.', '_', $derniere_version); |
break; |
case '*' : |
foreach ($table_num_version as $num_version) { |
$this->table_version[] = Config::get($prefixe_table).'_v'.str_replace('.', '_', $num_version); |
} |
break; |
default : |
$this->table_version[] = Config::get($prefixe_table).'_'.$this->version_projet; |
break; |
} |
} |
//valeur * signifie pas de limites |
public function definirNavigationLimite($valeur){ |
if (isset($this->parametres['navigation.limite']) ) { |
if ((preg_match('/^([0-9]+)$/', $valeur) && $valeur != 0 ) || $valeur == '*' ){ |
$this->limite_requete['limite'] = $valeur; |
} else { |
$e = "Erreur : valeur erronnée pour le paramètre navigation.limite."; |
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE); |
} |
} |
} |
public function definirNavigationDepart($valeur){ |
if (isset($this->parametres['navigation.depart'])) { |
if(preg_match('/^([0-9]+)$/', $valeur)){ |
$this->limite_requete['depart'] = $valeur; |
} else { |
$e = "Erreur : valeur erronnée pour le paramètre navigation.depart."; |
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE); |
} |
} else { |
$e = "indiquez également la valeur pour le paramètre navigation.limite."; |
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE); |
} |
} |
/** |
* Est appelée pour former l'url complete des resultats precedants ou suivants. |
* @param int : Permet de connaitre le nombre de noms obtenus par la requete |
* @return string Retourne l'url complete des resultats precedents ou suivant sous la forme d'un tableau |
*/ |
public function formulerUrl($nb_resultat, $id = null) { |
$url = array(); |
$debut_url = Config::get('url_service').$id.'?'; |
//on recréé l'url sans les parametres de navigation qui seront rajoutés ci-apres. On les enlève dc de la table des parametres |
foreach($this->parametres as $cle => $val) { |
$param_url[str_replace('_', '.', $cle)] = $val; |
} |
$this->recupererLesLimitesSuivantes($nb_resultat, $param_url); |
if (isset($param_url['navigation.depart']) && isset($param_url['navigation.limite'])) { |
$url['suivant'] = $debut_url.http_build_query($param_url); |
} |
$this->recupererLesLimitesPrecedentes($param_url); |
if (isset($param_url['navigation.depart']) && isset($param_url['navigation.limite'])) { |
$url['precedent'] = $debut_url.http_build_query($param_url); |
} |
return $url; |
} |
public function supprimerNavigation(&$param_url) { |
unset($param_url['navigation.depart']); |
unset($param_url['navigation.limite']); |
} |
/** |
* Description : |
* Permet de former les limites de la requete retournant les résultats suivants. |
* Cette url sera afficher dans l'entete de la reponse retournée en format JSON (retour.format=defaut). |
* @param int : $nb_resultat : Permet de connaitre le nombre de résultats obtenus par la requete |
* @return string : la fin de l'url decrivant les limites des resultats suivants. Si aucun résultats ne suient, |
* une chaine de caractère vide est retournée |
*/ |
public function recupererLesLimitesSuivantes($nb_resultat, &$param_url_suiv) { |
$this->supprimerNavigation($param_url); |
$depart = $this->limite_requete['depart']; |
$limite = $this->limite_requete['limite']; |
$depart_suivant = $depart + $limite; |
$limite_suivant = $limite; |
if ($nb_resultat > $depart_suivant) { |
$param_url_suiv['navigation.depart'] = $depart_suivant; |
$param_url_suiv['navigation.limite'] = $limite_suivant; |
} else { |
$param_url_suiv['navigation.depart'] = null; |
$param_url_suiv['navigation.limite'] = null; |
} |
} |
/** |
* Description : |
* Permet de former les limites de la requete retournant les résultats precedents. |
* Cette url sera afficher dans l'entete de la taxons/105reponse retournée en format JSON (retour.format=defaut) |
* @return string : la fin de l'url decrivant les limites des resultats precedents. |
* Si aucun résultats ne precedent, une chaine de caractère vide est retournée |
*/ |
public function recupererLesLimitesPrecedentes(&$param_url) { |
$this->supprimerNavigation($param_url); |
$depart = $this->limite_requete['depart']; |
$limite = $this->limite_requete['limite']; |
if ($depart == 0) { |
$url_precedente = ''; |
} else { |
if (($depart - $limite) < 0) { |
$depart_precedent = 0; |
} else { |
$depart_precedent = $depart - $limite; |
} |
$param_url['navigation.depart'] = $depart_precedent; |
$param_url['navigation.limite'] = $limite; |
} |
} |
static function getDureeCache() { |
$dureecache = 0; |
$dureecache = Config::get('dureecache'); |
if ($dureecache == null || !is_numeric($dureecache) || $dureecache < 0) { |
$dureecache = 0; |
} |
return (int) $dureecache; |
} |
public function ajouterHref($service, $val) { |
// http://tela-botanica.org/service:eflore:0.1/[projet]/[version_projet]/[service]/[ressource]:[valeur] |
if ($this->version_projet == '+') { |
$url = Config::get('url_service_base').Config::get('nom_projet').'/'.$service.'/'.$val; |
} else { |
$url = Config::get('url_service_base').Config::get('nom_projet').'/'.$service.'/'.$val.'?version.projet='.ltrim($this->version_projet, 'v'); |
} |
return $url; |
} |
static function s_ajouterHref($service, $val, $version_projet = '') { |
// http://tela-botanica.org/service:eflore:0.1/[projet]/[version_projet]/[service]/[ressource]:[valeur] |
return Config::get('url_service_base').Config::get('nom_projet').'/'.$service.'/'.$val . ($version_projet != '+') ? ('?version.projet='.ltrim($version_projet, 'v')) : ''; |
} |
public function ajouterHrefAutreProjet($service, $ressource, $valeur, $projet = null, $param = null) { |
//on enleve les GA et Co, les meta ou les "_" |
$this->transliterer($service, $valeur); |
//on définit les nom des projets, des services et des ressources de l'url (dans les méta-donnees) |
$tab = array( |
'langue' => array('service' => 'langues', 'projet' => 'iso-639-1', 'ressource' => ''), |
'couverture_spatiale' => array('service' => 'zone-geo', 'projet' => 'iso-3166-1', 'ressource' => ''), |
'type' => array('service' => 'ontologies', 'projet' => 'eflore', 'ressource' => 'contactType:'), |
'datum' => array('service' => 'ontologies', 'projet' => 'eflore', 'ressource' => 'datum:') |
); |
if (array_key_exists($service, $tab)) { |
extract($tab[$service]); |
} else { |
if (strpos(Config::get('nom_projet'), 'bd') === 0 && $projet == null) { |
$projet = 'bdnt'; |
$service = 'ontologies'; |
$ressource = ''; |
} |
} |
$param = ($param) ? "?".$param : ""; |
$url = Config::get('url_service_base').$projet.'/'.$service.'/'.$ressource.$valeur.$param; |
return $url; |
} |
static function s_ajouterHrefAutreProjet($service, $ressource, $valeur, $projet = null, $param = null) { |
//on enleve les GA et Co, les meta ou les "_" |
self::s_transliterer($service, $valeur); |
//on définit les nom des projets, des services et des ressources de l'url (dans les méta-donnees) |
$tab = array( |
'langue' => array('service' => 'langues', 'projet' => 'iso-639-1', 'ressource' => ''), |
'couverture_spatiale' => array('service' => 'zone-geo', 'projet' => 'iso-3166-1', 'ressource' => ''), |
'type' => array('service' => 'ontologies', 'projet' => 'eflore', 'ressource' => 'contactType:'), |
'datum' => array('service' => 'ontologies', 'projet' => 'eflore', 'ressource' => 'datum:') |
); |
if (array_key_exists($service, $tab)) { |
extract($tab[$service]); |
} else { |
if (strpos(Config::get('nom_projet'), 'bd') === 0 && $projet == null) { |
$projet = 'bdnt'; |
$service = 'ontologies'; |
$ressource = ''; |
} |
} |
$param = ($param) ? "?".$param : ""; |
$url = Config::get('url_service_base').$projet.'/'.$service.'/'.$ressource.$valeur.$param; |
return $url; |
} |
/**Permet de consulter une url et retourne le résultat ou une erreur |
* @param $url */ |
public function consulterHref($url) { |
$res = $this->getRestClient()->consulter($url); |
$entete = $this->getRestClient()->getReponseEntetes(); |
//Si le service meta-donnees fonctionne correctement, l'entete comprend la clé wrapper_data |
if (isset($entete['wrapper_data'])) { |
$res = json_decode($res); |
return $res; |
} else { |
$u = 'L\'url <a href="'.$url.'">'.$url.'</a> lancée via RestClient renvoie une erreur'; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $u); |
} |
} |
public function transliterer(&$service, &$val) { |
if (preg_match('/^.+:(.+)$/', $val, $match)) { |
$val = $match[1]; |
} |
$service = str_replace(array('_Ga','_Co','_meta'), '', $service); |
if ($service == 'rang') { |
$ressource = 'rangTaxo'; |
} elseif (preg_match('/^(statut)(?:_|-)([^_-]+)$/', $service, $match)) { |
$service = $match[1].ucfirst($match[2]); |
} elseif (strrpos($service, 'datum') !== false) { |
$service = 'datum'; |
} |
} |
static function s_transliterer(&$service, &$val) { |
if (preg_match('/^.+:(.+)$/', $val, $match)) { |
$val = $match[1]; |
} |
$service = str_replace(array('_Ga','_Co','_meta'), '', $service); |
if ($service == 'rang') { |
$ressource = 'rangTaxo'; |
} elseif (preg_match('/^(statut)(?:_|-)([^_-]+)$/', $service, $match)) { |
$service = $match[1].ucfirst($match[2]); |
} elseif (strrpos($service, 'datum') !== false) { |
$service = 'datum'; |
} |
} |
// prend en arguments la valeur de la recherche, les résultats approchés, le paramétre recherche |
// retourne le tableau trié en fonction de la ressemblance entre le résultat approché et la valeur recherchée |
public function trierRechercheFloue($nom_demande, $tab_approchee, $nom) { |
$trie = ''; |
$resultat = array(); |
foreach ($tab_approchee as $id => $tab) { |
$nom_demande_ss = strtolower(Chaine::supprimerAccents($nom_demande)); |
$nom_flou_ss = strtolower(Chaine::supprimerAccents($tab[$nom])); |
$stat = array(); |
// Prime pour la ressemblance globale : |
$score = 500 - levenshtein($nom_flou_ss, $nom_demande_ss); |
// On affine |
$score = $score + (similar_text($nom_demande_ss, $nom_flou_ss) * 3); |
$stat['score'] = $score; |
foreach ($tab as $key => $valeur) { |
$stat[$key] = $valeur; |
} |
$resultat[] = $stat; |
} |
// Vérification que nous avons bien trouvé un nom approché |
if (count($resultat) > 0) { |
$trie = Tableau::trierMD($resultat, array('score' => SORT_DESC)); |
} |
return $trie; |
} |
protected function recupererTableauConfig($param) { |
$tableau = array(); |
$tableauPartiel = explode(',', Config::get($param)); |
$tableauPartiel = array_map('trim', $tableauPartiel); |
foreach ($tableauPartiel as $champ) { |
if (strpos($champ, '=') === false) { |
$tableau[] = $champ; |
} else { |
list($cle, $val) = explode('=', $champ); |
$tableau[$cle] = $val; |
} |
} |
return $tableau; |
} |
static function s_recupererTableauConfig($param) { |
$tableau = array(); |
$tableauPartiel = array_map('trim', explode(',', Config::get($param))); |
foreach ($tableauPartiel as $champ) { |
if (strpos($champ, '=') === false) { |
$tableau[] = $champ; |
} else { |
list($cle, $val) = explode('=', $champ); |
$tableau[$cle] = $val; |
} |
} |
return $tableau; |
} |
//+------------------------------------------------------------------------------------------------------+ |
// Méthodes d'accès aux objets du Framework |
/** |
* Méthode de connection à la base de données sur demande. |
* Tous les services web n'ont pas besoin de s'y connecter. |
*/ |
protected function getBdd() { |
if (! isset($this->Bdd)) { |
$this->Bdd = new Bdd(); |
} |
return $this->Bdd; |
} |
/** |
* Méthode permettant de faire appel à un client REST en fonction des besoins du service. |
*/ |
protected function getRestClient() { |
if (! isset($this->RestClient)) { |
$this->RestClient = new RestClient(); |
} |
return $this->RestClient; |
} |
/** |
* Génération de fichiers pour les cartes |
*/ |
static function convertirEnPNGAvecRsvg($idFichier, $chemin, $svg) { |
// test répertoire de cache |
if(!is_dir($chemin)) { |
mkdir($chemin, 0777, true); |
} |
if(!is_dir($chemin)) { |
error_log(__FILE__ . ": can't create cache {$chemin}"); |
return NULL; |
} |
// test présence du binaire de conversion (rsvg) |
/* |
// `which` no possible using safe-mode... |
$i = $s = NULL; |
exec('which rsvg-convert', $s, $i); |
if($i != 0) { |
error_log(__FILE__ . ": no rsvg-convert binary"); |
return NULL; |
} |
*/ |
// conversion svg => png |
// troncage du nom de fichier si celui-ci est trop long |
// (passé 255 caractères, le risque de collision est très faible) |
$cheminReduit = substr($chemin.$idFichier, 0, 240); |
$fichierPng = $cheminReduit.'.png'; |
$fichierSvg = $cheminReduit.'.svg'; |
file_put_contents($fichierSvg, $svg); |
$i = $s = NULL; |
$rsvg = exec("rsvg-convert $fichierSvg -d 75 -p 75 -o $fichierPng", $s, $i); |
if($i != 0) { |
error_log(__FILE__ . ": `rsvg-convert $fichierSvg -o $fichierPng` returned $i: " . implode(', ', $s)); |
return NULL; |
} |
self::indexerFichierPng($fichierPng); |
return file_get_contents($fichierPng); |
} |
static function indexerFichierPng($fichierPng) { |
$img = imagecreatefrompng($fichierPng); |
imagetruecolortopalette($img, false, 32); |
$blanc = imagecolorallocate($img, 255, 255, 255); |
imagefill($img, 0, 0, $blanc); |
imagepng($img, $fichierPng, 9, PNG_ALL_FILTERS); |
} |
//+------------------------------------------------------------------------------------------------------+ |
// Fonctions appelées par plusieurs web services |
public function obtenirNumNomTaxonsSuperieurs($referentiel, $nn_demande) { |
$nn_taxons_sup = array(); |
// TODO: ceci ramène trop de champs alors que l'on a besoin que du numéro nomenclatural |
// et il y a peut-être un meilleur moyen que ramener la hierarchie des taxons supérieurs |
// mais pour le moment ça marche et c'est assez rapide |
$url = $this->ajouterHrefAutreProjet('taxons', $nn_demande, '/relations/superieurs',$referentiel); |
$classification = $this->consulterHref($url); |
$classification = is_object($classification) ? get_object_vars($classification) : array(); |
if(isset($classification[$nn_demande])) { |
$classification_nn_demande = get_object_vars($classification[$nn_demande]); |
$tab_nn_demandes = array_keys($classification_nn_demande); |
$nn_taxons_sup = $tab_nn_demandes; |
} |
return $nn_taxons_sup; |
} |
static function extraireComplementsOntologies($ontologie) { |
if (!$ontologie['complements']) return $ontologie; |
$complements = explode(',', trim($ontologie['complements'])); |
foreach ($complements as $complement) { |
@list($cle, $val) = explode('=', trim($complement)); |
// TODO: dirty workaround. Les compléments aux ontologies utilisent |
// des séparateurs variables. |
// cf disabledtestSeparateurToutesOntologies() dans tests/0.1/eflore/EfloreOntologiesTest.php |
// ainsi nous testons $cle et $val |
if($cle && $val) $ontologie[trim($cle)] = trim($val); |
} |
return $ontologie; |
} |
} |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v5.8-aspergeraie/services/modules/0.1/commun/Aide.php |
---|
New file |
0,0 → 1,223 |
<?php |
/** |
* Description : |
* Classe Aide.php fournit des informations sur les services des projets : leur état (up ou down), une description, |
* le lien vers le wikini |
* La ressource /projets donne la liste de tous les projets concernés par cette api. |
* |
* 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 Aide extends RestService { |
protected $retour_format = 'max'; |
protected $url_wikini = 'http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki='; |
protected $url_liste_projet = ''; |
protected $table_retour = array(); |
protected $corps_http = ''; |
protected $entete_http = ''; |
protected $projet = ''; |
public function consulter($ressources, $parametres) { |
$this->url_liste_projet = Config::get('url_service_base').'commun/aide/projets'; |
$this->projet = Config::get('nom_projet'); |
$this->traiterRessources($ressources); |
return $this->formerReponseHTTP($this->table_retour); |
} |
//-----------------------------------------traiter reponse http------------------------------------------------------------- |
public function formerReponseHTTP($resultat_formate, $mime = 'application/json', $encodage= 'utf-8') { |
// Si aucune erreur n'a été établie (donc un tableau de résultat a bien ete renvoyé...) |
if ($this->corps_http == '' && $this->entete_http == '') { |
$this->entete_http = RestServeur::HTTP_CODE_OK; |
$this->corps_http = $resultat_formate; |
} |
if ($this->entete_http != RestServeur::HTTP_CODE_OK) { |
$mime = 'text/html'; |
} |
// Gestion du type de contenu |
if (!is_null($mime) && !is_null($encodage)) { |
if(strpos($_SERVER['SCRIPT_NAME'], 'phpunit') === FALSE) header("Content-Type: $mime; charset=$encodage"); |
} else if (!is_null($mime) && is_null($encodage)) { |
if(strpos($_SERVER['SCRIPT_NAME'], 'phpunit') === FALSE) header("Content-Type: $mime"); |
} |
// Envoie de l'entête |
RestServeur::envoyerEnteteStatutHttp($this->entete_http); |
// Envoie du corps |
return $this->corps_http; |
} |
public function renvoyerErreur($e, $c) { |
$this->entete_http = $e; |
$this->corps_http = $c; |
} |
//---------------------------------traiter Ressources------------------------------------------------------------------ |
public function traiterRessources($ressources) { |
if (isset($ressources) && !empty($ressources)) { |
//-----------------------service /aide/projets------------------------------------ |
if ($ressources[0] == 'projets') { |
$this->afficherInfosTousProjets(); |
} else { |
$r = 'Erreur dans votre requête </br> Ressources disponibles : |
<br/><li> /aide </li><li> /aide/projets </li>'; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r); |
} |
} else { |
//-----------------------service /aide------------------------------------ |
$this->afficherInfosProjet(); |
$this->formaterAideListeProjetEtRessources(); |
} |
} |
public function afficherInfosTousProjets() { |
$req = 'show tables'; |
$tables = $this->getBdd()->recupererTous($req); |
foreach ($tables as $table) { |
if (preg_match('/^(.+)_meta$/', array_shift($table), $projet)) { |
if (isset($projet[1])) { |
$projets[] = $projet[1]; |
} else { |
$e = "erreur."; |
trigger_error($e, E_USER_ERROR); |
} |
} |
} |
foreach ($projets as $projet) { |
$this->table_retour[$projet] = $this->recupererInfoProjet($projet); |
} |
} |
public function recupererInfoProjet($projet) { |
$res_return = null; |
$projet = str_replace('_', '-', $projet); |
$url = Config::get('url_service_base').$projet.'/aide'; |
$intitule = 'PROJET '.strtoupper($projet); |
$res = $this->consulterHref($url); |
if ($res) { |
$res_return = $res->$intitule; |
} |
return $res_return; |
} |
public function formaterAideListeProjetEtRessources() { |
$projets = 'LISTE DES PROJETS'; |
$services = 'Ressources'; |
$this->table_retour[$projets]['liste des projets en place']['href'] = $this->url_liste_projet; |
$this->table_retour[$projets]['liste de tous les projets']['wikini'] = $this->url_wikini.'EfloreIntegrationProjets'; |
} |
public function afficherInfosProjet() { |
$res = array(); |
$ressources = $this->recupererListeDesRessources(); |
if (isset($ressources['href']) && $ressources['href'] != '') { |
$this->table_retour['PROJET '.strtoupper($this->projet)]['projet.href'] = $ressources['href']; |
} |
$etats = $this->verifierEtatDesRessources($ressources['WS']); |
$this->table_retour['PROJET '.strtoupper($this->projet)]['projet.services'] = $etats['projet.services']; |
} |
public function recupererListeDesRessources() { |
$resultat = null; |
$req = 'SELECT url_projet, version, web_services FROM '.Config::get('bdd_table_meta').' ORDER BY CAST(version as DECIMAL)'; |
$res = $this->getBdd()->recuperer($req); |
if ($res == '') { |
$r = 'La requête SQL formée comporte une erreur !!'; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $r); |
Debug::printr($req); |
} elseif ($res) { |
$resultat['WS'] = $res['web_services']; |
$resultat['href'] = $res['url_projet']; |
} else { |
$d = 'Les données recherchées sont introuvables dans la version '.$res[0]['version'].'de la table de méta données'; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $d); |
Debug::printr($req); |
} |
return $resultat; |
} |
public function verifierEtatDesRessources($ressources) { |
$ressources = explode(';', $ressources); |
$etats = array(); |
foreach ($ressources as $key => $ressApi) { |
list($ress, $api) = explode(':', $ressApi); |
$this->translitererRess($ress); |
$url = Config::get('url_service').'/'.$ress; |
$wikini = $this->url_wikini.'EfloreApi'.str_replace('.', '', $api).$this->creerChaMot($ress); |
$url_service = Config::get('url_service').'/'.$ress; |
$etat = array( |
'service.nom' => $ress, |
'service.href' => $url_service, |
'service.wikini' => $wikini, |
'service.etat' => 'UP'); |
$res = $this->consulterHref($url); |
if (!$res) { |
$etat['service.etat'] = 'DOWN'; |
} |
$etats['projet.services'][] = $etat; |
} |
return $etats; |
} |
/**Permet de consulter une url et retourne le résultat ou une erreur |
* @param $url */ |
public function consulterHref($url) { |
$res = $this->getRestClient()->consulter($url); |
$entete = $this->getRestClient()->getReponseEntetes(); |
//Si le service meta-donnees fonctionne correctement, l'entete comprend la clé wrapper_data |
if (isset($entete['wrapper_data'])) { |
$res = json_decode($res); |
return $res; |
} else { |
$u = 'L\'url <a href="'.$url.'">'.$url.'</a> lancée via RestClient renvoie une erreur'; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $u); |
} |
} |
public function translitererRess(&$ress) { |
$ress = strtolower($ress); |
if ($ress == 'metadonnees') { |
$ress = 'meta-donnees'; |
} |
} |
public function creerChaMot($nom) { |
$chaine = new Chaine(); |
$nom = $chaine->supprimerAccents($nom); |
$nom_modif = ''; |
$nom_dec = preg_split('/-/', $nom); |
foreach ($nom_dec as $dec) { |
$nom_modif .= ucfirst($dec); |
} |
return trim($nom_modif); |
} |
} |
?> |
/branches/v5.8-aspergeraie/services/modules/0.1/commun/MetaDonnees.php |
---|
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']; |
} |
} |
/branches/v5.8-aspergeraie/services/modules/0.1/commun/Ontologies.php |
---|
New file |
0,0 → 1,440 |
<?php |
/** |
* Description : |
* Classe Ontologies.php fournit des informations sur ensemble structuré des termes et concepts représentant les éléments |
* d'un domaine de connaissances . |
* Le but étant de fournir un ensemble minimal d'information comprenant : |
* un identifiant (numérique ou alphanumérique sous forme de ChatMot si possible), un nom, une description et |
* éventuellement une relation hiérarchique avec un autre terme (=classe). |
* Si l'url finit par /ontologies 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 ? : /ontologies?param1=val1¶m2=val2&... |
* |
* Les paramètres de requête disponibles sont : masque, masque.code, masque.nom, masque.description , recherche, |
* distinct, retour.format, navigation.depart et navigation.limite. |
* |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* @package eflore-projets |
* @author Jennifer DHÉ <jennifer.dhe@tela-botanica.org> |
* @author Delphine CAUQUIL <delphine@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@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 0.1 |
* @copyright 1999-2011 Tela Botanica (accueil@tela-botanica.org) |
*/ |
class Ontologies extends Commun { |
protected $requete_condition = null; //Représente la partie de la requete SQL ajoutant une condition (WHERE ...) |
/** Permet de stocker la requete formulée: /ontologies | /ontologies/#id | /ontologies/#id/champ | /ontologies/#id/relations */ |
protected $format_reponse = 'ontologies'; |
/** Permet de stocker les limite de la requete SQL (par défaut seul les 100 premiers résultats seront retournés). |
* Stocke également les valeurs des paramètres navigation.depart et navigation.limite passés dans la requete*/ |
protected $limite_requete = array( 'depart' => 0, 'limite' => 100); |
/** Stocke le nombre total de résultats de la requete principale. Est calculée lors de l'assemblage de la requete */ |
protected $total_resultat; |
protected $retour_format = 'max'; |
// beaucoup plus flexible dans le cas de requêtes SQL complexes |
protected $mesChamps = ''; |
protected $mesJoinsEtConditions = ''; |
public function traiterParametres() { |
if (isset($this->parametres) && !empty($this->parametres)) { |
foreach ($this->parametres as $param => $valeur) { |
switch ($param) { |
case 'masque' : $this->ajouterLeFiltreMasque('masque', $valeur); break; |
case 'masque.code' : $this->ajouterLeFiltreMasque('code', $valeur); break; |
case 'masque.nom' : $this->ajouterLeFiltreMasque('nom', $valeur); break; |
case 'masque.description' : $this->ajouterLeFiltreMasque('description', $valeur); break; |
case 'retour.format' : $this->retour_format = $valeur; break; |
case 'retour.champs' : $this->parametres['retour_champs'] = $valeur; break; |
case 'navigation.depart' : $this->limite_requete['depart'] = $valeur; break; |
case 'navigation.limite' : $this->limite_requete['limite'] = $valeur; break; |
case 'recherche' : break; |
case 'version.projet' : break; |
default : |
$e = 'Erreur dans les parametres de recherche de votre requête : </br> Le paramètre " ' |
.$param.' " n\'existe pas.'; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e); break; |
} |
} |
} |
} |
public function ajouterLeFiltreMasque($nom_champ, $valeur) { |
if ($nom_champ == 'code') { |
$this->requete_condition[] = $nom_champ.' = '.$this->getBdd()->proteger($valeur); |
} else { |
if (isset($this->parametres['recherche']) && $this->parametres['recherche'] == 'floue') { |
if ($nom_champ == 'masque') { |
$this->requete_condition[] = '( code = '.$this->getBdd()->proteger($valeur) |
.' OR ( SOUNDEX(nom) = SOUNDEX(\''.$valeur.'\')' |
.' OR SOUNDEX(REVERSE(nom)) = SOUNDEX(REVERSE(\''.$valeur.'\')) ' |
.') OR ( SOUNDEX(description) = SOUNDEX(\''.$valeur.'\')' |
.' OR SOUNDEX(REVERSE(description)) = SOUNDEX(REVERSE(\''.$valeur.'\')) ))'; |
} else { |
$this->requete_condition[] = '(SOUNDEX('.$nom_champ.') = SOUNDEX(\''.$valeur.'\')' |
.' OR SOUNDEX(REVERSE('.$nom_champ.')) = SOUNDEX(REVERSE(\''.$valeur.'\')))'; |
} |
} else { |
if (isset($this->parametres['recherche']) && $this->parametres['recherche'] == 'etendue') { |
$valeur = str_replace(' ','%', $valeur); |
$valeur .= '%'; |
} |
if ($nom_champ == 'masque') { |
$this->requete_condition[] = '(code = '.$this->getBdd()->proteger($valeur) |
.' OR nom LIKE '.$this->getBdd()->proteger($valeur) |
.' OR description LIKE '.$this->getBdd()->proteger($valeur).')'; |
} else { |
$this->requete_condition[] = $nom_champ.' LIKE '.$this->getBdd()->proteger($valeur); |
} |
} |
} |
} |
public function traiterRessources() { |
if (isset($this->ressources) && !empty($this->ressources)) { |
if (isset($this->ressources[0]) && !empty($this->ressources[0])) { |
//requete = /ontologies/#id |
$this->traiterRessourceId(); |
if (isset($this->ressources[1]) && !empty($this->ressources[1])) { |
//requete = /ontologies/#id/relations |
$this->traiterRessourceRelations(); |
} |
} |
} |
} |
public function traiterRessourceId() { |
$this->requete_condition = array(); |
//requete : /ontologies/#id (ex : /ontologies/7) |
if (is_numeric($this->ressources[0])) { |
$this->requete_condition[] = ' id = '.$this->getBdd()->proteger($this->ressources[0]); |
$this->format_reponse .= '/id'; |
//requete : /ontologies/#classe:#code (ex : /ontologies/rangTaxo:290) |
} elseif (strrpos($this->ressources[0], ':') !== false) { |
// plusieurs couples #classe:#code séparés par des virgules |
if(strrpos($this->ressources[0], ',') !== false) { |
$this->traiterMultipleRessourceId(); |
return; |
} |
// ou un unique couple #classe:#code |
$this->format_reponse .= '/id'; |
preg_match('/^([^:]+):([^:]+)$/', $this->ressources[0], $match); |
$this->requete_condition[] = |
' id IN (SELECT id FROM '.$this->table.' WHERE code = '.$this->getBdd()->proteger($match[2]) |
.' AND classe_id = (SELECT id FROM '.$this->table.' WHERE code = '.$this->getBdd()->proteger($match[1]).'))'; |
// TODO: optimiser, à voir: traiterMultipleRessourceId() ci-dessous |
// SELECT a.* |
// FROM $this->table a |
// LEFT JOIN $this->table b ON a.id = b.id LEFT JOIN $this->table c ON b.classe_id = c.id |
// WHERE b.code = $this->getBdd()->proteger($match[2]) |
// AND c.code = $this->getBdd()->proteger($match[1]); |
} else { |
$e = 'Erreur dans les paramètres de recherche de votre requête : </br> Le paramètre " ' |
.$this->ressources[0].' " n\'existe pas.'; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e); |
} |
} |
// Requète : /ontologies/#classe:#code,[...] (ex : /ontologies/numStatus:2,numStatus:3,genreNombre:10) |
public function traiterMultipleRessourceId() { |
$this->format_reponse .= '/ids'; // noter le "s" |
$this->mesChamps = Array( |
// 'a.*' // pourquoi pas, mais alors des unset() seront nécessaire |
'a.id', |
'a.classe_id AS `classe.id`', |
'a.nom', |
'a.description', |
'a.code', |
'a.complements', |
'c.nom AS classe', // évite très simplement (un très couteux) ajouterClasseCorrespondante() |
'concat(c.code,":", b.code) AS requete'); // permet aux appelants de récupérer la valeur qu'ils recherchent |
$this->mesChamps = implode(', ', $this->mesChamps); |
$this->mesJoinsEtConditions = |
// alias de la table première |
" a " |
. " LEFT JOIN {$this->table} b ON a.id = b.id LEFT JOIN {$this->table} c ON b.classe_id = c.id" |
. " WHERE "; |
$or_stack = false; |
$tab = explode(',', $this->ressources[0]); |
foreach($tab as $couple) { |
preg_match('/^([^:]+):([^:]+)$/', $couple, $match); |
if($or_stack) { |
// une fois qu'un set de condition et présent, |
// les autres sont `OR`-ed. |
$this->mesJoinsEtConditions .= " OR "; |
} |
$this->mesJoinsEtConditions .= |
sprintf("(b.code = %s AND c.code = %s)", |
$this->getBdd()->proteger($match[2]), |
$this->getBdd()->proteger($match[1])); |
$or_stack = true; |
} |
} |
public function traiterRessourceRelations() { |
//requete = /ontologies/#id/relations : |
if ($this->ressources[1] == 'relations') { |
$this->format_reponse .= '/relations'; |
$this->requete_condition = array('classe_id = (SELECT classe_id FROM '.$this->table.' WHERE ' |
.implode(' AND ', $this->requete_condition).')'); |
} |
} |
//+--------------------------FONCTION ASSEMBLAGE DE LA REQUETE-------------------------------------------+ |
public function assemblerLaRequete() { |
$requete = ' SELECT '.$this->formerRequeteChamp(). |
' FROM '.$this->table |
.$this->retournerRequeteCondition() |
.$this->formerRequeteLimite(); //print_r($requete); |
return $requete; |
} |
public function formerRequeteChamp() { |
if($this->mesChamps) return $this->mesChamps; |
$champ[] = 'id'; |
if ($this->format_reponse == 'ontologies') { |
$champ[] = 'nom, code '; |
} |
if (isset($this->parametres['retour_champs']) || $this->format_reponse == 'ontologies/id/champs') { |
$champs_recherches = explode(',', $this->parametres['retour_champs']); |
$champs_possibles = $this->rechercherChampsPossibles(); |
foreach ($champs_recherches as $champ_recherche) { |
if ($this->verifierValiditeChamp($champ_recherche, $champs_possibles)) { |
$champ[] = (preg_match('/classe/', $champ_recherche)) ? 'classe_id' : $champ_recherche; |
} |
} |
} |
if (count($champ) == 1) { |
$champ = array(' * '); |
} |
return implode(', ', $champ); |
} |
public function rechercherChampsPossibles() { |
$this->recupererNomChamp($this->table); |
$champs_possibles = $this->champs_table; |
$champs_possibles[] = 'classe.id'; |
$champs_possibles[] = 'classe'; |
$champs_possibles[] = 'classe.href'; |
return $champs_possibles; |
} |
public function verifierValiditeChamp($champ, $champs_possibles) { |
$validite = false; |
preg_match('/^([^.]+)(:?\.([^.]+))?$/', $champ, $match); |
if (in_array($match[1], $champs_possibles)) { |
$validite = true; |
} else { |
$champs = implode('</li><li>', $champs_possibles); |
$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); |
} |
return $validite; |
} |
public function retournerRequeteCondition() { |
if($this->mesJoinsEtConditions) return $this->mesJoinsEtConditions; |
$condition = ''; |
if ($this->requete_condition !== null) { |
$condition = ' WHERE '.implode(' AND ', $this->requete_condition); |
} |
return $condition; |
} |
public function formerRequeteLimite() { |
$this->total_resultat = $this->recupererTotalResultat(); |
if (in_array($this->format_reponse , array('textes/id', 'textes/id/relations'))) { |
$this->requete_limite = ''; |
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat)) { |
$this->limite_requete['depart'] = |
(($this->total_resultat - $this->limite_requete['limite']) < 0) ? 0 : ($this->total_resultat - $this->limite_requete['limite']); |
$this->requete_limite = ' LIMIT '.$this->limite_requete['depart'].', '.$this->limite_requete['limite']; |
} else { |
$this->requete_limite = ' LIMIT '.$this->limite_requete['depart'].', '.$this->limite_requete['limite']; |
} |
return $this->requete_limite; |
} |
public function recupererTotalResultat() { |
//on récupère le nombre total de résultats de la requete (ex : le nombre d'id contenu dans la liste /ontologies) |
$requete = 'SELECT count(*) as nombre FROM ' |
.$this->table |
.$this->retournerRequeteCondition(); |
$res = $this->getBdd()->recuperer($requete); |
if ($res) { |
$total = $res['nombre']; |
} else { |
$e = 'Données introuvables dans la base'; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e); |
Debug::printr($requete); |
} |
return $total; |
} |
//+------------------------------------------------------------------------------------------------------+ |
public function retournerResultatFormate($resultat) { |
// determine en fct du service appelé (/ontologies | /ontologies/#id | /ontologies/#id/champ | |
// /ontologies/#id/relations) le format du tableau à retourner. Encode en json |
switch ($this->format_reponse) { |
case 'ontologies' : $reponse = $this->formaterOntologies($resultat); break; |
case 'ontologies/id' : $reponse = $this->formaterOntologiesId($resultat[0]); break; |
case 'ontologies/ids' : $reponse = $this->formaterMultipleOntologiesId($resultat); break; |
case 'ontologies/id/relations' : $reponse = $this->formaterOntologiesIdRelations($resultat); break; |
default : break; |
} |
return $reponse; |
} |
public function formaterOntologies($resultat) { |
$this->ajouterEnteteResultat($resultat); |
$table_retour_json['entete'] = $this->ajouterEnteteResultat($resultat); |
if (isset($this->parametres['masque_code']) || isset($this->parametres['masque'])) { |
$resultat = $this->trierRechercheFloue($this->parametres['masque_code'], $resultat, 'code'); |
} elseif (isset($this->parametres['masque_nom'])) { |
$resultat = $this->trierRechercheFloue($this->parametres['masque_nom'], $resultat, 'nom'); |
} elseif (isset($this->parametres['masque_description'])) { |
$resultat = $this->trierRechercheFloue($this->parametres['masque_description'], $resultat, 'description'); |
} |
//on remplit la table $table_retour_json['resultat'] |
foreach ($resultat as $tab) { |
$num = $tab['id']; |
unset($tab['id']); |
foreach ($tab as $param => $valeur) { |
$resultat_json[$num][$param] = $valeur; |
} |
if ($this->retour_format == 'max') $resultat_json[$num]['href'] = $this->ajouterHref('ontologies', $num); |
} |
$table_retour_json['resultat'] = $resultat_json; |
return $table_retour_json; |
} |
public function ajouterEnteteResultat($resultat) { |
//on remplit la table $table_retour_json['entete'] |
$entete['depart'] = $this->limite_requete['depart']; |
$entete['limite'] = $this->limite_requete['limite']; |
$entete['total'] = $this->total_resultat; |
//formuler les urls |
$url = $this->formulerUrl($this->total_resultat, '/ontologies'); |
if (isset($url['precedent']) && $url['precedent'] != '') { $entete['href.precedent'] = $url['precedent']; } |
if (isset($url['suivant']) && $url['suivant'] != '') { $entete['href.suivant'] = $url['suivant']; } |
return $entete; |
} |
public function __anonyme1($val) { return $val != ''; } |
public function formaterOntologiesId($resultat) { |
$table_retour = array_filter($resultat, array($this, '__anonyme1')); |
$this->calculerClassID($table_retour); |
return $table_retour; |
} |
public function formaterMultipleOntologiesId($resultats) { |
$result = Array(); |
foreach($resultats as $k => $resultat) { |
$id = $resultat['requete']; |
$result[$id] = array_filter($resultat, array($this, '__anonyme1')); |
unset($result[$id]['requete']); |
$this->calculerClassID($result[$id]); |
} |
return $result; |
} |
public function calculerClassID(&$resultat) { |
// commenté: pourquoi restreindre le choix des champs au format "max", |
// ça ne semble pas logique... |
// if ($this->retour_format != 'max') return; |
// question: pourquoi ne pas passer les infos relatives aux ontologies 0 ? |
// et que signifie ce commentaire: "pas de parent" |
if (@$resultat['classe_id'] == '0') return; |
$valeur = isset($resultat['classe_id']) ? $resultat['classe_id'] : $resultat['classe.id']; |
if(! isset($resultat['classe.id'])) { |
$resultat['classe.id'] = $resultat['classe_id']; |
unset($resultat['classe_id']); |
} |
// max-format et pas de champs spécifiques demandés ? |
// Alors on rempli "classe" et "classe.href" |
// Mais ne pas recalculer (surtout la classe) si ce n'est pas nécessaire |
// (c'est le cas si l'on a demandé plusieurs critère [provenons de formaterMultipleOntologiesId()]) |
if (! isset($this->parametres['retour_champs'])) { |
if(! isset($resultat['classe'])) { |
$nom_classe = $this->ajouterClasseCorrespondante($valeur); |
if (isset($nom_classe)) $resultat['classe'] = $nom_classe; |
} |
if(! isset($resultat['classe.href'])) { |
$resultat['classe.href'] = $this->ajouterHref('ontologies', $valeur); |
} |
return; |
} |
// cas où des champs sont demandés |
$champs = explode(',', $this->parametres['retour_champs']); |
if(in_array('classe', $champs) && ! isset($resultat['classe'])) { |
$this->ajouterClasseCorrespondante($valeur); |
} |
if(in_array('classe.id', $champs) && ! isset($resultat['classe.id'])) { |
$resultat['classe.id'] = $valeur; |
} |
if(in_array('classe.href', $champs) && ! isset($resultat['classe.href'])) { |
$resultat['classe.href'] = $this->ajouterHref('ontologies', $valeur); |
} |
if(in_array('classe.*', $champs) && (! isset($resultat['classe.href']) || ! isset($resultat['classe.id']))) { |
$resultat['classe.id'] = $valeur; |
$resultat['classe.href'] = $this->ajouterHref('ontologies', $valeur); |
} |
} |
/** Recherche par interrogation de la base, le nom de la classe à partir de son identifiant (classe.id) */ |
public function ajouterClasseCorrespondante($classe_id) { |
$nom = null; |
if ($classe_id != 0) { |
$nom = ''; |
$req = 'SELECT nom FROM '.$this->table.' WHERE id = '.$this->getBdd()->proteger($classe_id); |
$res = $this->getBdd()->recuperer($req); |
if ($res) { |
$nom = $res['nom']; |
} else { |
$e = "Données introuvables dans la table $this->table"; |
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e); |
Debug::printr($req); |
} |
} |
return $nom; |
} |
public function formaterOntologiesIdRelations($resultat) { |
$retour = null; |
if ($resultat != '') { |
$retour['entete'] = $this->ajouterEnteteResultat($resultat); |
//on remplit la table $table_retour_json['resultat'] |
foreach ($resultat as $tab) { |
$num = $tab['id']; |
$retour['resultat'][$num]['nom'] = $tab['nom']; |
if ($this->retour_format == 'max') { |
$retour['resultat'][$num]['href'] = $this->ajouterHref('ontologies', $num); |
} |
} |
} |
return $retour; |
} |
} |
?> |