Subversion Repositories eFlore/Projets.eflore-projets

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1172 → Rev 1174

/tags/v5.12-baouque/services/apidoc-header.md
New file
0,0 → 1,4
Autres API :
- [CEL](http://tela-botanica.net/doc/services/cel/)
- [COEL](http://tela-botanica.net/doc/services/coel/)
- [DEL](http://tela-botanica.net/doc/services/del/)
/tags/v5.12-baouque/services/apidoc.json
New file
0,0 → 1,18
{
"name": "eFlore",
"version": "0.1",
"description": "Documentation des web services d'eFlore",
"title": "eFlore - API",
"url" : "http://api.tela-botanica.org/service:eflore:0.1",
"template": {
"withCompare": false,
"withGenerator": true
},
"header": {
"title": "eFlore",
"filename": "apidoc-header.md"
},
"footer": {
"filename": "apidoc-footer.md"
}
}
/tags/v5.12-baouque/services/modules/0.1/commun/Commun.php
New file
0,0 → 1,600
<?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;
 
/** par défaut : configuration du projet, section [NomDuService] */
protected $config;
 
/** 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();
 
public function __construct($bdd = null, $config = null) {
$this->Bdd = is_null($bdd) ? $this->getBdd() : $bdd;
$this->config = is_null($config) ? Config::get($this->serviceNom) : $config;
$this->init();
}
 
// ajustements post-constructeur
protected function init() {}
 
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
/tags/v5.12-baouque/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);
}
}
 
?>
/tags/v5.12-baouque/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&param2=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'];
}
}
/tags/v5.12-baouque/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&param2=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;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtre/CommunNomsTaxons.php
New file
0,0 → 1,932
<?php
// declare(encoding='UTF-8');
/**
* Description :
* Classe CommunNomsTaxons.php
* 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-2011 Tela Botanica (accueil@tela-botanica.org)
*/
 
 
abstract class CommunNomsTaxons extends Commun {
 
/** Tableau de correspondance entre les noms des champs et les codes de l'ontologie.*/
private $relationsChampsCodesOntologie = null;
protected $table_retour; //Permet de stocker le tableau de résultat (non encodé en json)
protected $resultat_req; // Permet de stocker le résultat de la requete principale.
protected $compo_nom = null; //Stocke sous forme de tableau les composant du nom à ajouter au nom scientifique
protected $table;// Nom de la table dans laquelle on récupèrera les données dans les requetes SQL
protected $total_resultat = null;
/** Stocke le service appelé correspondant. Est utilisé principalement lors de l'affichage du href d'un synonyme
(ex id=12, basionyme num 25 est un synonyme) dans le service taxon */
protected $service_href = null;
protected $erreursParametres = null;
protected $sans_nom_sci = array('gen','sp','ssp','fam','au_ss','bib_ss');
private $bib_traitees = array();
private $ontologie = array();
 
//+------------------------------- PARAMÈTRES ---------------------------------------------------------------+
 
public function traiterParametres() {
$this->definirParametresParDefaut();
$this->verifierParametres();
 
if (isset($this->parametres) && count($this->parametres) > 0) {
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'ns.structure' :
$this->remplirTableCompositionNom($val);
if (in_array($val,$this->sans_nom_sci)){
$this->requete_champ = implode(', ',$this->compo_nom);
}else {
$this->requete_champ .= ' ,'.implode(', ',$this->compo_nom);
}
break;
case 'navigation.depart' :
$this->limite_requete['depart'] = $val;
break;
case 'navigation.limite' :
$this->limite_requete['limite'] = $val;
break;
}
}
$this->traiterParametresSpecifiques();
}
}
 
protected function definirParametresParDefaut() {
if (empty($this->parametres['recherche'])) {
$this->parametres['recherche'] = 'stricte';
}
if (empty($this->parametres['ns.format'])) {
$this->parametres['ns.format'] = 'txt';
}
if (empty($this->parametres['retour.format'])) {
$this->parametres['retour.format'] = 'max';
}
if (empty($this->parametres['ns.structure']) &&
$this->parametres['retour.format'] != 'oss') {
$this->parametres['ns.structure'] = 'au,an,bib';
}
}
 
 
public function verifierParametres() {
//$this->verifierParametresAPI();
 
$this->verifierParametre('recherche', 'stricte|floue|etendue|complete');
$this->verifierParametre('ns.format', 'htm|txt');
$this->verifierParametre('retour.format', 'min|max|oss|perso');
$this->verifierParametreAvecValeurMultipe('ns.structure', 'an|au|bib|ad|gen|sp|ssp|fam|au_ss|bib_ss');
 
/*if (count($this->erreursParametres) > 0) {
$m = 'Erreur dans votre requête : '.implode('<br/>', $this->erreursParametres);
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}*/
}
 
public function verifierParametresAPI() {
$parametresApi = $this->recupererTableauConfig('parametresAPI');
while (!is_null($parametre = key($this->parametres))) {
if (!in_array($parametre, $parametresApi)) {
$this->erreursParametres[] = "Le paramètre '$parametre' n'est pas pris en compte par cette version de l'API.";
}
next($this->parametres);
}
}
 
public function verifierParametre($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeur = $this->parametres[$parametre];
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
 
public function verifierParametreAvecValeurMultipe($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeursConcatenees = $this->parametres[$parametre];
$valeurs = explode(',', $valeursConcatenees);
foreach ($valeurs as $valeur) {
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
}
 
private function verifierValeursPermises($parametre, $valeur, $valeursPermises) {
if (!in_array($valeur, explode('|', $valeursPermises))) {
$this->erreursParametres[] = "Le paramètre '$parametre' ne peut pas prendre la valeur '$valeur'. Valeurs permises : $valeursPermises";
}
}
 
public function traiterParametresCommuns() {
 
}
 
public function ajouterFiltreMasque($nom_champ, $valeur) {
$valeur = explode(',',$valeur);
$conditions = array();
if ($nom_champ == 'annee' || $nom_champ == 'rang') {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ = ".$this->getBdd()->proteger($val);
}
} else {
if ($this->parametres['recherche'] == 'etendue') {
foreach ($valeur as $val) {
$val = $this->modifierValeur($val);
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
 
} elseif ($this->parametres['recherche'] == 'floue') {
foreach ($valeur as $val) {
$val = $this->getBdd()->proteger($val);
$conditions[] = "( SOUNDEX($nom_champ) = SOUNDEX($val))".
" OR ( SOUNDEX(REVERSE($nom_champ)) = SOUNDEX(REVERSE($val)))";
}
} else {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
}
}
$this->requete_condition[]= '('.implode(' OR ', $conditions ).')';
$this->masque[$nom_champ] = $nom_champ.'='.implode(',',$valeur);
}
 
private function modifierValeur($valeur) {
$valeur = $this->remplacerCaractereHybrideEtChimere($valeur);
$valeur = $this->preparerChainePourRechercheEtendue($valeur);
return $valeur;
}
 
private function remplacerCaractereHybrideEtChimere($valeur) {
$caracteres = array('×', '%D7', '+', '%2B');
$remplacements = array('x ','x ', '+', '+');
$valeur = str_replace($caracteres, $remplacements, $valeur);
return $valeur;
}
 
private function preparerChainePourRechercheEtendue($valeur) {
$valeur = str_replace(' ', '% ', trim($valeur));
$valeur = $valeur.'%';
return $valeur;
}
 
//+-------------------------------Fonctions d'analyse des ressources-------------------------------------+
 
private function etreRessourceId() {
$ok = false;
if ($this->estUnIdentifiant() && count($this->ressources) == 1) {
$ok = true;
}
return $ok;
}
 
public function traiterRessources() {
if (isset($this->ressources) && count($this->ressources) > 0) {
if ($this->ressources[0] == 'relations') {
$this->traiterRessourceIdRelations();
} elseif ($this->estUnIdentifiant()) { //l'identifiant peut etre de type /#id ou /nt:#id
$this->traiterRessourcesIdentifiant(); // dans le service noms ou taxons
} elseif ($this->ressources[0] == 'stats') { //ressource = noms/stats
$this->traiterRessourcesStats();
} else {
$e = 'Erreur dans votre requete </br> Ressources disponibles : <br/>
<li> /'.$this->service.'/#id (id : L\'identifiant du nom rechercher)</li>
<li> /'.$this->service.'/nt:#id (id : Numero du taxon recherche)</li>
<li> /'.$this->service.'/stats </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
}
 
public function traiterRessourcesStats() {
$this->format_reponse = $this->service.'/stats';
 
$e = "Erreur dans votre requête </br> Ressources disponibles : $this->service/stats/[annees|rangs|initiales]";
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
switch ($this->ressources[1]) {
case 'annees' :
$this->traiterRessourceStatsAnnees();
break;
case 'rangs' :
$this->traiterRessourceStatsRangs();
break;
case 'initiales' :
$this->traiterRessourceStatsInitiales();
break;
default :
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
} else {
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
/** Vérifie si la première valeur de la table de ressource est un identifiant :
* un numerique ou un numéro taxonomique sous la forme nt:xx */
public function estUnIdentifiant() {
return (is_numeric($this->ressources[0]) || (strrpos($this->ressources[0],'nt:') !== false
&& is_numeric(str_replace('nt:','',$this->ressources[0]))));
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonction d'analyse des parametres
 
/** Permet de remplir le tableau compo_nom. Il comprendra en fct du paramètre ns.structure les éléments à rajouter
* au nom_sci (annee, auteur, biblio ou addendum). */
public function remplirTableCompositionNom($valeur) {
$structure_nom = explode(',', $valeur);
foreach ($structure_nom as $structure) {
$structure = trim($structure);
$patterns = array('/^an$/', '/^au$/', '/^bib$/', '/^ad$/', '/^sp$/', '/^gen$/', '/^ssp$/','/^fam$/',
'/^au_ss$/','/^bib_ss$/');
$champs = array('annee', 'auteur', 'biblio_origine', 'nom_addendum', 'epithete_sp', 'genre',
'epithete_infra_sp','famille','auteur', 'biblio_origine');
 
// avec str_replace() 'sp' est inclu dans 'ssp', et la conversion pour 'ssp' est mauvaise
$this->compo_nom[$structure] = preg_replace($patterns, $champs, $structure);
}
}
 
public function mettreAuFormat() {
if ($this->parametres['ns.format'] == 'htm') {
if (strrpos($this->requete_champ, 'nom_sci_html as nom_sci') === false) {
$this->requete_champ = str_replace('nom_sci', 'nom_sci_html as nom_sci', $this->requete_champ);
}
}
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonctions de formatage
 
/** 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. */
public function recupererTableSignification($table) {
$tables = explode(',', $table);
foreach ($tables as $tab) {
if ($tab == 'champs_comp') {
$champ_bdnff_api = array_keys($this->champs_api); //on recupère le nom des champ ds la bdd
$this->champs_comp = array_diff($this->champs_table, $champ_bdnff_api);
} elseif ($tab == 'champs_api') {
foreach ($this->correspondance_champs as $key => $val) {
preg_match('/(hybride[.]parent_0[12](?:[.]notes)?|nom_sci[.][^.]+|[^.]+)(?:[.](id|code))?/', $val, $match);
$val = $match[1];
$this->champs_api[$key] = $val;
}
} else {
$this->$tab = $this->recupererTableauConfig($tab);
}
}
}
 
public function formaterEnOss($resultat) {
$table_nom = array();
$oss = '';
foreach ($resultat as $tab) {
if (isset($tab['nom_sci']) ) {
if (!in_array($tab['nom_sci'], $table_nom)) {
$table_nom[] = $tab['nom_sci'];
$oss[] = $tab['nom_sci'].' '.$this->ajouterCompositionNom($tab);
}
}else {
$res = $this->ajouterCompositionNom($tab);
if($res) {
$oss[] = $res;
}
}
 
}
 
if (isset($this->masque)) $masque = implode('&', $this->masque);
else $masque = 'Pas de masque';
$table_retour_oss = array($masque, $oss);
return $table_retour_oss;
}
 
public function afficherEnteteResultat($url_service) {
$this->table_retour['depart'] = $this->limite_requete['depart'];
$this->table_retour['limite'] = $this->limite_requete['limite'];
$this->table_retour['total'] = $this->total_resultat;
$url = $this->formulerUrl($this->total_resultat, $url_service);
if (isset($url['precedent']) && $url['precedent'] != '') {
$this->table_retour['href.precedent'] = $url['precedent'];
}
if (isset($url['suivant']) && $url['suivant'] != '') {
$this->table_retour['href.suivant'] = $url['suivant'];
}
}
 
public function afficherNomHrefRetenu($tab, $num) {
$this->resultat_req = $tab;
$this->afficherDonnees('num_nom', $num);
if ($this->parametres['retour.format'] == 'min') { // sinon est affiché ds afficherDonnees(num_nom, $val) ci-dessus
$this->table_retour['nom_sci'] = $tab['nom_sci'];
$this->table_retour['nom_sci_complet'] = $tab['nom_sci'].' '.$this->ajouterCompositionNom($tab);
}
if ($tab['num_nom_retenu'] != '') {
$retenu = ($tab['num_nom_retenu'] == $num) ? 'true' : 'false';
} else {
$retenu = 'absent';
}
$this->table_retour['retenu'] = $retenu;
unset($this->table_retour['id']);
}
 
 
//+------------------------------------------------------------------------------------------------------+
// Fonction de formatage pour les services /#id/
 
public function formaterId($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
 
foreach ($resultat as $cle => $valeur) {
if ($valeur != '') {
$this->afficherDonnees($cle, $valeur);
}
}
if (isset($this->parametres['retour.champs']) && $this->format_reponse == 'noms/id') {
$retour = $this->table_retour;
$this->table_retour = array();
$champs = explode(',', $this->parametres['retour.champs']);
$this->ajouterChampsPersonnalises($champs, $retour);
}
unset($this->table_retour['href']);
return $this->table_retour;
}
 
public function formaterIdChamp($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$reponse_id = $this->formaterId($resultat);
$this->table_retour = array();
$champs = explode(' ', $this->ressources[1]);
$this->ajouterChampsPersonnalises($champs, $reponse_id);
return $this->table_retour;
}
 
protected function ajouterChampsPersonnalises($champs, $reponse_id) {
$champs_a_libeller = array('nom_retenu', 'rang', 'basionyme', 'hybride', 'hybride.parent_01',
'hybride.parent_02', 'presence', 'tax_sup', 'statut_origine', 'statut_culture', 'statut_introduction');
$champs_forces = array('rang'); // même s'ils sont dans "à libeller", on les prend quand même en brut, en plus
if (! is_null($champs) && is_array($champs) && count($champs) > 0) {
foreach ($champs as $champ) {
if ($this->verifierValiditeChamp($champ)) {
if (strrpos($champ, '.*') !== false) {
$this->afficherPointEtoile($champ, $reponse_id);
} elseif (in_array($champ, $champs_a_libeller)) {
$this->table_retour[$champ.'.libelle'] =
(isset($reponse_id[$champ.'.libelle'])) ? $reponse_id[$champ.'.libelle'] : null;
} else {
$champ = $this->trouverChampBddCorrespondant($champ);
$this->table_retour[$champ] = (isset($reponse_id[$champ])) ? $reponse_id[$champ] : null;
}
// champs bruts en plus, ajouté pour obtenir le rang, mais retourne rang.code avec du kk dedans :-/
if (in_array($champ, $champs_forces)) {
$champ = $this->trouverChampBddCorrespondant($champ);
$this->table_retour[$champ] = (isset($reponse_id[$champ])) ? $reponse_id[$champ] : null;
}
}
}
}
}
 
public function afficherPointEtoile($champ, $reponse) {
preg_match('/^([^.]+\.)\*$/', $champ, $match);
if ($match[1] == 'nom_sci') {
$this->afficherNomSciPointEpithete($this->resultat_req);
} else {
foreach ($reponse as $chp => $valeur) {
if (strrpos($chp, $match[1]) !== false) {
if ($valeur != '') {
$this->table_retour[$chp] = $valeur;
} else {
$this->table_retour[$chp] = null;
}
}
}
}
}
 
public function decomposerNomChamp($champ) {
$decomposition = false;
if (preg_match('/^(?:([^.]+\.parent_0[12]|[^.]+))(?:\.(.+))?$/', $champ, $match)) {
$radical_champ = $match[1];
$suffixe = (isset($match[2])) ? $match[2] : "";
$decomposition = array($radical_champ, $suffixe);
}
return $decomposition;
}
 
public function verifierValiditeChamp($champ) {
$decomposition = $this->decomposerNomChamp($champ);
$validite_ressource = true;
if ($decomposition) {
list($radical, $suffixe) = $decomposition;
$champs_complementaire = array('nom_retenu_complet', 'basionyme_complet');
// on verifie si le nom du champ existe bien
if (!$this->estChampApi($radical) && !$this->estChampComplementaire($radical)) {
if (!in_array($radical, $champs_complementaire)) {
$validite_ressource = false;
$e = 'Le champ "'.$radical.'" n\'existe pas dans la base. <br/><br/>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} elseif ($this->estUnPoint($champ)) {
$validite_ressource = $this->verifierValiditeSuffixe($suffixe, $radical);
}
}
return $validite_ressource;
}
 
public function estChampApi($radical_champ) {
$champ_api_ok = false;
if (in_array($radical_champ, $this->champs_api) || in_array($radical_champ, $this->correspondance_champs)) {
$champ_api_ok = true;
}
return $champ_api_ok;
}
 
public function estChampComplementaire($radical_champ) {
$champ_complementaire_ok = in_array($radical_champ, $this->champs_comp) ? true : false;
return $champ_complementaire_ok;
}
 
public function verifierValiditeSuffixe($suffixe, $radical_champ) {
$validite_ressource = true;
if ($this->correspondAUnId($radical_champ) || $radical_champ == 'id') {
$this->verificationSuffixesIdentifiant($suffixe, $radical_champ, $validite_ressource);
} elseif ($this->correspondAUnCode($radical_champ)) {
$this->verificationSuffixesCodes($suffixe, $radical_champ, $validite_ressource);
} elseif ($radical_champ == 'nom_sci') {
if ($suffixe != '*') {
$validite_ressource = false;
$m = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/>
Les suffixes possibles sont les suivants : <li> * </li>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
} else {
$validite_ressource = false;
$m = 'Erreur : Le paramètre "'.$radical_champ.'" ne peut pas présenter de suffixe. <br/><br/>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
return $validite_ressource;
}
 
public function verificationSuffixesCodes(&$suffixe, &$radical_champ, &$validite_ressource ) {
if (!in_array($suffixe, array('*', 'code', 'href', 'details'))) {
$validite_ressource = false;
$e = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'.<br/> Les suffixes '
.'possibles sont les suivants : <li> .* </li><li> .code </li><li> .href </li><li> .details </li>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
public function verificationSuffixesIdentifiant(&$suffixe, &$radical_champ, &$validite_ressource) {
if ((strrpos($radical_champ, 'parent') !== false && !in_array($suffixe, array('*', 'id', 'href', 'details', 'notes')))
|| !in_array($suffixe, array('*', 'id', 'href', 'details')) && strrpos($radical_champ, 'parent') === false) {
$validite_ressource = false;
$e = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/> Les suffixes '
.'possibles sont les suivants : <li> .* </li><li> .id </li><li> .href </li><li> .details </li>'
.'<li> .notes (seulement pour les hybride.parent)';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
 
//------------------------------fonction de formatage pour les services /stats/-----------------------------------------
 
public function formaterStatsAnnee($resultat) {
foreach ($resultat as $cle_annee) {
$annee = ($cle_annee['annee'] != '') ? $cle_annee['annee'] : 'ND';
$nb = $cle_annee['nombre'];
$retour_stats_annee[$annee] = $nb;
}
return $retour_stats_annee;
}
 
public function formaterStatsRang($resultat) {
foreach ($resultat as $rangs) {
if ($rangs['rang'] != 0) {
$rang = $rangs['rang'];
if ($this->parametres['retour.format'] == 'max') {
$retour_rang[$rang]['rang'] = $this->ajouterSignificationCode('rang',$rang);
}
$nombre = $rangs['nombre'];
$retour_rang[$rang]['nombre'] = $nombre;
}
}
return $retour_rang;
}
 
public function formaterStatsInitiales($resultat) {
$rang = null;
$table_rang = array();
foreach ($resultat as $tuple) {
if ($tuple['rang'] != 0) {
$this->memoriserRang($table_rang, $tuple, $rang);
if ($tuple['lettre'] == 'x ') {
$this->ajouterHybrideChimere('hybride', $rang, $tuple);
} elseif ($tuple['lettre'] == '+ ') {
$this->ajouterHybrideChimere('chimere', $rang, $tuple);
} else {
$l = substr($tuple['lettre'], 0, 1);
if (isset($this->table_retour[$rang][$l])) {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] += floatval($tuple['nb']);
} else {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] = floatval($tuple['nb']);
}
}
}
}
return $this->table_retour;
}
 
public function memoriserRang(&$table_rang, $tuple, &$rang) {
if (is_array($table_rang)) {
if (!in_array($tuple['rang'], $table_rang)) {
$rang = $tuple['rang'];
$table_rang[] = $rang;
if ($this->parametres['retour.format'] == 'max') {
$rang = $this->ajouterSignificationCode('rang', $rang);
}
}
}
}
 
public function ajouterHybrideChimere($groupe, &$rang, &$tuple) {
if (isset($this->table_retour[$rang][str_replace('hybride', 'hyb', $groupe)])) {
$this->table_retour[$rang][$groupe] += floatval($tuple['nb']);
} else {
$this->table_retour[$rang][$groupe] = floatval($tuple['nb']);
}
}
 
//-----------------------------Fonctions d'affichage utiliser dans les fonctions de formatage---------------------------
 
public function afficherDonnees($champApi, $valeur) {
$champBdd = $this->trouverChampBddCorrespondant($champApi);
if ($this->parametres['retour.format'] == 'min') {
if ($champApi == 'nom_sci') {
$valeur = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req);
}
if ($champApi == 'nom_sci_html') {
$valeur = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req, 'htm');
}
$this->table_retour[$champBdd] = $valeur;
} else {
$this->afficherToutesLesInfos($champBdd, $valeur);
}
}
 
public function trouverChampBddCorrespondant($champApi) {
if (array_key_exists($champApi, $this->champs_api)) {
$champBdd = $this->correspondance_champs[$champApi];
} else {
$champBdd = $champApi;
}
return $champBdd;
}
 
public function afficherToutesLesInfos($nom_champ_api, $valeur) {
if ($this->presentePlusieursId($nom_champ_api, $valeur)) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'details', $valeur);
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif (strrpos($nom_champ_api, 'parent') !== false && strrpos($nom_champ_api, 'notes') !== false) {
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif (($this->correspondAUnId($nom_champ_api) || $nom_champ_api == 'id' && $valeur != '0')) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'id,signification,href', $valeur);
 
} elseif ($this->correspondAUnCode($nom_champ_api)) {
preg_match('/^([^.]+)(?:\.code)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'code,signification,href', $valeur);
 
} elseif ($nom_champ_api == 'nom_sci_html') {
$this->table_retour['nom_sci_html'] = $valeur;
$this->table_retour['nom_sci_html_complet'] = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req, 'htm');
}elseif ($nom_champ_api != 'nom_sci') {
$this->table_retour[$nom_champ_api] = $valeur;
}
}
 
public function presentePlusieursId($ressource, $valeur = null) {
if ($valeur) {
$presente = strrpos($ressource, 'proparte') !== false && strrpos($valeur, ',') !== false;
} else { //pour la vérification du champ, on ignore alors la valeur de la ressource
$presente = strrpos($ressource, 'proparte') !== false;
}
return $presente;
}
 
public function afficherInfosPrecises($champ, $suffixe, $valeur) {
$suffixes = explode(',', $suffixe);
//on initialise au service appelé. Sera potentiellement modifié dans la fonction afficherSignification()
$this->service_href = $this->service;
foreach ($suffixes as $suffixe) {
switch ($suffixe) {
case 'id' :
$this->table_retour[str_replace('id.id', 'id', $champ.'.id')] = $valeur;
break;
case 'details' :
$this->afficherTableDetails($champ, $valeur);
break;
case 'signification' :
$this->afficherSignification($champ, $valeur);
break;
case 'href' :
$url = $this->creerUrl($champ, $valeur);
$this->table_retour[str_replace('id.href', 'href', $champ.'.href')] = $url;
break;
case 'code' :
$this->table_retour[$champ.'.code'] = $this->obtenirCode($champ, $valeur);
break;
case 'notes' :
$this->table_retour[$champ.'.notes'] = $this->resultat_req[str_replace('.', '_', $champ).'_notes'];
break;
default : break;
}
}
}
 
public function afficherTableDetails($nom_champ_api, $valeur) {
$tab_id = explode(',', $valeur);
$tab_res = $this->table_retour;
$this->table_retour = array();
foreach ($tab_id as $id) {
$this->afficherInfosPrecises($nom_champ_api, 'id,signification,href', $id);
$tab_res[$nom_champ_api.'.details'][] = $this->table_retour;
$this->table_retour = array();
}
$this->table_retour = $tab_res;
}
 
private function obtenirCode($champ, $valeur) {
$code = $this->transformerChampEnCode($champ);
return "bdnt.$code:$valeur";
}
 
private function transformerChampEnCode($champ) {
if (is_null($this->relationsChampsCodesOntologie)) {
$this->relationsChampsCodesOntologie = Outils::recupererTableauConfig('ChampsCodesOntologie');
}
 
$code = $champ;
if (array_key_exists($champ, $this->relationsChampsCodesOntologie)) {
$code = $this->relationsChampsCodesOntologie[$champ];
}
return $code;
}
 
public function creerUrl($champ, $valeur) {
if ($this->correspondAUnId($champ) || $champ == 'id') {
$service = $this->service_href;
$url = $this->ajouterHref($service, $valeur);
} else {
$code = $this->transformerChampEnCode($champ);
$url = $this->ajouterHrefAutreProjet('ontologies', "$code:", $valeur, 'bdnt');
}
return $url;
}
 
public function afficherSignification($champ, $valeur) {
if ($champ == 'id' && isset($this->resultat_req['nom_sci']) && $this->resultat_req['num_nom'] == $valeur) {
//si le nom_sci du num_nom que l'on veut afficher est déjà dans la table de résultat :
$this->table_retour['nom_sci'] = $this->resultat_req['nom_sci'];
$this->table_retour['nom_sci_complet'] = $this->resultat_req['nom_sci'].' '.
$this->ajouterCompositionNom($this->resultat_req);
} elseif ($this->correspondAUnId($champ) || $champ == 'id') {
$nom = $this->recupererNomSci($valeur);
if ($nom != array()) {
$this->table_retour[$champ.'.libelle'] = $nom['nom_sci'];
$this->table_retour[$champ.'_html'] = $nom['nom_sci_html'];
$this->table_retour[$champ.'_complet'] = $nom['nom_sci_complet'];
$this->table_retour[$champ.'_html_complet'] = $nom['nom_sci_complet_html'];
$this->service_href = $nom['service'];
}
} elseif ($this->correspondAUnCode($champ)) {
$this->table_retour[$champ.'.libelle'] = $this->ajouterSignificationCode($champ, $valeur);
}
}
 
/** Permet d'afficher les élements nomenclatural du nom_sci lors de l'appel dans le service noms/id/champ du champ^nom_sci.*/
public function afficherNomSciPointEpithete($resultat) {
$tab_nom_sci = array('nom_supra_generique', 'genre', 'epithete_infra_generique', 'epithete_sp',
'type_epithete', 'epithete_infra_sp', 'cultivar_groupe', 'cultivar', 'nom_commercial');
foreach ($tab_nom_sci as $compo_nom) {
if (isset($resultat[$compo_nom]) && !empty($resultat[$compo_nom])) {
$this->table_retour['nom_sci.'.$compo_nom] = $resultat[$compo_nom];
}
}
}
 
public function ajouterSignificationCode($champ, $valeur) {
if($this->termeOntologieEstEnCache($champ, $valeur)) {
$nom_code = $this->obtenirTermeOntologieParCache($champ, $valeur);
} else {
$code = $this->transformerChampEnCode($champ);
if (preg_match('/^([^_-]+)(?:_|-)([^_-]+)$/', $code, $match)) {
$code = $match[1].ucfirst($match[2]);
}
$url = Config::get('url_ontologie').$code.':'.$valeur.'/nom';
try {
$res = $this->consulterHref($url); //dans commun.php
$nom_code = $valeur;
if (is_object($res)) {
$nom_code = $res->nom;
}
$this->mettreEnCacheOntologie($champ, $valeur, $nom_code);
} catch (Exception $e) {
$nom_code = '';
}
}
return $nom_code;
}
 
public function recupererNomSci($id) {
$nom = array();
if ($id != 0) {
if ($this->compo_nom == null) {
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html FROM '.$this->table.' WHERE num_nom = '.$id;
} else { //on ajoute à la requete sql, les champs de ns.structure
//print_r($this->compo_nom);
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html, '.implode(', ', $this->compo_nom)
.' FROM '.$this->table
.' WHERE num_nom = '.$id;
}
if ($this->parametres['ns.format'] == 'htm') {
$req = str_replace('nom_sci', 'nom_sci_html as nom_sci', $req);
}
$res = $this->getBdd()->recuperer($req);
if ($res) {
$nom['nom_sci'] = $res['nom_sci'];
$nom['nom_sci_html'] = $res['nom_sci_html'];
$nom['nom_sci_complet'] = $res['nom_sci'].' '.$this->ajouterCompositionNom($res);
$nom['nom_sci_complet_html'] = $res['nom_sci_html'].' '.$this->ajouterCompositionNom($res, 'htm');
$nom['service'] = ($res['num_nom_retenu'] == $id && $this->service == 'taxons') ? 'taxons' : 'noms';
}
}
return $nom;
}
 
/** Permet de retourner une chaine de caractère composée des parametres du nom (ns.structure : annnée, auteur,
* bibilio et addendum). A ajouter au nom scientifique */
public function ajouterCompositionNom($tab_res, $format = '') {
$format = ($format == '') ? $this->parametres['ns.format'] : $format;
 
$nom = '';
if (isset($this->compo_nom)) {
if ($format == 'htm') {
$format = array(
'au' => '<span class="auteur">%s</span>',
'an' => '[<span class="annee">%s</span>]',
'an_bib' => '[<span class="annee">%s</span>, <span class="biblio">%s</span>]',
'bib' => '[<span class="biblio">%s</span>]',
'ad' => '[<span class="adendum">%s</span>]');
} else {
$format = array(
'au' => '%s',
'an' => '[%s]',
'an_bib' => '[%s, %s]',
'bib' => '[%s]',
'ad' => '[%s]',
'gen' => '%s',
'sp' => '%s',
'ssp' => '%s',
'fam' => '%s',
'au_ss' => '%s',
'bib_ss' => '%s');
}
$compo_nom = array();
 
foreach ($this->compo_nom as $key => $champ) {
if (isset($tab_res[$champ]) && !empty($tab_res[$champ])) {
$compo_nom[$key] = $tab_res[$champ];
}
}
$nom_complet = $this->formerNomComplet($compo_nom, $format);
$nom = implode(' ', $nom_complet);
}
return rtrim($nom, ' ');
}
 
 
public function formerNomComplet($compo_nom, $format) {
$nom_complet = array();
extract($compo_nom);
if (isset($au)) $nom_complet[] = sprintf($format['au'], $au);
if (isset($an)) {
if (isset($bib)) {
$nom_complet[] = sprintf($format['an_bib'], $an, $bib);
} else {
$nom_complet[] = sprintf($format['an'], $an);
}
} elseif (isset($bib)) {
$nom_complet[] = sprintf($format['bib'], $bib);
}
if (isset($ad)) $nom_complet[] = sprintf($format['ad'], $ad);
if (isset($gen)) $nom_complet[] = sprintf($format['gen'], $gen);
if (isset($ssp)) $nom_complet[] = sprintf($format['ssp'], $ssp);
if (isset($sp)) $nom_complet[] = sprintf($format['sp'], $sp);
if (isset($fam)) $nom_complet[] = sprintf($format['fam'], $fam);
if (isset($au_ss)) $nom_complet[] = sprintf($format['au_ss'], $au_ss);
if (isset($bib_ss)) {
$bibl = $this->tronquerBiblio($bib_ss);
//simule un 'select distinct' sur les biblio tronquées
if (!isset($this->bib_traitees[$bibl])) {
$nom_complet[] = sprintf($format['bib_ss'],$bibl );
$this->bib_traitees[$bibl] = 1;
}
}
return $nom_complet;
}
 
public function tronquerBiblio($valeur){
$bib = '';
if(strpos($valeur,',') !== false) {
$bib = explode(',',$valeur);
}
if(strpos($bib[0],';') !== false) {
 
$bib[0] = strstr($bib[0],';');
$bib[0] = str_replace('; ','',$bib[0]);
}
return $bib[0];
}
 
 
 
public function correspondAUnCode($key) {
return (strrpos($key, '.code') !== false) || (in_array($key.'.code', $this->correspondance_champs));
}
 
public function correspondAUnId($key) {
return (strrpos($key, '.id') !== false) || (in_array($key.'.id', $this->correspondance_champs));
}
 
public function estUnPoint($key) {
if (strrpos($key, 'hybride.parent') !== false) {
$key = str_replace('hybride.parent', 'hybride_parent', $key);
}
return (strrpos($key, '.') !== false);
}
 
public function recupererMasquePrincipal() {
$masque = null;
$tab_masque = array(
'masque' => 'nom_sci',
'masque_sg' => 'nom_supra_generique',
'masque_gen' => 'genre',
'masque_sp' => 'epithete_sp',
'masque_ssp' => 'epithete_infra_sp',
'masque_au' => 'auteur',
'masque_an' => 'annee',
'masque_bib' => 'biblio_origine',
'masque_ad' => 'addendum',
'masque_rg' => 'rang');
$liste_masque = array();
 
if (isset($this->masque['num_nom'])) {
$liste_masque[] = $this->masque['num_nom'];
}
 
foreach ($tab_masque as $key => $filtre) {
if (isset($this->masque[$filtre])) {
if (!isset($masque) && !in_array($filtre, array('rang', 'annee'))) {
$masque = array($key, $filtre);
}
$liste_masque[] = $this->masque[$filtre];
}
}
$this->masque = $liste_masque;
return $masque;
}
 
private function mettreEnCacheOntologie($categorie, $valeur, $correspondance) {
if(!isset($this->ontologie[$categorie])) {
$this->ontologie[$categorie] = array();
}
if(!isset($this->ontologie[$categorie][$valeur])) {
$this->ontologie[$categorie][$valeur] = array();
}
$this->ontologie[$categorie][$valeur] = $correspondance;
}
 
private function termeOntologieEstEnCache($categorie, $valeur) {
return array_key_exists($categorie, $this->ontologie) && array_key_exists($valeur, $this->ontologie[$categorie]);
}
 
private function obtenirTermeOntologieParCache($categorie, $valeur) {
return $this->ontologie[$categorie][$valeur];
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtre/Noms.php
New file
0,0 → 1,733
<?php
// declare(encoding='UTF-8');
/**
* Classe permettant de fournir des informations sur les noms scientifiques.
* Si l'url finit par /noms on retourne une liste de noms latin et leurs identifiants (seulement les 100 premeiers noms par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /noms?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, masque.gen (nom de genre), masque.sp (épithète d'espèce), masque.ssp (épithète infra-spécifique),
* masque.au (auteur du nom), masque.an (année de publication du nom), masque.bib (réf biblio de la publi d'origine du nom), masque.ad (nomen addendum),
* masque.nn (identifiant du nom), recherche, rang, distinct, retour.format, nl.format, nl.structure, navigation.depart et navigation.limite.
* Les différentes requetes :
* - noms | noms/relations/#projet/#id_projet | noms/#id | noms/#id/#champ+#champ
* - noms/#id/relations | noms/#id/relations/synonymie | noms/#id/relations/homonymie | noms/#id/relations/flores
* - noms/stats/rangs | noms/stats/annees | noms/stats/initiales
*
* @package bdtfx
* @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 $Id$
* @copyright 1999-2011 Tela Botanica (accueil@tela-botanica.org)
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Noms
*/
 
class Noms extends CommunNomsTaxons {
 
protected $format_reponse = 'noms'; // Permet de stocker la requete formulée
protected $service = 'noms';
protected $serviceNom = 'noms';
protected $requete_champ = 'num_nom, nom_sci, num_nom_retenu';
protected $requete_condition = null;
protected $requete_group_by = '';
/** Permet de stocker les limite de la requete SQL (par défaut seul les 100 premiers résultats seront retournés).*/
protected $limite_requete = array('depart' => 0, 'limite' => 100);
protected $distinct = null; // Valeur du paramètre de requete distinct (=0|1)
 
public function consulter($ressources, $parametres) {
return parent::consulter($ressources, $parametres);
}
 
//+----------------FONCTION D'ANALYSE DES PARAMETRES---------------------------------------------------------+
 
public function traiterParametresSpecifiques() {
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'masque' :
$champ = isset($this->parametres['recherche']) && ($this->parametres['recherche'] == 'etendue') ?
'CONCAT(nom_sci," ",auteur)' : 'nom_sci';
$this->ajouterFiltreMasque($champ, $val);
break;
case 'masque.sg' :
$this->ajouterFiltreMasque('nom_supra_generique', $val);
break;
case 'masque.gen' :
$this->ajouterFiltreMasque('genre', $val);
break;
case 'masque.sp' :
$this->ajouterFiltreMasque('epithete_sp', $val);
break;
case 'masque.ssp' :
$this->ajouterFiltreMasque('epithete_infra_sp',$val);
break;
case 'masque.au' :
$this->ajouterFiltreMasque('auteur', $val);
break;
case 'masque.an' :
$this->ajouterFiltreMasque('annee', $val);
break;
case 'masque.bib' :
$this->ajouterFiltreMasque('biblio_origine',$val);
break;
case 'masque.ad' :
$this->ajouterFiltreMasque('nom_addendum', $val);
break;
case 'masque.nn' :
$this->requete_condition []= 'num_nom IN ('.$val.')';
$this->masque['num_nom'] = "num_nom=$val";
break;
case 'masque.nt' :
$this->requete_condition []= 'num_tax IN ('.$val.')';
$this->masque['num_tax'] = "num_tax=$val";
break;
case 'masque.rg' :
$this->ajouterFiltreMasque('rang', $val);
break;
case 'retour.champs' :
$this->verifierParamChamps($param, $val);
break;
case 'distinct' :
$this->ajouterNomDistinct($val);
break;
case 'masque.fam' :
$this->ajouterFiltreMasque('famille', $val);
break;
case 'masque.sto' :
$this->ajouterFiltreMasque('statut_origine', $val);
break;
case 'masque.sti' :
$this->ajouterFiltreMasque('statut_introduction', $val);
break;
case 'masque.stc' :
$this->ajouterFiltreMasque('statut_culture', $val);
break;
case 'masque.and' :
$this->requete_condition []= " annee >= ".$this->getBdd()->proteger($val);
break;
case 'masque.anf' :
$this->requete_condition []= " annee <= ".$this->getBdd()->proteger($val);
break;
case 'masque.prgua' :
$this->ajouterFiltreMasque('presence_Guadeloupe', $val);
break;
case 'masque.prmar' :
$this->ajouterFiltreMasque('presence_Martinique', $val);
break;
case 'masque.prstm' :
$this->ajouterFiltreMasque('presence_Saint_Martin', $val);
break;
case 'masque.prdes' :
$this->ajouterFiltreMasque('presence_La_Desirade', $val);
break;
case 'masque.prstb' :
$this->ajouterFiltreMasque('presence_Saint_Barthelemy', $val);
break;
case 'masque.prmga' :
$this->ajouterFiltreMasque('presence_Marie_Galante', $val);
break;
case 'masque.prsai' :
$this->ajouterFiltreMasque('presence_Les-Saintes', $val);
break;
}
}
}
 
public function verifierParamChamps($param, $val) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$champs_demandes = explode(',', $val);
$champs_verifies = array();
$champs_api = array_flip($this->champs_api);
$champs_supp = array('nom_retenu_complet'=>'num_nom_retenu', 'basionyme_complet'=>'basionyme');
$champs_api = array_merge($champs_api, $champs_supp);
foreach ($champs_demandes as $champ) {
if (array_key_exists($champ, $champs_api)) {
$champs_verifies[] = $champs_api[$champ];
}
}
if (count($champs_verifies) > 0) {
$this->requete_champ .= ', '.implode(',', $champs_verifies);
}
}
 
/** Permet de rajouter à la requete sql le parametre distinct. N'est utilisé qu'avec le format oss */
public function ajouterNomDistinct($distinct) {
if (isset($distinct)) {
if ($distinct == 1 && $this->parametres['retour.format'] == 'oss') {
$this->distinct = ' distinct ';
} elseif ($distinct == 1 && $this->parametres['retour.format'] != 'oss') {
$e = 'Erreur dans votre requête </br> L\'utilisation du paramètre distinct ne se fait que sous
le format oss';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
}
 
//-----------------FONCTION D'ANALYSE DES RESSOURCES--------------------------------------------------------------------
 
public function traiterRessourcesIdentifiant() {
//on initialise la condition de la requete sql et le format de réponse
$this->requete_condition = array(); //on vide la table dans le cas de plusieurs version
$this->requete_condition[] = 'num_nom = '.$this->getBdd()->proteger($this->ressources[0]);
$this->format_reponse = $this->service.'/id';
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
if ($this->ressources[1] == 'relations') {
$this->traiterRessourceIdRelations();
} else {
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> noms/#id/relations </li> <li> noms/#id/#champ+#champ </li>
<li> noms/#id/relations/synonymie </li> <li> noms/#id/relations/flores </li>
<li> noms/#id/relations/homonymie </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else { // requete de type noms/#id : rajout du nom_sci pour récupérer le format html par la fct mettreAuFormat()
$this->requete_champ = ' *, nom_sci ';
}
}
 
public function traiterRessourceRelations() {
$this->format_reponse .= '/relations';
$projet = $this->ressources[1];
$num_nom = $this->ressources[2];
if (strrpos($num_nom, 'nn.coste') !== false) {
list($p, $nn) = explode('=', $num_nom);
$num_nom = $nn;
}
$champ = "flore_$projet"."_num";
if (isset($this->ressources[3])) {
$type = $this->ressources[3];
if (!in_array($type, array('homonymie', 'synonymie', 'flores'))) {
$e = "Les types disponibles pour les noms sont homonymie, synonymie et flores";
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
$this->requete_champ = ' num_nom ';
$this->requete_condition = array();
$this->requete_condition[] = "$champ = ".$this->getBdd()->proteger($num_nom);
}
 
public function traiterRessourceIdRelations() {
$this->format_reponse .= '/relations';
if (isset($this->ressources[2]) && !empty($this->ressources[2])) {
// requete de type noms/#id/relations/#relation
switch ($this->ressources[2]) {
case 'synonymie' :
$this->traiterRessourceIdSynonymie();
break;
case 'flores' :
$this->traiterRessourceIdFlores();
break;
case 'homonymie' :
$this->traiterRessourceIdHomonymie();
break;
default :
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> noms/#id/relations </li> <li> noms/#id/relations/synonymie </li>
<li> noms/#id/relations/flores </li> <li> noms/#id/relations/homonymie </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
}
}
 
public function traiterRessourceIdSynonymie() {
// SELECT num_nom, nom_sci, num_nom_retenu, basionyme FROM bdtfx_v2_00 WHERE num_nom = X LIMIT 0,100;
$this->format_reponse .= '/synonymie';
if (strrpos($this->requete_champ, ', basionyme') === false) {
$this->requete_champ .= ', basionyme ';
}
if (strrpos($this->requete_champ, ', num_type') === false) {
$this->requete_champ .= ', num_type ';
}
$this->requete_condition[0] = 'num_nom_retenu = '.
'(SELECT num_nom_retenu FROM '.$this->table.' WHERE '.$this->requete_condition[0].')';
}
 
public function traiterRessourceIdHomonymie() {
// SELECT num_nom, nom_sci, num_nom_retenu FROM bdtfx_v2_00 WHERE nom_sci = (SELECT nom_sci FROM bdtfx_v2_00 WHERE num_nom = X);
$this->format_reponse .= '/homonymie';
$this->requete_condition[0] = 'nom_sci = (SELECT nom_sci FROM '.$this->table
.' WHERE '.$this->requete_condition[0].')';
}
 
public function traiterRessourceIdFlores() {
$champ_flores = '';
foreach ($this->champs_table as $champ) {
if (preg_match('/^flore_.*$/', $champ)) {
$champ_flores .= ', '.$champ;
}
}
$this->format_reponse .= '/flores';
$this->requete_champ = 'num_nom'.$champ_flores;
}
 
public function traiterRessourceStatsRangs() {
// SELECT count(*) as nombre, rang FROM bdtfx_v2_00 [WHERE rang = 290] GROUP BY rang ORDER BY rang;
$this->format_reponse .= '/rangs';
$this->requete_champ = 'count(*) as nombre, rang ';
$this->requete_group_by = ' GROUP BY rang ORDER BY rang ';
}
 
public function traiterRessourceStatsAnnees() {
// SELECT count(*) as nombre, annee FROM bdtfx_v2_00 GROUP BY annee ORDER BY annee;
$this->format_reponse .= '/annees';
$this->requete_champ = 'count(*) as nombre, annee ';
$this->requete_condition = null;
$this->requete_group_by = ' GROUP BY annee ORDER BY annee ';
}
 
public function traiterRessourceStatsInitiales() {
// SELECT count(left( nom_sci, 2 )) as nb, rang, left(nom_sci, 2) as lettre GROUP BY rang, left(nom_sci, 2);
$this->format_reponse .= '/initiales';
$this->requete_champ = 'count(left( nom_sci, 2 )) as nb, rang, left(nom_sci, 2) as lettre ';
$this->requete_group_by = ' GROUP BY rang, left(nom_sci, 2)';
}
 
//-----------------------------FONCTIONS DASSEMBLAGE DE LA REQUETE-----------------------------------------------------
 
public function assemblerLaRequete() {
if ( strrpos($this->format_reponse, 'noms/stats/') === false ) {
$this->mettreAuFormat(); //Ds CommunNomsTaxons.php
}
$requete = 'SELECT '.$this->retournerChamps().' '.
"FROM {$this->table} ".
$this->retournerRequeteCondition().' '.
$this->requete_group_by.' '.
$this->retournerOrderBy().' '.
$this->formerRequeteLimite();
return $requete;
}
 
public function retournerChamps() {
$sql = '';
if ($this->distinct) {
$sql .= $this->distinct.' ';
}
if ($this->requete_champ) {
$sql .= $this->requete_champ.' ';
}
 
// Champs "virtuels" pour tier sur l'ensemble des résultats
if (isset($this->parametres['retour.tri'])) {
list($champ, $ordre) = $this->decouperParametreRetourTri();
if ($champ == 'retenu') {
$sql .= ", IF(num_nom = num_nom_retenu, '0', '1') AS nom_retenu_tri ";
}
}
 
return $sql;
}
 
public function decouperParametreRetourTri() {
$tri = array('', '');
if (isset($this->parametres['retour.tri'])) {
if (preg_match('/^(retenu)(?:,(ASC|DESC)|)$/', $this->parametres['retour.tri'], $match))
$tri[0] = $match[1];
$tri[1] = isset($match[2]) ? $match[2] : '';
}
return $tri;
}
 
public function retournerRequeteCondition() {
$condition = '';
if ($this->requete_condition) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
 
public function retournerOrderBy() {
$orderBy = array();
 
// Tri sur l'ensemble des résultats
if (isset($this->parametres['retour.tri'])) {
list($champ, $ordre) = $this->decouperParametreRetourTri();
if ($champ == 'retenu') {
$orderBy[] = "nom_retenu_tri $ordre";
}
}
// Tri par défaut
if ($this->format_reponse == 'noms') {
$orderBy[] = 'nom_sci ASC';
}
 
$sql = '';
if (count($orderBy) > 0) {
$sql = 'ORDER BY '.implode(', ', $orderBy).' ';
}
return $sql;
}
 
public function formerRequeteLimite() {
if ($this->format_reponse != 'noms' && $this->format_reponse != 'noms/id/relations/synonymie'
&& $this->format_reponse != 'noms/id/relations/homonymie') {
$this->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
$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;
}
 
/** Recupere le nombre total de résultat d'une requete lancée. */
public function recupererTotalResultat() {
$total = null;
$requete = 'SELECT count(*) as nombre FROM '.$this->table.$this->retournerRequeteCondition().$this->requete_group_by;
$res = $this->getBdd()->recuperer($requete);
if ($res) {
$total = $res['nombre'];
} else {
$e = 'Fct recupererTotalResultat() : <br/>Données introuvables dans la base';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
}
return $total;
}
 
 
//-------------------FONCTIONS POUR LE FORMATAGE EN JSON----------------------------------------------------------------
 
public function retournerResultatFormate($resultat) {
switch ($this->format_reponse) {
case 'noms/relations' :
$reponse = $this->formaterRelations($resultat[0]);
break;
case 'noms/id' : //ds CommunNomsTaxons
$reponse = $this->formaterId($resultat[0]);
break;
case 'noms/id/relations' :
$reponse = $this->formaterIdRelations($resultat[0]);
break;
case 'noms/id/relations/synonymie' :
$reponse = $this->formaterIdSynonymie($resultat);
break;
case 'noms/id/relations/homonymie' :
$reponse = $this->formaterIdHomonymie($resultat);
break;
case 'noms/id/relations/flores' : //ds CommunsNomsTaxons
$reponse = $this->formaterIdFlores($resultat[0]);
break;
case 'noms/stats/annees' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsAnnee($resultat);
break;
case 'noms/stats/rangs' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsRang($resultat);
break;
case 'noms/stats/initiales' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsInitiales($resultat);
break;
case 'noms' :
$reponse = $this->formaterNoms($resultat);
break;
}
return $reponse;
}
 
//+---------------------concerne les resultats pour des requetes de type noms/id-----------------------------+
 
public function formaterRelations($resultat) {
$num_nom = $resultat['num_nom'];
if (isset($this->ressources[3])) {
$url = Config::get('url_service').$this->service."/$num_nom/relations";
} else {
$type = $this->ressources[3];
$url = Config::get('url_service')."/$this->service/$num_nom/relations/$type";
}
$res = $this->consulterHref($url);
return $res;
}
 
public function formaterIdRelations($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
$retour_id_rel = array ('entete' => array()); //on initialise pr que l'entete apparaisse en premier lors de l'affichage
 
//on recupère le resultat de chaque relation (appel du WS correspondant)
$flores = $this->ajouterRelations('flores');
if (isset($flores)) $retour_id_rel['resultat']['flores'] = $flores;
$homonymes = $this->ajouterRelations('homonymie');
if (isset($homonymes)) $retour_id_rel['resultat']['homonymes'] = $homonymes;
$synonymes = $this->ajouterRelations('synonymie');
if (isset($synonymes)) $retour_id_rel['resultat']['synonymes'] = $synonymes;
 
//on renvoit null si il n'existe aucune relations (on efface l'entete en premier lieu)
if (!isset($retour_id_rel['resultat'])) {
$retour_id_rel = null;
} else { //on rajoute l'entete si des relations existent
$this->afficherDonnees('num_nom', $this->ressources[0]);
$retour_id_rel['entete'] = $this->table_retour;
$this->table_retour = array();
}
return $retour_id_rel;
}
 
/**
* Recupere les relations (type de la relation passée en paramètres :[type_relation] = synonymie, homonymie ou
* flores) par l'appel du web service [version]/noms/#id/relations/[type_relation]
*/
public function ajouterRelations($relation) {
$version = str_replace(Config::get('bdd_table').'_', '', $this->table);
$res = null;
$parametres_url = '';
if ($this->parametres != array()) $parametres_url = '?'.http_build_query($this->parametres, '', '&');
$url = Config::get('url_service').'/'.$this->service.'/'.
$this->ressources[0].'/relations/'.
$relation.$parametres_url;
 
$relation = $this->consulterHref($url);
 
$res = $relation->resultat;
return $res;
}
 
 
public function formaterIdSynonymie($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$retour_id_syn = array();
if ($resultat[0]['num_nom_retenu'] == '') {
$retour_id_syn[] = 'nom_retenu N.D.';
} elseif (count($resultat) != 1) {
//on remplit d'abord l'entete du resultat
$this->table_retour['id'] = $this->ressources[0];
$this->afficherEnteteResultat('/'.$this->service.'/'.$this->ressources[0].'/relations/synonymie');
$retour_id_syn['entete'] = $this->table_retour;
$this->table_retour = array();
foreach ($resultat as $tab) {
//pour chaque basionyme, on recupère le résultat : num_nom, nom_sci, basionyme et num_nom_retenu :
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('basionyme', $tab['basionyme']);
$retour_id_syn['resultat'][$num] = $this->table_retour;
$this->table_retour = array();
}
if (!isset($retour_id_syn['resultat']) && !in_array('nom_retenu N.D.', $retour_id_syn)) {
$retour_id_syn = null; //on initialise le resultat à null
}
}
return $retour_id_syn;
}
 
public function formaterIdHomonymie($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
if (count($resultat) != 1) {
$this->table_retour['id'] = $this->ressources[0];
$this->afficherEnteteResultat($resultat, '/'.$this->service.'/'.$this->ressources[0].'/relations/homonymie');
$retour_id_hom['entete'] = $this->table_retour;
$this->table_retour = array();
foreach ($resultat as $homonyme) {
$this->resultat_req = $homonyme;
$id = $homonyme['num_nom'];
$this->afficherDonnees('num_nom', $id);
if ($homonyme['num_nom_retenu'] != '') {
$retenu = ($id == $homonyme['num_nom_retenu']) ? 'true' : 'false';
} else {
$retenu = 'absent';
}
$this->table_retour['retenu'] = $retenu;
$retour_id_hom['resultat'][$id] = $this->table_retour;
unset($retour_id_hom['resultat'][$id]['id']);
$this->table_retour = array();
}
} else {
$retour_id_hom = null;
}
return $retour_id_hom;
}
 
public function obtenirSynonymesParNumNomAvecInfosFlore($num_nom, $version='1_02') {
 
$champs_flore = 'flore_bonnier_num, flore_bonnier_rem,'.
'flore_cnrs_num, flore_cnrs_rem '.
'flore_fe_num, flore_fe_rem '.
'flore_coste_num, flore_coste_rem '.
'flore_fh_num, flore_fh_rem '.
'flore_fournier_num, flore_fournier_rem';
 
$requete = 'SELECT num_nom, nom_sci, '.$champs_flore.' '.
'FROM '.$this->table.' '.
'WHERE num_nom_retenu = '.
'('.
'SELECT num_nom_retenu FROM '.$this->table.' WHERE num_nom = "'.$num_nom.'"'.
')';
 
return $this->getBdd()->recupererTous($requete);
}
 
public function formaterIdFlores($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp,noms_projets');
$this->resultat_req = $resultat;
$id = array_shift($resultat);
$reponse['entete']['id'] = $id;
$synonymes_flores = $this->obtenirSynonymesParNumNomAvecInfosFlore($this->ressources[0]);
if(is_array($synonymes_flores)) {
foreach ($synonymes_flores as $synonyme) {
$nom_sci = $synonyme['nom_sci'];
$num_nom = $synonyme['num_nom'];
unset($synonyme['nom_sci']);
unset($synonyme['num_nom']);
foreach ($synonyme as $flores => $valeur) {
if ($valeur != '' && $valeur != '0') {
$this->afficherInfosFlore($synonyme, $flores, $valeur, $nom_sci, $num_nom);
}
}
}
}
 
if ($this->table_retour != array()) {
$reponse['resultat'] = $this->table_retour;
$this->table_retour = array();
} else {
$reponse = null;
}
return $reponse;
}
 
public function getNomCompletFlore($flore) {
return Config::get($flore.'_texte');
}
 
public function afficherInfosFlore(&$resultat, $flores, $valeur, $nom_sci, $num_nom) {
$flore = substr($flores,0,strrpos($flores, '_'));
$projet = $this->noms_projets[$flore];
 
//TODO voir si l'on peut factoriser les affectations à la table retour
// et simplifier ce gros pavé
if (strrpos($flores, 'num') !== false) {
if (preg_match('/^([0-9]+)(?:[.]syn[^a-z]*|(.*))?$/', $valeur, $match)) {
$this->table_retour[$num_nom][$flore]['id'] = $match[1];
if ($projet == 'coste') {
$this->table_retour[$num_nom][$flore]['href'] = $this->ajouterHrefAutreProjet('noms', 'nn_coste:', $match[1], $projet);
}
if (isset($match[2]) && $match[2] != '') $this->table_retour[$num_nom][$flore]['cle'] = $match[2];
$this->table_retour[$num_nom][$flore]['nom_flore'] = $this->getNomCompletFlore($flore);
$this->table_retour[$num_nom][$flore]['nom_sci'] = $nom_sci;
}
if (isset($resultat[$flore.'_rem']) && !empty($resultat[$flore.'_rem'])) {
$this->table_retour[$num_nom][$flore]['remarque'] = $resultat[$flore.'_rem'];
$this->table_retour[$num_nom][$flore]['nom_flore'] = $this->getNomCompletFlore($flore);
$this->table_retour[$num_nom][$flore]['nom_sci'] = $nom_sci;
unset($resultat[$flore.'_rem']);
}
} elseif (strrpos($flores,'belge') !== false) {
if (preg_match('/^([0-9]+) (R|S)?$/', $valeur, $match)) {
if (isset($match[2])) $type = ($match[2] == 'R') ? 'taxons' : 'synonyme';
$this->table_retour[$num_nom][$flore]['page'] = $match[1];
$this->table_retour[$num_nom][$flore]['type'] = $type;
$this->table_retour[$num_nom][$flore]['nom_flore'] = $this->getNomCompletFlore($flore);
$this->table_retour[$num_nom][$flore]['nom_sci'] = $nom_sci;
}
}
}
 
//+---------------------concerne les resultats pour des requetes de type /noms avec ou sans paramètres-------+
 
public function formaterNoms($resultat) {
if ($this->parametres['retour.format'] == 'oss') {
$reponse = $this->formaterEnOss($resultat); //Ds CommunNomsTaxons.php
} else {
$reponse = $this->formaterEnJsonMax($resultat);
}
return $reponse;
}
 
public function formaterEnJsonMax($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
 
// TODO : améliorer le tri des résultats
// ATTENTION : ce comportement est étrange
$masque = $this->recupererMasquePrincipal();
if (isset($masque) && !isset($this->parametres['retour.tri'])) {
// fonction du pauvre pour palier aux "." remplacés accidentellement par des "_"
$index = str_replace('masque_','masque.',$masque[0]);
//$resultat = $this->trierRechercheFloue($this->parametres[$index], $resultat, $masque[1]);
}
 
// Tri à la mode du CeL : lexicographique puis noms retenus (retour.tri = "alpharet")
if (isset($this->parametres['retour.tri']) && ($this->parametres['retour.tri'] == "alpharet")) {
usort($resultat, array($this, 'genrePuisNomsRetenusEnTete'));
}
 
$table_retour_json['entete'] = $this->remplirJsonEntete();
$table_retour_json['resultat'] = $this->remplirJsonResultat($resultat);
return $table_retour_json;
}
 
// Trie les éléments du tableau de résultats : le genre en tête, puis les noms retenus, puis le reste
// mais à partir du jeu de données retourné par SQL (indépendents du statut "retenu")
private function genrePuisNomsRetenusEnTete($a, $b) {
// On pourrait utiliser l'indice ['retenu'] mais il contient parfois "absent", qui est dur à traiter
$aEstRetenu = ($a['num_nom'] == $a['num_nom_retenu']);
$bEstRetenu = ($b['num_nom'] == $b['num_nom_retenu']);
$retour = 0;
 
// les noms retenus en premier ("inférieurs")
if ($aEstRetenu) {
if (! $bEstRetenu) {
$retour = -1;
}
} else {
if ($bEstRetenu) {
$retour = 1;
}
}
 
// en cas d'égalité on conserve le tri lexicographique - devrait faire sortir le genre en première position
// car il ne contient pas le nom d'auteur
if ($retour == 0) {
$retour = strcasecmp($a['nom_sci'], $b['nom_sci']);
}
 
return $retour;
}
 
public function remplirJsonResultat($resultat) {
$champs = null;
if (array_key_exists('retour.champs', $this->parametres)) {
$champs = explode(',', $this->parametres['retour.champs']);
}
 
// Structure des données: objet ou liste ?
$modeListe = false;
if (array_key_exists('retour.structure', $this->parametres)) {
$modeListe = ($this->parametres['retour.structure'] === "liste");
}
 
$noms = array();
foreach ($resultat as $tab) {
$this->table_retour = array();
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num); // ajoute le nom_sci, href et si le nom est retenu dans $this->table_retour
$retour = $this->table_retour;
$this->table_retour = array();
if ($champs != null) {
$reponse_id = $this->formaterId($tab);
$this->table_retour = array();
$this->ajouterChampsPersonnalises($champs, $reponse_id);
$retour = array_merge($retour, $this->table_retour);
}
if ($modeListe) {
$retour['num_nom'] = intval($num);
$noms[] = $retour;
} else {
$noms[$num] = $retour;
}
}
 
return $noms;
}
 
public function remplirJsonEntete() {
$entete = array();
if (isset($this->masque)) {
$this->table_retour['masque'] = implode('&', $this->masque);
}
parent::afficherEnteteResultat('/'.$this->service);
return $this->table_retour;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtre/Taxons.php
New file
0,0 → 1,521
<?php
 
// declare(encoding='UTF-8');// ou ISO-8859-15
/**
* Description :
* Classe Taxons.php permettant de fournir des informations sur les noms scientifiques retenu.
* Si l'url finit par /taxons on retourne une liste de noms latin et leurs identifiants (seulement les 100 premeiers noms par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /taxons?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, recherche, rang, distinct, retour.format, nl.format,
* nl.structure, 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 Taxons extends CommunNomsTaxons {
/** Permet de stocker la requete formulée taxons | taxons/#id | taxons/#id/#champ+#champ ...*/
protected $format_reponse = 'taxons';
protected $service = 'taxons';
protected $requete_champ = 'num_nom, nom_sci, num_nom_retenu, num_tax as num_taxonomique ';
protected $requete_condition = null;
protected $requete_group_by = ' ';
/** Permet de stocker les limite de la requete SQL (par défaut seul les 100 premiers résultats seront retournés).*/
protected $limite_requete = array('depart' => 0, 'limite' => 100);
protected $num_nom_taxon; //Stocke le num_nom du nom retenu du num_nom recherché
protected $presence_num_tax = true;
public function consulter($ressources, $parametres) {
return parent::consulter($ressources, $parametres);
}
public function traiterParametresSpecifiques() {
$this->requete_condition[] = 'num_nom = num_nom_retenu';
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'masque' :
$this->ajouterFiltreMasque('nom_sci', $val);
break;
case 'masque.nt' :
$this->requete_condition[] = "num_tax IN ($val)";
$this->masque[] = "num_tax=$val";
break;
case 'masque.rg':
$this->requete_condition[] = 'rang = '.$this->getBdd()->proteger($val);
$this->masque[] = "rang=$val";
break;
}
}
}
//------------------------------------------Fonction ressources---------------------------------------------------------------------
public function gererNumTax() {
if (!in_array('num_taxonomique', $this->champs_table)) {
$this->presence_num_tax = false;
$this->requete_champ = str_replace(', num_tax ', '', $this->requete_champ);
} else {
$this->presence_num_tax = true;
}
}
public function traiterRessourcesIdentifiant() {
$this->format_reponse = 'taxons/id';
$this->traiterRessourceNtId();
$this->num_nom_taxon = $this->recupererNumNomTaxon(); //on recupere le taxon correspondant au num_nom recherché
if ($this->entete_http == '') {
$this->requete_condition[0] = 'num_nom = '.$this->getBdd()->proteger($this->num_nom_taxon);
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
//---------------- requete de type taxons/#id/#champ+#champ--------------------------------------
if ($this->ressources[1] != 'relations') { // SELECT *, nom_sci FROM bftfx_v2_00 WHERE num_nom = X;
$this->requete_champ = ' *, nom_sci ';
$this->format_reponse .= '/champ';
//---------------- requete de type taxons/#id/relations/#relation--------------------------------
} elseif ($this->ressources[1] == 'relations') {
$this->traiterRessourceIdRelations();
} else {
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> #id/relations </li> <li> #id/#champ+#champ </li> <li> #id/relations </li>
<li> #id/relations/inferieurs </li> <li> #id/relations/superieurs </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else { //--------------- requete de type taxons/#id-----------------------------------------------------
$this->requete_champ = ' *, nom_sci ';
}
}
}
public function traiterRessourceNtId() {
if (strrpos($this->ressources[0], 'nt:') !== false) {
if ($this->presence_num_tax) {
// SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = num_nom_retenu AND num_taxonomique = X;
$this->requete_condition[0] = ' num_tax = '
.str_replace('nt:', '', $this->ressources[0]).' ';
} else {
$e = 'Erreur dans votre requête : </br> Le numéro taxonomique n\'existe pas dans ce projet';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else {
// SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = (SELECT num_nom_retenu FROM bdtfx_v2_00 WHERE num_nom = X);
$this->requete_condition[0] = 'num_nom = '.$this->ressources[0];
}
}
/** Permet de récupérer le num_nom du taxon recherché. Soit le numéro taxonomique est demandé (avec nt: )
* soit un num_nom dont on recherche le num_nom_retenu */
public function recupererNumNomTaxon() {
$identifiant = '';
if ($this->entete_http == '') {
//on récupere l'identifiant du taxon correspondant au num_nom ou num_taxonomique demandé pour pouvoir l'afficher
$req_tax = 'SELECT num_nom_retenu FROM '.$this->table.' WHERE '.$this->requete_condition[0];
$res_tax = $this->getBdd()->recuperer($req_tax);
//on recherche ensuite les identifiants des taxons supérieurs ou inférieurs
if ($res_tax && $res_tax != '') {
$identifiant = $res_tax['num_nom_retenu'];
} else {
$e = 'Le numéro de taxon ou l\'identifiant de nom correspondant au num_nom '
.$this->ressources[0].' n\'existe pas dans la base.';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
Debug::printr($req_tax);
}
}
return $identifiant;
}
public function traiterRessourceIdRelations() {
//----------------- requete de type taxons/#id/relations-------------------------------------------
// SELECT *, nom_sci FROM bftfx_v2_00 WHERE num_nom = X;
$this->format_reponse .= '/relations';
if (isset($this->ressources[2]) && !empty($this->ressources[2])) {
//------------- requete de type taxons/#id/relations/#relation--------------------------------
switch ($this->ressources[2]) {
case 'superieurs' :
$rel = 'recupererIdSup';
$this->format_reponse .= '/superieurs';
$this->traiterRessourceIdRelationInfSup($rel);
break;
case 'inferieurs' :
$rel = 'recupererIdInf';
$this->format_reponse .= '/inferieurs';
$this->traiterRessourceIdRelationInfSup($rel);
break;
case 'hierarchie' :
$rel = 'recupererIdHierarchie';
$this->format_reponse .= '/hierarchie';
$this->traiterRessourceIdRelationHierarchie($rel);
break;
default :
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> taxons/#id/relations </li><li> #id/relations/inferieurs </li>
<li> #id/relations/superieurs </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
}
}
public function traiterRessourceIdRelationHierarchie($rel) {
//Appel de la fct récupérerIdSup ou recupererIdInf : retourne les num_nom des noms inferieurs ou superieurs
$res_relation = $this->$rel();
//analyse du résultat retourné par la requete de recherche des identifiants correspondant aux taxons inf|sup :
if ($res_relation == '') {
//dans le cas ou la requete comporte des erreurs
$e = 'Fct traiterRessourceIdRelationInfSup : La requête forme comporte une erreur!';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
} elseif ($res_relation) {
//dans le cas ou une ou plusieurs relations est retournée, on récupère les identifiants ss la forme (id, id, id)
foreach ($res_relation as $ligne) $res[] = $ligne['num_nom'];
$res = implode(',',$res);
$this->requete_condition[0] = "num_nom IN ($res)";
$this->requete_champ .= ', rang, num_tax_sup ';
} else { //dans le cas ou aucune relation n'existe
$res = array($this->num_nom_taxon => null);
$this->corps_http = json_encode($res);
$this->entete_http = RestServeur::HTTP_CODE_OK;
}
}
public function recupererIdHierarchie() {
$req_relation = 'SELECT num_nom FROM '.$this->table.' '.
' WHERE hierarchie LIKE CONCAT('.
'(SELECT hierarchie FROM '.
$this->table.' '.
'WHERE num_nom = '.$this->getBdd()->proteger($this->num_nom_taxon).')'.
', '.$this->getBdd()->proteger($this->num_nom_taxon.'-%').
')';
$res_relation = $this->getBdd()->recupererTous($req_relation);
return $res_relation;
}
public function traiterRessourceIdRelationInfSup($rel) {
//Appel de la fct récupérerIdSup ou recupererIdInf : retourne les num_nom des noms inferieurs ou superieurs
$res_relation = $this->$rel();
//analyse du résultat retourné par la requete de recherche des identifiants correspondant aux taxons inf|sup :
if ($res_relation == '') { //dans le cas ou la requete comporte des erreurs
$e = 'Fct traiterRessourceIdRelationInfSup : La requête forme comporte une erreur!';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
} elseif ($res_relation) {
//dans le cas ou une ou plusieurs relations est retournée, on récupère les identifiants ss la forme (id, id, id)
foreach ($res_relation as $ligne) $res[] = $ligne['num_nom'];
$res = implode(',',$res);
$this->requete_condition[0] = "num_nom IN ($res)";
$this->requete_champ .= ', rang, num_tax_sup ';
} else { //dans le cas ou aucune relation n'existe
$res = array($this->num_nom_taxon => null);
$this->corps_http = json_encode($res);
$this->entete_http = RestServeur::HTTP_CODE_OK;
}
}
public function recupererIdInf() {
//SELECT num_nom FROM bfdtx_v2_00 WHERE num_tax_sup = (SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = X);
$req_relation = 'SELECT num_nom FROM '.$this->table
.' WHERE num_nom = num_nom_retenu AND num_tax_sup = (SELECT num_nom FROM '
.$this->table
.' WHERE '.implode(' AND ', $this->requete_condition).')';
$res_relation = $this->getBdd()->recupererTous($req_relation);
return $res_relation;
}
public function recupererIdSup() {
//SELECT num_nom FROM bfdtx_v2_00 WHERE num_nom = (SELECT num_tax_sup FROM bdtfx_v2_00 WHERE num_nom = X);
$this->requete_condition[] = "num_nom = num_nom_retenu" ;
$req_relation = 'SELECT num_tax_sup as num_nom FROM '.$this->table
.' WHERE '.implode(' AND ', $this->requete_condition);
$res_relation = $this->getBdd()->recupererTous($req_relation);
return $res_relation;
}
 
public function traiterRessourceStatsInitiales() {
// SELECT count(nom_sci) as nb, rang, left(nom_sci, 2) as lettre FROM bdtfx_v2_00 GROUP BY rang, left(nom_sci, 2);
$this->format_reponse = 'taxons/stats/initiales';
$this->requete_champ = 'count(nom_sci) as nb, rang, left(nom_sci, 2) as lettre ';
$this->requete_group_by = ' GROUP BY rang, left(nom_sci, 2) ';
}
public function traiterRessourceStatsRangs() {
// SELECT count(*) as nombre, rang FROM bdtfx_v2_00 [WHERE rang = 290] GROUP BY rang ORDER BY rang;
$this->format_reponse = 'taxons/stats/rangs';
$this->requete_champ = 'count(*) as nombre, rang ';
$this->requete_group_by = ' GROUP BY rang ORDER BY rang ';
}
public function traiterRessourceStatsAnnees() {
// SELECT count(*) as nombre, annee FROM bdtfx_v2_00 GROUP BY annee ORDER BY annee;
$this->format_reponse = 'taxons/stats/annees';
$this->requete_champ = 'count(*) as nombre, annee ';
$this->requete_group_by = ' GROUP BY annee ORDER BY annee ';
}
//-----------------------------FONCTIONS DASSEMBLAGE DE LA REQUETE-----------------------------------------------------
public function assemblerLaRequete() {
if ($this->format_reponse != 'taxons/stats/initiales') {
$this->mettreAuFormat(); //on remplace les nom_sci par les nom_sci_html
}
$requete = ' SELECT '.$this->requete_champ.
' FROM '.$this->table
.$this->retournerRequeteCondition()
.$this->requete_group_by
.$this->formerRequeteLimite();
return $requete;
}
public function formerRequeteLimite() {
if ($this->format_reponse != 'taxons' && $this->format_reponse != 'taxons/id/relations/homonymie') {
$this->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
$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 retournerRequeteCondition() {
$condition = '';
if ($this->requete_condition) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
public function recupererTotalResultat() {
$requete = 'SELECT count(*) as nombre FROM '.$this->table.$this->retournerRequeteCondition().$this->requete_group_by;
$res = $this->getBdd()->recuperer($requete);
if ($res) {
$total = $res['nombre'];
}
return $total;
}
 
//-------------------------FONCTIONS DE FORMATION DU RESULTAT-----------------------------------------------------------
/** Permet de récupérer le résultat à retourner propre à chaque requete et de l'encoder en json*/
public function retournerResultatFormate($resultat, $version) {
switch ($this->format_reponse) {
case 'taxons/id' ://ds CommunNomsTaxons
$reponse = $this->formaterId($resultat[0]);
break;
case 'taxons/id/champ' ://ds CommunNomsTaxons
$reponse = $this->formaterIdChamp($resultat[0]);
break;
case 'taxons/id/relations' :
$reponse = $this->formaterIdRelations($resultat[0],$version);
break;
case 'taxons/id/relations/superieurs' :
$reponse = $this->formaterIdSuperieur($resultat, $version);
break;
case 'taxons/id/relations/inferieurs' :
$reponse = $this->formaterIdInferieur($resultat);
break;
case 'taxons/id/relations/hierarchie' :
// le formatage de la hiérarchie est identique aux relations inférieures
$reponse = $this->formaterIdInferieur($resultat);
break;
case 'taxons/stats/annees' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsAnnee($resultat);
break;
case 'taxons/stats/rangs' ://ds CommunNomsTaxons
$reponse = $this->formaterStatsRang($resultat);
break;
case 'taxons/stats/initiales' ://ds CommunNomsTaxons
$reponse = $this->formaterStatsInitiales($resultat);
break;
case 'taxons' :
$reponse = $this->formatertaxons($resultat);
break;
}
return $reponse;
}
//----------------------concerne les resultats pour des requetes de type /noms avec ou sans paramètres--------------
public function formaterTaxons($resultat) {
if ($this->parametres['retour.format'] == 'oss') {
$reponse = $this->formaterEnOss($resultat);
} else {
$reponse = $this->formaterEnJsonMax($resultat);
}
return $reponse;
}
public function formaterEnJsonMax($resultat) {
//print_r($resultat);
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$masque = $this->recupererMasquePrincipal();
if (isset($masque)) $resultat = $this->trierRechercheFloue($this->parametres[$masque[0]], $resultat, $masque[1]);
if (isset($this->masque)) $this->table_retour['masque'] = implode('&', $this->masque);
$this->afficherEnteteResultat('/'.$this->service);
$table_retour_json['entete'] = $this->table_retour;
$this->table_retour = array();
//on remplit la table $table_retour_json['resultat']
$tab_tax_inf = $this->recupererListeTaxonInf($resultat);
foreach ($resultat as $tab) {
$num = $tab['num_nom'];
if (isset($this->parametres['masque.nt'])) $this->afficherDonnees('num_taxonomique', $tab['num_taxonomique']);
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherTaxonInfNb($num, $tab_tax_inf);
$resultat_json[$num] = $this->table_retour;
$this->table_retour = array(); //on vide le tableau table_retour
}
$table_retour_json['resultat'] = $resultat_json;
return $table_retour_json;
}
//--------------------concerne les resultats pour des requetes de type noms/id----------------------------------------
 
public function formaterIdRelations($resultat, $version) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
$retour_id_rel = array ('entete' => array()); //on initialise pr que l'entete apparaisse en premier
 
$superieurs = $this->ajouterRelations('superieurs'); //, $version);
if (isset($superieurs)) $retour_id_rel['resultat']['superieurs'] = $superieurs;
$inferieurs = $this->ajouterRelations('inferieurs', $version);
if (isset($inferieurs)) $retour_id_rel['resultat']['inferieurs'] = $inferieurs;
if (!isset($retour_id_rel['resultat'])) { //on renvoit un tableau null si il n'existe aucune relations
$retour_id_rel = 'null';
} else { //on rajoute l'entete si des relations existent
$this->afficherDonnees('num_nom', $this->num_nom_taxon); //$this->afficherEnteteResultat($resultat, '/'.$this->service.'/'.$this->ressources[0].'/relations/synonymie');
$retour_id_rel['entete'] = $this->table_retour;
$this->table_retour = array();
}
return $retour_id_rel;
}
public function ajouterRelations($relation, $version) {
$version = str_replace(Config::get('bdd_table').'_', '', $version);
$res = null;
$taxon = $this->num_nom_taxon;
$parametres_url = '';
if ($this->parametres != array()) $parametres_url = '?'.http_build_query($this->parametres, '', '&');
$url = Config::get('url_service').'/'
.$this->service.'/'.$version.'/'
.$this->ressources[0].'/relations/'
.$relation.$parametres_url;
$relation = $this->consulterHref($url);
if (isset($relation->resultat)) {
$res = $relation->resultat;
} elseif (isset($relation->$taxon)) { //pour les relations inf et sup
$res = $relation->$taxon;
}
return $res;
}
public function formaterIdSuperieur($resultat, $version) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$tab_relation = null; //si il n'existe aucune relation
$taxon_sup_traites = array();
if (($resultat) != '' ) {
//on recupere d'abord les rangs supérieurs
$sup = $resultat[0];
do {
$sup = $this->recupererIdSuperieur($sup['num_tax_sup'], $version);
if(!in_array($sup['num_nom'], $taxon_sup_traites)) {
$taxon_sup_traites[] = $sup['num_nom'];
} else {
$sup = null;
}
if ($sup['rang'] == '0') $sup['rang'] = '10'; //erreur dans la base
if (isset($sup)) $resultat[] = $sup;
} while ($sup != null);
krsort($resultat);
//on les affiche ensuite
foreach ($resultat as $tab) {
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('rang', $tab['rang']);
$tab_inf[$num] = $this->table_retour;
$tab_inf[$num]['num_nom'] = $tab['num_nom'];
$this->table_retour = array();
}
$tab_relation[$this->num_nom_taxon] = $tab_inf;
}
return $tab_relation;
}
public function recupererIdSuperieur($id, $version) {
$req = 'SELECT num_nom, num_nom_retenu, num_tax_sup, rang, nom_sci FROM '
.$version.' WHERE num_nom = '.$this->getBdd()->proteger($id);
$res = $this->getBdd()->recupererTous($req);
if ($res) {
$resultat = $res[0];
} else {
$resultat = null; //on return null si il n'y a pas de taxon superieur
}
return $resultat;
}
public function formaterIdInferieur($resultat) {
// Attention à l'ordre, on doit d'abord récupérer correpondance_champs avant champs_api
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$tab_relation = null;
if (($resultat) != array()) {
foreach ($resultat as $tab) {
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('rang', $tab['rang']);
$tab_inf[$num] = $this->table_retour;
$tab_inf[$num]['nom_sci'] = $tab['nom_sci'];
$tab_inf[$num]['num_nom'] = $tab['num_nom'];
$this->table_retour = array();
}
$tab_relation[$this->num_nom_taxon] = $tab_inf;
}
return $tab_relation;
}
public function afficherTaxonInfNb($num, $tab_tax_inf) {
foreach ($tab_tax_inf as $taxNb) {
if ($taxNb['num_tax_sup'] == $num) {
$this->table_retour['taxon_inferieur_nbre'] = $taxNb['nb'];
}
}
if (!isset($this->table_retour['taxon_inferieur_nbre'])) {
$this->table_retour['taxon_inferieur_nbre'] = '0';
}
}
public function recupererListeTaxonInf($resultat) {
// SELECT num_tax_sup, count(*) as nb FROM bdtfx_v2_00 WHERE num_tax_sup IN (id, id, id) AND num_nom = num_nom_retenu GROUP BY num_tax_sup';
foreach ($resultat as $tab) {
$tab_num[] = $tab['num_nom']; //on regroupe ici les id des taxons dont on cherche le nb de taxon inf
}
$req = 'SELECT num_tax_sup, count(*) as nb FROM '.$this->table
.' WHERE num_tax_sup IN ('.implode(',',$tab_num)
.') AND num_nom = num_nom_retenu GROUP BY num_tax_sup';
$res = $this->getBdd()->recupererTous($req);
if ($res) {
$resultat = $res;
} else {
$resultat = array(); //on retourne un tableau vide s'il n'y a pas de taxon inférieurs
}
return $resultat;
}
}
 
?>
/tags/v5.12-baouque/services/modules/0.1/isfan/CommunNomsTaxons.php
New file
0,0 → 1,928
<?php
// declare(encoding='UTF-8');
/**
* Description :
* Classe CommunNomsTaxons.php
* 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-2011 Tela Botanica (accueil@tela-botanica.org)
*/
 
 
abstract class CommunNomsTaxons extends Commun {
 
/** Tableau de correspondance entre les noms des champs et les codes de l'ontologie.*/
private $relationsChampsCodesOntologie = null;
protected $table_retour; //Permet de stocker le tableau de résultat (non encodé en json)
protected $resultat_req; // Permet de stocker le résultat de la requete principale.
protected $compo_nom = null; //Stocke sous forme de tableau les composant du nom à ajouter au nom scientifique
protected $table;// Nom de la table dans laquelle on récupèrera les données dans les requetes SQL
protected $total_resultat = null;
/** Stocke le service appelé correspondant. Est utilisé principalement lors de l'affichage du href d'un synonyme
(ex id=12, basionyme num 25 est un synonyme) dans le service taxon */
protected $service_href = null;
protected $erreursParametres = null;
protected $sans_nom_sci = array('gen','sp','ssp','fam','au_ss','bib_ss');
private $bib_traitees = array();
private $ontologie = array();
 
//+------------------------------- PARAMÈTRES ---------------------------------------------------------------+
 
public function traiterParametres() {
$this->definirParametresParDefaut();
$this->verifierParametres();
 
if (isset($this->parametres) && count($this->parametres) > 0) {
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'ns.structure' :
$this->remplirTableCompositionNom($val);
if (in_array($val,$this->sans_nom_sci)){
$this->requete_champ = implode(', ',$this->compo_nom);
}else {
$this->requete_champ .= ' ,'.implode(', ',$this->compo_nom);
}
break;
case 'navigation.depart' :
$this->limite_requete['depart'] = $val;
break;
case 'navigation.limite' :
$this->limite_requete['limite'] = $val;
break;
}
}
$this->traiterParametresSpecifiques();
}
}
 
protected function definirParametresParDefaut() {
if (empty($this->parametres['recherche'])) {
$this->parametres['recherche'] = 'stricte';
}
if (empty($this->parametres['ns.format'])) {
$this->parametres['ns.format'] = 'txt';
}
if (empty($this->parametres['retour.format'])) {
$this->parametres['retour.format'] = 'max';
}
if (empty($this->parametres['ns.structure']) &&
$this->parametres['retour.format'] != 'oss') {
$this->parametres['ns.structure'] = 'au,an,bib';
}
}
 
 
public function verifierParametres() {
//$this->verifierParametresAPI();
 
$this->verifierParametre('recherche', 'stricte|floue|etendue|complete');
$this->verifierParametre('ns.format', 'htm|txt');
$this->verifierParametre('retour.format', 'min|max|oss|perso');
$this->verifierParametreAvecValeurMultipe('ns.structure', 'an|au|bib|ad|gen|sp|ssp|fam|au_ss|bib_ss');
 
/*if (count($this->erreursParametres) > 0) {
$m = 'Erreur dans votre requête : '.implode('<br/>', $this->erreursParametres);
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}*/
}
 
public function verifierParametresAPI() {
$parametresApi = $this->recupererTableauConfig('parametresAPI');
while (!is_null($parametre = key($this->parametres))) {
if (!in_array($parametre, $parametresApi)) {
$this->erreursParametres[] = "Le paramètre '$parametre' n'est pas pris en compte par cette version de l'API.";
}
next($this->parametres);
}
}
 
public function verifierParametre($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeur = $this->parametres[$parametre];
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
 
public function verifierParametreAvecValeurMultipe($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeursConcatenees = $this->parametres[$parametre];
$valeurs = explode(',', $valeursConcatenees);
foreach ($valeurs as $valeur) {
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
}
 
private function verifierValeursPermises($parametre, $valeur, $valeursPermises) {
if (!in_array($valeur, explode('|', $valeursPermises))) {
$this->erreursParametres[] = "Le paramètre '$parametre' ne peut pas prendre la valeur '$valeur'. Valeurs permises : $valeursPermises";
}
}
 
public function traiterParametresCommuns() {
 
}
 
public function ajouterFiltreMasque($nom_champ, $valeur) {
$valeur = explode(',',$valeur);
$conditions = array();
if ($nom_champ == 'annee' || $nom_champ == 'rang') {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ = ".$this->getBdd()->proteger($val);
}
} else {
if ($this->parametres['recherche'] == 'etendue') {
foreach ($valeur as $val) {
$val = $this->modifierValeur($val);
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
 
} elseif ($this->parametres['recherche'] == 'floue') {
foreach ($valeur as $val) {
$val = $this->getBdd()->proteger($val);
$conditions[] = "( SOUNDEX($nom_champ) = SOUNDEX($val))".
" OR ( SOUNDEX(REVERSE($nom_champ)) = SOUNDEX(REVERSE($val)))";
}
} else {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
}
}
$this->requete_condition[]= '('.implode(' OR ', $conditions ).')';
$this->masque[$nom_champ] = $nom_champ.'='.implode(',',$valeur);
}
 
private function modifierValeur($valeur) {
$valeur = $this->remplacerCaractereHybrideEtChimere($valeur);
$valeur = $this->preparerChainePourRechercheEtendue($valeur);
return $valeur;
}
 
private function remplacerCaractereHybrideEtChimere($valeur) {
$caracteres = array('×', '%D7', '+', '%2B');
$remplacements = array('x ','x ', '+', '+');
$valeur = str_replace($caracteres, $remplacements, $valeur);
return $valeur;
}
 
private function preparerChainePourRechercheEtendue($valeur) {
$valeur = str_replace(' ', '% ', trim($valeur));
$valeur = $valeur.'%';
return $valeur;
}
 
//+-------------------------------Fonctions d'analyse des ressources-------------------------------------+
 
private function etreRessourceId() {
$ok = false;
if ($this->estUnIdentifiant() && count($this->ressources) == 1) {
$ok = true;
}
return $ok;
}
 
public function traiterRessources() {
if (isset($this->ressources) && count($this->ressources) > 0) {
if ($this->ressources[0] == 'relations') {
$this->traiterRessourceRelations();
} elseif ($this->estUnIdentifiant()) { //l'identifiant peut etre de type /#id ou /nt:#id
$this->traiterRessourcesIdentifiant(); // dans le service noms ou taxons
} elseif ($this->ressources[0] == 'stats') { //ressource = noms/stats
$this->traiterRessourcesStats();
} else {
$e = 'Erreur dans votre requete </br> Ressources disponibles : <br/>
<li> /'.$this->service.'/#id (id : L\'identifiant du nom rechercher)</li>
<li> /'.$this->service.'/nt:#id (id : Numero du taxon recherche)</li>
<li> /'.$this->service.'/stats </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
}
 
public function traiterRessourcesStats() {
$this->format_reponse = $this->service.'/stats';
 
$e = "Erreur dans votre requête </br> Ressources disponibles : $this->service/stats/[annees|rangs|initiales]";
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
switch ($this->ressources[1]) {
case 'annees' :
$this->traiterRessourceStatsAnnees();
break;
case 'rangs' :
$this->traiterRessourceStatsRangs();
break;
case 'initiales' :
$this->traiterRessourceStatsInitiales();
break;
default :
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
} else {
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
/** Vérifie si la première valeur de la table de ressource est un identifiant :
* un numerique ou un numéro taxonomique sous la forme nt:xx */
public function estUnIdentifiant() {
return (is_numeric($this->ressources[0]) || (strrpos($this->ressources[0],'nt:') !== false
&& is_numeric(str_replace('nt:','',$this->ressources[0]))));
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonction d'analyse des parametres
 
/** Permet de remplir le tableau compo_nom. Il comprendra en fct du paramètre ns.structure les éléments à rajouter
* au nom_sci (annee, auteur, biblio ou addendum). */
public function remplirTableCompositionNom($valeur) {
$structure_nom = explode(',', $valeur);
foreach ($structure_nom as $structure) {
$structure = trim($structure);
$patterns = array('/^an$/', '/^au$/', '/^bib$/', '/^ad$/', '/^sp$/', '/^gen$/', '/^ssp$/','/^fam$/',
'/^au_ss$/','/^bib_ss$/');
$champs = array('annee', 'auteur', 'biblio_origine', 'nom_addendum', 'epithete_sp', 'genre',
'epithete_infra_sp','famille','auteur', 'biblio_origine');
 
// avec str_replace() 'sp' est inclu dans 'ssp', et la conversion pour 'ssp' est mauvaise
$this->compo_nom[$structure] = preg_replace($patterns, $champs, $structure);
}
}
 
public function mettreAuFormat() {
if ($this->parametres['ns.format'] == 'htm') {
if (strrpos($this->requete_champ, 'nom_sci_html as nom_sci') === false) {
$this->requete_champ = str_replace('nom_sci', 'nom_sci_html as nom_sci', $this->requete_champ);
}
}
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonctions de formatage
 
/** 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. */
public function recupererTableSignification($table) {
$tables = explode(',', $table);
foreach ($tables as $tab) {
if ($tab == 'champs_comp') {
$champ_bdnff_api = array_keys($this->champs_api); //on recupère le nom des champ ds la bdd
$this->champs_comp = array_diff($this->champs_table, $champ_bdnff_api);
} elseif ($tab == 'champs_api') {
foreach ($this->correspondance_champs as $key => $val) {
preg_match('/(hybride[.]parent_0[12](?:[.]notes)?|nom_sci[.][^.]+|[^.]+)(?:[.](id|code))?/', $val, $match);
$val = $match[1];
$this->champs_api[$key] = $val;
}
} else {
$this->$tab = $this->recupererTableauConfig($tab);
}
}
}
 
public function formaterEnOss($resultat) {
$table_nom = array();
$oss = '';
foreach ($resultat as $tab) {
if (isset($tab['nom_sci']) ) {
if (!in_array($tab['nom_sci'], $table_nom)) {
$table_nom[] = $tab['nom_sci'];
$oss[] = $tab['nom_sci'].' '.$this->ajouterCompositionNom($tab);
}
}else {
$res = $this->ajouterCompositionNom($tab);
if($res) {
$oss[] = $res;
}
}
 
}
 
if (isset($this->masque)) $masque = implode('&', $this->masque);
else $masque = 'Pas de masque';
$table_retour_oss = array($masque, $oss);
return $table_retour_oss;
}
 
public function afficherEnteteResultat($url_service) {
$this->table_retour['depart'] = $this->limite_requete['depart'];
$this->table_retour['limite'] = $this->limite_requete['limite'];
$this->table_retour['total'] = $this->total_resultat;
$url = $this->formulerUrl($this->total_resultat, $url_service);
if (isset($url['precedent']) && $url['precedent'] != '') {
$this->table_retour['href.precedent'] = $url['precedent'];
}
if (isset($url['suivant']) && $url['suivant'] != '') {
$this->table_retour['href.suivant'] = $url['suivant'];
}
}
 
public function afficherNomHrefRetenu($tab, $num) {
$this->resultat_req = $tab;
$this->afficherDonnees('num_nom', $num);
if ($this->parametres['retour.format'] == 'min') { // sinon est affiché ds afficherDonnees(num_nom, $val) ci-dessus
$this->table_retour['nom_sci'] = $tab['nom_sci'];
$this->table_retour['nom_sci_complet'] = $tab['nom_sci'].' '.$this->ajouterCompositionNom($tab);
}
if ($tab['num_nom_retenu'] != '') {
$retenu = ($tab['num_nom_retenu'] == $num) ? 'true' : 'false';
} else {
$retenu = 'absent';
}
$this->table_retour['retenu'] = $retenu;
unset($this->table_retour['id']);
}
 
 
//+------------------------------------------------------------------------------------------------------+
// Fonction de formatage pour les services /#id/
 
public function formaterId($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
 
foreach ($resultat as $cle => $valeur) {
if ($valeur != '') {
$this->afficherDonnees($cle, $valeur);
}
}
if (isset($this->parametres['retour.champs']) && $this->format_reponse == 'noms/id') {
$retour = $this->table_retour;
$this->table_retour = array();
$champs = explode(',', $this->parametres['retour.champs']);
$this->ajouterChampsPersonnalises($champs, $retour);
}
unset($this->table_retour['href']);
return $this->table_retour;
}
 
public function formaterIdChamp($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$reponse_id = $this->formaterId($resultat);
$this->table_retour = array();
$champs = explode(' ', $this->ressources[1]);
$this->ajouterChampsPersonnalises($champs, $reponse_id);
return $this->table_retour;
}
 
protected function ajouterChampsPersonnalises($champs, $reponse_id) {
$champs_a_libeller = array('nom_retenu', 'rang', 'basionyme', 'hybride', 'hybride.parent_01',
'hybride.parent_02', 'presence', 'tax_sup', 'statut_origine', 'statut_culture', 'statut_introduction');
$champs_forces = array('rang'); // même s'ils sont dans "à libeller", on les prend quand même en brut, en plus
if (! is_null($champs) && is_array($champs) && count($champs) > 0) {
foreach ($champs as $champ) {
if ($this->verifierValiditeChamp($champ)) {
if (strrpos($champ, '.*') !== false) {
$this->afficherPointEtoile($champ, $reponse_id);
} elseif (in_array($champ, $champs_a_libeller)) {
$this->table_retour[$champ.'.libelle'] =
(isset($reponse_id[$champ.'.libelle'])) ? $reponse_id[$champ.'.libelle'] : null;
} else {
$champ = $this->trouverChampBddCorrespondant($champ);
$this->table_retour[$champ] = (isset($reponse_id[$champ])) ? $reponse_id[$champ] : null;
}
// champs bruts en plus, ajouté pour obtenir le rang, mais retourne rang.code avec du kk dedans :-/
if (in_array($champ, $champs_forces)) {
$champ = $this->trouverChampBddCorrespondant($champ);
$this->table_retour[$champ] = (isset($reponse_id[$champ])) ? $reponse_id[$champ] : null;
}
}
}
}
}
 
public function afficherPointEtoile($champ, $reponse) {
preg_match('/^([^.]+\.)\*$/', $champ, $match);
if ($match[1] == 'nom_sci') {
$this->afficherNomSciPointEpithete($this->resultat_req);
} else {
foreach ($reponse as $chp => $valeur) {
if (strrpos($chp, $match[1]) !== false) {
if ($valeur != '') {
$this->table_retour[$chp] = $valeur;
} else {
$this->table_retour[$chp] = null;
}
}
}
}
}
 
public function decomposerNomChamp($champ) {
$decomposition = false;
if (preg_match('/^(?:([^.]+\.parent_0[12]|[^.]+))(?:\.(.+))?$/', $champ, $match)) {
$radical_champ = $match[1];
$suffixe = (isset($match[2])) ? $match[2] : "";
$decomposition = array($radical_champ, $suffixe);
}
return $decomposition;
}
 
public function verifierValiditeChamp($champ) {
$decomposition = $this->decomposerNomChamp($champ);
$validite_ressource = true;
if ($decomposition) {
list($radical, $suffixe) = $decomposition;
$champs_complementaire = array('nom_retenu_complet', 'basionyme_complet');
// on verifie si le nom du champ existe bien
if (!$this->estChampApi($radical) && !$this->estChampComplementaire($radical)) {
if (!in_array($radical, $champs_complementaire)) {
$validite_ressource = false;
$e = 'Le champ "'.$radical.'" n\'existe pas dans la base. <br/><br/>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} elseif ($this->estUnPoint($champ)) {
$validite_ressource = $this->verifierValiditeSuffixe($suffixe, $radical);
}
}
return $validite_ressource;
}
 
public function estChampApi($radical_champ) {
$champ_api_ok = false;
if (in_array($radical_champ, $this->champs_api) || in_array($radical_champ, $this->correspondance_champs)) {
$champ_api_ok = true;
}
return $champ_api_ok;
}
 
public function estChampComplementaire($radical_champ) {
$champ_complementaire_ok = in_array($radical_champ, $this->champs_comp) ? true : false;
return $champ_complementaire_ok;
}
 
public function verifierValiditeSuffixe($suffixe, $radical_champ) {
$validite_ressource = true;
if ($this->correspondAUnId($radical_champ) || $radical_champ == 'id') {
$this->verificationSuffixesIdentifiant($suffixe, $radical_champ, $validite_ressource);
} elseif ($this->correspondAUnCode($radical_champ)) {
$this->verificationSuffixesCodes($suffixe, $radical_champ, $validite_ressource);
} elseif ($radical_champ == 'nom_sci') {
if ($suffixe != '*') {
$validite_ressource = false;
$m = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/>
Les suffixes possibles sont les suivants : <li> * </li>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
} else {
$validite_ressource = false;
$m = 'Erreur : Le paramètre "'.$radical_champ.'" ne peut pas présenter de suffixe. <br/><br/>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
return $validite_ressource;
}
 
public function verificationSuffixesCodes(&$suffixe, &$radical_champ, &$validite_ressource ) {
if (!in_array($suffixe, array('*', 'code', 'href', 'details'))) {
$validite_ressource = false;
$e = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'.<br/> Les suffixes '
.'possibles sont les suivants : <li> .* </li><li> .code </li><li> .href </li><li> .details </li>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
public function verificationSuffixesIdentifiant(&$suffixe, &$radical_champ, &$validite_ressource) {
if ((strrpos($radical_champ, 'parent') !== false && !in_array($suffixe, array('*', 'id', 'href', 'details', 'notes')))
|| !in_array($suffixe, array('*', 'id', 'href', 'details')) && strrpos($radical_champ, 'parent') === false) {
$validite_ressource = false;
$e = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/> Les suffixes '
.'possibles sont les suivants : <li> .* </li><li> .id </li><li> .href </li><li> .details </li>'
.'<li> .notes (seulement pour les hybride.parent)';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
 
//------------------------------fonction de formatage pour les services /stats/-----------------------------------------
 
public function formaterStatsAnnee($resultat) {
foreach ($resultat as $cle_annee) {
$annee = ($cle_annee['annee'] != '') ? $cle_annee['annee'] : 'ND';
$nb = $cle_annee['nombre'];
$retour_stats_annee[$annee] = $nb;
}
return $retour_stats_annee;
}
 
public function formaterStatsRang($resultat) {
foreach ($resultat as $rangs) {
if ($rangs['rang'] != 0) {
$rang = $rangs['rang'];
if ($this->parametres['retour.format'] == 'max') {
$retour_rang[$rang]['rang'] = $this->ajouterSignificationCode('rang',$rang);
}
$nombre = $rangs['nombre'];
$retour_rang[$rang]['nombre'] = $nombre;
}
}
return $retour_rang;
}
 
public function formaterStatsInitiales($resultat) {
$rang = null;
$table_rang = array();
foreach ($resultat as $tuple) {
if ($tuple['rang'] != 0) {
$this->memoriserRang($table_rang, $tuple, $rang);
if ($tuple['lettre'] == 'x ') {
$this->ajouterHybrideChimere('hybride', $rang, $tuple);
} elseif ($tuple['lettre'] == '+ ') {
$this->ajouterHybrideChimere('chimere', $rang, $tuple);
} else {
$l = substr($tuple['lettre'], 0, 1);
if (isset($this->table_retour[$rang][$l])) {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] += floatval($tuple['nb']);
} else {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] = floatval($tuple['nb']);
}
}
}
}
return $this->table_retour;
}
 
public function memoriserRang(&$table_rang, $tuple, &$rang) {
if (is_array($table_rang)) {
if (!in_array($tuple['rang'], $table_rang)) {
$rang = $tuple['rang'];
$table_rang[] = $rang;
if ($this->parametres['retour.format'] == 'max') {
$rang = $this->ajouterSignificationCode('rang', $rang);
}
}
}
}
 
public function ajouterHybrideChimere($groupe, &$rang, &$tuple) {
if (isset($this->table_retour[$rang][str_replace('hybride', 'hyb', $groupe)])) {
$this->table_retour[$rang][$groupe] += floatval($tuple['nb']);
} else {
$this->table_retour[$rang][$groupe] = floatval($tuple['nb']);
}
}
 
//-----------------------------Fonctions d'affichage utiliser dans les fonctions de formatage---------------------------
 
public function afficherDonnees($champApi, $valeur) {
$champBdd = $this->trouverChampBddCorrespondant($champApi);
if ($this->parametres['retour.format'] == 'min') {
if ($champApi == 'nom_sci') {
$valeur = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req);
}
if ($champApi == 'nom_sci_html') {
$valeur = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req, 'htm');
}
$this->table_retour[$champBdd] = $valeur;
} else {
$this->afficherToutesLesInfos($champBdd, $valeur);
}
}
 
public function trouverChampBddCorrespondant($champApi) {
if (array_key_exists($champApi, $this->champs_api)) {
$champBdd = $this->correspondance_champs[$champApi];
} else {
$champBdd = $champApi;
}
return $champBdd;
}
 
public function afficherToutesLesInfos($nom_champ_api, $valeur) {
if ($this->presentePlusieursId($nom_champ_api, $valeur)) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'details', $valeur);
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif (strrpos($nom_champ_api, 'parent') !== false && strrpos($nom_champ_api, 'notes') !== false) {
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif (($this->correspondAUnId($nom_champ_api) || $nom_champ_api == 'id' && $valeur != '0')) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'id,signification,href', $valeur);
 
} elseif ($this->correspondAUnCode($nom_champ_api)) {
preg_match('/^([^.]+)(?:\.code)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'code,signification,href', $valeur);
 
} elseif ($nom_champ_api == 'nom_sci_html') {
$this->table_retour['nom_sci_html'] = $valeur;
$this->table_retour['nom_sci_html_complet'] = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req, 'htm');
}elseif ($nom_champ_api != 'nom_sci') {
$this->table_retour[$nom_champ_api] = $valeur;
}
}
 
public function presentePlusieursId($ressource, $valeur = null) {
if ($valeur) {
$presente = strrpos($ressource, 'proparte') !== false && strrpos($valeur, ',') !== false;
} else { //pour la vérification du champ, on ignore alors la valeur de la ressource
$presente = strrpos($ressource, 'proparte') !== false;
}
return $presente;
}
 
public function afficherInfosPrecises($champ, $suffixe, $valeur) {
$suffixes = explode(',', $suffixe);
//on initialise au service appelé. Sera potentiellement modifié dans la fonction afficherSignification()
$this->service_href = $this->service;
foreach ($suffixes as $suffixe) {
switch ($suffixe) {
case 'id' :
$this->table_retour[str_replace('id.id', 'id', $champ.'.id')] = $valeur;
break;
case 'details' :
$this->afficherTableDetails($champ, $valeur);
break;
case 'signification' :
$this->afficherSignification($champ, $valeur);
break;
case 'href' :
$url = $this->creerUrl($champ, $valeur);
$this->table_retour[str_replace('id.href', 'href', $champ.'.href')] = $url;
break;
case 'code' :
$this->table_retour[$champ.'.code'] = $this->obtenirCode($champ, $valeur);
break;
case 'notes' :
$this->table_retour[$champ.'.notes'] = $this->resultat_req[str_replace('.', '_', $champ).'_notes'];
break;
default : break;
}
}
}
 
public function afficherTableDetails($nom_champ_api, $valeur) {
$tab_id = explode(',', $valeur);
$tab_res = $this->table_retour;
$this->table_retour = array();
foreach ($tab_id as $id) {
$this->afficherInfosPrecises($nom_champ_api, 'id,signification,href', $id);
$tab_res[$nom_champ_api.'.details'][] = $this->table_retour;
$this->table_retour = array();
}
$this->table_retour = $tab_res;
}
 
private function obtenirCode($champ, $valeur) {
$code = $this->transformerChampEnCode($champ);
return "bdnt.$code:$valeur";
}
 
private function transformerChampEnCode($champ) {
if (is_null($this->relationsChampsCodesOntologie)) {
$this->relationsChampsCodesOntologie = Outils::recupererTableauConfig('ChampsCodesOntologie');
}
 
$code = $champ;
if (array_key_exists($champ, $this->relationsChampsCodesOntologie)) {
$code = $this->relationsChampsCodesOntologie[$champ];
}
return $code;
}
 
public function creerUrl($champ, $valeur) {
if ($this->correspondAUnId($champ) || $champ == 'id') {
$service = $this->service_href;
$url = $this->ajouterHref($service, $valeur);
} else {
$code = $this->transformerChampEnCode($champ);
$url = $this->ajouterHrefAutreProjet('ontologies', "$code:", $valeur, 'bdnt');
}
return $url;
}
 
public function afficherSignification($champ, $valeur) {
if ($champ == 'id' && isset($this->resultat_req['nom_sci']) && $this->resultat_req['num_nom'] == $valeur) {
//si le nom_sci du num_nom que l'on veut afficher est déjà dans la table de résultat :
$this->table_retour['nom_sci'] = $this->resultat_req['nom_sci'];
$this->table_retour['nom_sci_complet'] = $this->resultat_req['nom_sci'].' '.
$this->ajouterCompositionNom($this->resultat_req);
} elseif ($this->correspondAUnId($champ) || $champ == 'id') {
$nom = $this->recupererNomSci($valeur);
if ($nom != array()) {
$this->table_retour[$champ.'.libelle'] = $nom['nom_sci'];
$this->table_retour[$champ.'_html'] = $nom['nom_sci_html'];
$this->table_retour[$champ.'_complet'] = $nom['nom_sci_complet'];
$this->table_retour[$champ.'_html_complet'] = $nom['nom_sci_complet_html'];
$this->service_href = $nom['service'];
}
} elseif ($this->correspondAUnCode($champ)) {
$this->table_retour[$champ.'.libelle'] = $this->ajouterSignificationCode($champ, $valeur);
}
}
 
/** Permet d'afficher les élements nomenclatural du nom_sci lors de l'appel dans le service noms/id/champ du champ^nom_sci.*/
public function afficherNomSciPointEpithete($resultat) {
$tab_nom_sci = array('nom_supra_generique', 'genre', 'epithete_infra_generique', 'epithete_sp',
'type_epithete', 'epithete_infra_sp', 'cultivar_groupe', 'cultivar', 'nom_commercial');
foreach ($tab_nom_sci as $compo_nom) {
if (isset($resultat[$compo_nom]) && !empty($resultat[$compo_nom])) {
$this->table_retour['nom_sci.'.$compo_nom] = $resultat[$compo_nom];
}
}
}
 
public function ajouterSignificationCode($champ, $valeur) {
if($this->termeOntologieEstEnCache($champ, $valeur)) {
$nom_code = $this->obtenirTermeOntologieParCache($champ, $valeur);
} else {
$code = $this->transformerChampEnCode($champ);
if (preg_match('/^([^_-]+)(?:_|-)([^_-]+)$/', $code, $match)) {
$code = $match[1].ucfirst($match[2]);
}
$url = Config::get('url_ontologie').$code.':'.$valeur.'/nom';
$res = $this->consulterHref($url); //dans commun.php
$nom_code = $valeur;
if (is_object($res)) {
$nom_code = $res->nom;
}
$this->mettreEnCacheOntologie($champ, $valeur, $nom_code);
}
return $nom_code;
}
 
public function recupererNomSci($id) {
$nom = array();
if ($id != 0) {
if ($this->compo_nom == null) {
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html FROM '.$this->table.' WHERE num_nom = '.$id;
} else { //on ajoute à la requete sql, les champs de ns.structure
//print_r($this->compo_nom);
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html, '.implode(', ', $this->compo_nom)
.' FROM '.$this->table
.' WHERE num_nom = '.$id;
}
if ($this->parametres['ns.format'] == 'htm') {
$req = str_replace('nom_sci', 'nom_sci_html as nom_sci', $req);
}
$res = $this->getBdd()->recuperer($req);
if ($res) {
$nom['nom_sci'] = $res['nom_sci'];
$nom['nom_sci_html'] = $res['nom_sci_html'];
$nom['nom_sci_complet'] = $res['nom_sci'].' '.$this->ajouterCompositionNom($res);
$nom['nom_sci_complet_html'] = $res['nom_sci_html'].' '.$this->ajouterCompositionNom($res, 'htm');
$nom['service'] = ($res['num_nom_retenu'] == $id && $this->service == 'taxons') ? 'taxons' : 'noms';
}
}
return $nom;
}
 
/** Permet de retourner une chaine de caractère composée des parametres du nom (ns.structure : annnée, auteur,
* bibilio et addendum). A ajouter au nom scientifique */
public function ajouterCompositionNom($tab_res, $format = '') {
$format = ($format == '') ? $this->parametres['ns.format'] : $format;
 
$nom = '';
if (isset($this->compo_nom)) {
if ($format == 'htm') {
$format = array(
'au' => '<span class="auteur">%s</span>',
'an' => '[<span class="annee">%s</span>]',
'an_bib' => '[<span class="annee">%s</span>, <span class="biblio">%s</span>]',
'bib' => '[<span class="biblio">%s</span>]',
'ad' => '[<span class="adendum">%s</span>]');
} else {
$format = array(
'au' => '%s',
'an' => '[%s]',
'an_bib' => '[%s, %s]',
'bib' => '[%s]',
'ad' => '[%s]',
'gen' => '%s',
'sp' => '%s',
'ssp' => '%s',
'fam' => '%s',
'au_ss' => '%s',
'bib_ss' => '%s');
}
$compo_nom = array();
 
foreach ($this->compo_nom as $key => $champ) {
if (isset($tab_res[$champ]) && !empty($tab_res[$champ])) {
$compo_nom[$key] = $tab_res[$champ];
}
}
$nom_complet = $this->formerNomComplet($compo_nom, $format);
$nom = implode(' ', $nom_complet);
}
return rtrim($nom, ' ');
}
 
 
public function formerNomComplet($compo_nom, $format) {
$nom_complet = array();
extract($compo_nom);
if (isset($au)) $nom_complet[] = sprintf($format['au'], $au);
if (isset($an)) {
if (isset($bib)) {
$nom_complet[] = sprintf($format['an_bib'], $an, $bib);
} else {
$nom_complet[] = sprintf($format['an'], $an);
}
} elseif (isset($bib)) {
$nom_complet[] = sprintf($format['bib'], $bib);
}
if (isset($ad)) $nom_complet[] = sprintf($format['ad'], $ad);
if (isset($gen)) $nom_complet[] = sprintf($format['gen'], $gen);
if (isset($ssp)) $nom_complet[] = sprintf($format['ssp'], $ssp);
if (isset($sp)) $nom_complet[] = sprintf($format['sp'], $sp);
if (isset($fam)) $nom_complet[] = sprintf($format['fam'], $fam);
if (isset($au_ss)) $nom_complet[] = sprintf($format['au_ss'], $au_ss);
if (isset($bib_ss)) {
$bibl = $this->tronquerBiblio($bib_ss);
//simule un 'select distinct' sur les biblio tronquées
if (!isset($this->bib_traitees[$bibl])) {
$nom_complet[] = sprintf($format['bib_ss'],$bibl );
$this->bib_traitees[$bibl] = 1;
}
}
return $nom_complet;
}
 
public function tronquerBiblio($valeur){
$bib = '';
if(strpos($valeur,',') !== false) {
$bib = explode(',',$valeur);
}
if(strpos($bib[0],';') !== false) {
 
$bib[0] = strstr($bib[0],';');
$bib[0] = str_replace('; ','',$bib[0]);
}
return $bib[0];
}
 
 
 
public function correspondAUnCode($key) {
return (strrpos($key, '.code') !== false) || (in_array($key.'.code', $this->correspondance_champs));
}
 
public function correspondAUnId($key) {
return (strrpos($key, '.id') !== false) || (in_array($key.'.id', $this->correspondance_champs));
}
 
public function estUnPoint($key) {
if (strrpos($key, 'hybride.parent') !== false) {
$key = str_replace('hybride.parent', 'hybride_parent', $key);
}
return (strrpos($key, '.') !== false);
}
 
public function recupererMasquePrincipal() {
$masque = null;
$tab_masque = array(
'masque' => 'nom_sci',
'masque_sg' => 'nom_supra_generique',
'masque_gen' => 'genre',
'masque_sp' => 'epithete_sp',
'masque_ssp' => 'epithete_infra_sp',
'masque_au' => 'auteur',
'masque_an' => 'annee',
'masque_bib' => 'biblio_origine',
'masque_ad' => 'addendum',
'masque_rg' => 'rang');
$liste_masque = array();
 
if (isset($this->masque['num_nom'])) {
$liste_masque[] = $this->masque['num_nom'];
}
 
foreach ($tab_masque as $key => $filtre) {
if (isset($this->masque[$filtre])) {
if (!isset($masque) && !in_array($filtre, array('rang', 'annee'))) {
$masque = array($key, $filtre);
}
$liste_masque[] = $this->masque[$filtre];
}
}
$this->masque = $liste_masque;
return $masque;
}
 
private function mettreEnCacheOntologie($categorie, $valeur, $correspondance) {
if(!isset($this->ontologie[$categorie])) {
$this->ontologie[$categorie] = array();
}
if(!isset($this->ontologie[$categorie][$valeur])) {
$this->ontologie[$categorie][$valeur] = array();
}
$this->ontologie[$categorie][$valeur] = $correspondance;
}
 
private function termeOntologieEstEnCache($categorie, $valeur) {
return array_key_exists($categorie, $this->ontologie) && array_key_exists($valeur, $this->ontologie[$categorie]);
}
 
private function obtenirTermeOntologieParCache($categorie, $valeur) {
return $this->ontologie[$categorie][$valeur];
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/isfan/Noms.php
New file
0,0 → 1,648
<?php
// declare(encoding='UTF-8');
/**
* Classe permettant de fournir des informations sur les noms scientifiques.
* Si l'url finit par /noms on retourne une liste de noms latin et leurs identifiants (seulement les 100 premeiers noms par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /noms?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, masque.gen (nom de genre), masque.sp (épithète d'espèce), masque.ssp (épithète infra-spécifique),
* masque.au (auteur du nom), masque.an (année de publication du nom), masque.bib (réf biblio de la publi d'origine du nom), masque.ad (nomen addendum),
* masque.nn (identifiant du nom), recherche, rang, distinct, retour.format, nl.format, nl.structure, navigation.depart et navigation.limite.
* Les différentes requetes :
* - noms | noms/relations/#projet/#id_projet | noms/#id | noms/#id/#champ+#champ
* - noms/#id/relations | noms/#id/relations/synonymie | noms/#id/relations/homonymie | noms/#id/relations/flores
* - noms/stats/rangs | noms/stats/annees | noms/stats/initiales
*
* @package bdtfx
* @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 $Id$
* @copyright 1999-2011 Tela Botanica (accueil@tela-botanica.org)
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Noms
*/
 
class Noms extends CommunNomsTaxons {
 
protected $format_reponse = 'noms'; // Permet de stocker la requete formulée
protected $service = 'noms';
protected $serviceNom = 'noms';
protected $requete_champ = 'num_nom, nom_sci, num_nom_retenu';
protected $requete_condition = null;
protected $requete_group_by = '';
/** Permet de stocker les limite de la requete SQL (par défaut seul les 100 premiers résultats seront retournés).*/
protected $limite_requete = array('depart' => 0, 'limite' => 100);
protected $distinct = null; // Valeur du paramètre de requete distinct (=0|1)
 
public function consulter($ressources, $parametres) {
return parent::consulter($ressources, $parametres);
}
 
//+----------------FONCTION D'ANALYSE DES PARAMETRES---------------------------------------------------------+
 
public function traiterParametresSpecifiques() {
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'masque' :
$champ = isset($this->parametres['recherche']) && ($this->parametres['recherche'] == 'etendue') ?
'CONCAT(nom_sci," ",auteur)' : 'nom_sci';
$this->ajouterFiltreMasque($champ, $val);
break;
case 'masque.sg' :
$this->ajouterFiltreMasque('nom_supra_generique', $val);
break;
case 'masque.gen' :
$this->ajouterFiltreMasque('genre', $val);
break;
case 'masque.sp' :
$this->ajouterFiltreMasque('epithete_sp', $val);
break;
case 'masque.ssp' :
$this->ajouterFiltreMasque('epithete_infra_sp',$val);
break;
case 'masque.au' :
$this->ajouterFiltreMasque('auteur', $val);
break;
case 'masque.an' :
$this->ajouterFiltreMasque('annee', $val);
break;
case 'masque.bib' :
$this->ajouterFiltreMasque('biblio_origine',$val);
break;
case 'masque.ad' :
$this->ajouterFiltreMasque('nom_addendum', $val);
break;
case 'masque.nn' :
$this->requete_condition []= 'num_nom IN ('.$val.')';
$this->masque['num_nom'] = "num_nom=$val";
break;
case 'masque.nt' :
$this->requete_condition []= 'num_taxonomique IN ('.$val.')';
$this->masque['num_tax'] = "num_taxonomique=$val";
break;
case 'masque.rg' :
$this->ajouterFiltreMasque('rang', $val);
break;
case 'retour.champs' :
$this->verifierParamChamps($param, $val);
break;
case 'distinct' :
$this->ajouterNomDistinct($val);
break;
case 'masque.fam' :
$this->ajouterFiltreMasque('famille', $val);
break;
case 'masque.sto' :
$this->ajouterFiltreMasque('statut_origine', $val);
break;
case 'masque.sti' :
$this->ajouterFiltreMasque('statut_introduction', $val);
break;
case 'masque.stc' :
$this->ajouterFiltreMasque('statut_culture', $val);
break;
case 'masque.and' :
$this->requete_condition []= " annee >= ".$this->getBdd()->proteger($val);
break;
case 'masque.anf' :
$this->requete_condition []= " annee <= ".$this->getBdd()->proteger($val);
break;
case 'masque.prgua' :
$this->ajouterFiltreMasque('presence_Guadeloupe', $val);
break;
case 'masque.prmar' :
$this->ajouterFiltreMasque('presence_Martinique', $val);
break;
case 'masque.prstm' :
$this->ajouterFiltreMasque('presence_Saint_Martin', $val);
break;
case 'masque.prdes' :
$this->ajouterFiltreMasque('presence_La_Desirade', $val);
break;
case 'masque.prstb' :
$this->ajouterFiltreMasque('presence_Saint_Barthelemy', $val);
break;
case 'masque.prmga' :
$this->ajouterFiltreMasque('presence_Marie_Galante', $val);
break;
case 'masque.prsai' :
$this->ajouterFiltreMasque('`presence_Les-Saintes`', $val);
break;
}
}
}
 
public function verifierParamChamps($param, $val) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$champs_demandes = explode(',', $val);
$champs_verifies = array();
$champs_api = array_flip($this->champs_api);
$champs_supp = array('nom_retenu_complet'=>'num_nom_retenu', 'basionyme_complet'=>'basionyme');
$champs_api = array_merge($champs_api, $champs_supp);
foreach ($champs_demandes as $champ) {
if (array_key_exists($champ, $champs_api)) {
$champs_verifies[] = $champs_api[$champ];
}
}
if (count($champs_verifies) > 0) {
$this->requete_champ .= ', '.implode(',', $champs_verifies);
}
}
 
/** Permet de rajouter à la requete sql le parametre distinct. N'est utilisé qu'avec le format oss */
public function ajouterNomDistinct($distinct) {
if (isset($distinct)) {
if ($distinct == 1 && $this->parametres['retour.format'] == 'oss') {
$this->distinct = ' distinct ';
} elseif ($distinct == 1 && $this->parametres['retour.format'] != 'oss') {
$e = 'Erreur dans votre requête </br> L\'utilisation du paramètre distinct ne se fait que sous
le format oss';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
}
 
//-----------------FONCTION D'ANALYSE DES RESSOURCES--------------------------------------------------------------------
 
public function traiterRessourcesIdentifiant() {
//on initialise la condition de la requete sql et le format de réponse
$this->requete_condition = array(); //on vide la table dans le cas de plusieurs version
$this->requete_condition[] = 'num_nom = '.$this->getBdd()->proteger($this->ressources[0]);
$this->format_reponse = $this->service.'/id';
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
if ($this->ressources[1] == 'relations') {
$this->traiterRessourceIdRelations();
} else {
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> noms/#id/relations </li> <li> noms/#id/#champ+#champ </li>
<li> noms/#id/relations/synonymie </li>
<li> noms/#id/relations/homonymie </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else { // requete de type noms/#id : rajout du nom_sci pour récupérer le format html par la fct mettreAuFormat()
$this->requete_champ = ' *, nom_sci ';
}
}
 
public function traiterRessourceRelations() {
$this->format_reponse .= '/relations';
$projet = $this->ressources[1];
$num_nom = $this->ressources[2];
if (strrpos($num_nom, 'nn.coste') !== false) {
list($p, $nn) = explode('=', $num_nom);
$num_nom = $nn;
}
$champ = "flore_$projet"."_num";
if (isset($this->ressources[3])) {
$type = $this->ressources[3];
if (!in_array($type, array('homonymie', 'synonymie'))) {
$e = "Les types disponibles pour les noms sont homonymie, synonymie";
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
$this->requete_champ = ' num_nom ';
$this->requete_condition = array();
$this->requete_condition[] = "$champ = ".$this->getBdd()->proteger($num_nom);
}
 
public function traiterRessourceIdRelations() {
$this->format_reponse .= '/relations';
if (isset($this->ressources[2]) && !empty($this->ressources[2])) {
// requete de type noms/#id/relations/#relation
switch ($this->ressources[2]) {
case 'synonymie' :
$this->traiterRessourceIdSynonymie();
break;
case 'homonymie' :
$this->traiterRessourceIdHomonymie();
break;
default :
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> noms/#id/relations </li> <li> noms/#id/relations/synonymie </li>
<li> noms/#id/relations/homonymie </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
}
}
 
public function traiterRessourceIdSynonymie() {
// SELECT num_nom, nom_sci, num_nom_retenu, basionyme FROM bdtfx_v2_00 WHERE num_nom = X LIMIT 0,100;
$this->format_reponse .= '/synonymie';
if (strrpos($this->requete_champ, ', basionyme') === false) {
$this->requete_champ .= ', basionyme ';
}
if (strrpos($this->requete_champ, ', num_type') === false) {
$this->requete_champ .= ', num_type ';
}
$this->requete_condition[0] = 'num_nom_retenu = '.
'(SELECT num_nom_retenu FROM '.$this->table.' WHERE '.$this->requete_condition[0].')';
}
 
public function traiterRessourceIdHomonymie() {
// SELECT num_nom, nom_sci, num_nom_retenu FROM bdtfx_v2_00 WHERE nom_sci = (SELECT nom_sci FROM bdtfx_v2_00 WHERE num_nom = X);
$this->format_reponse .= '/homonymie';
$this->requete_condition[0] = 'nom_sci = (SELECT nom_sci FROM '.$this->table
.' WHERE '.$this->requete_condition[0].')';
}
 
public function traiterRessourceStatsRangs() {
// SELECT count(*) as nombre, rang FROM bdtfx_v2_00 [WHERE rang = 290] GROUP BY rang ORDER BY rang;
$this->format_reponse .= '/rangs';
$this->requete_champ = 'count(*) as nombre, rang ';
$this->requete_group_by = ' GROUP BY rang ORDER BY rang ';
}
 
public function traiterRessourceStatsAnnees() {
// SELECT count(*) as nombre, annee FROM bdtfx_v2_00 GROUP BY annee ORDER BY annee;
$this->format_reponse .= '/annees';
$this->requete_champ = 'count(*) as nombre, annee ';
$this->requete_condition = null;
$this->requete_group_by = ' GROUP BY annee ORDER BY annee ';
}
 
public function traiterRessourceStatsInitiales() {
// SELECT count(left( nom_sci, 2 )) as nb, rang, left(nom_sci, 2) as lettre GROUP BY rang, left(nom_sci, 2);
$this->format_reponse .= '/initiales';
$this->requete_champ = 'count(left( nom_sci, 2 )) as nb, rang, left(nom_sci, 2) as lettre ';
$this->requete_group_by = ' GROUP BY rang, left(nom_sci, 2)';
}
 
//-----------------------------FONCTIONS DASSEMBLAGE DE LA REQUETE-----------------------------------------------------
 
public function assemblerLaRequete() {
if ( strrpos($this->format_reponse, 'noms/stats/') === false ) {
$this->mettreAuFormat(); //Ds CommunNomsTaxons.php
}
$requete = 'SELECT '.$this->retournerChamps().' '.
"FROM {$this->table} ".
$this->retournerRequeteCondition().' '.
$this->requete_group_by.' '.
$this->retournerOrderBy().' '.
$this->formerRequeteLimite();
return $requete;
}
 
public function retournerChamps() {
$sql = '';
if ($this->distinct) {
$sql .= $this->distinct.' ';
}
if ($this->requete_champ) {
$sql .= $this->requete_champ.' ';
}
 
// Champs "virtuels" pour tier sur l'ensemble des résultats
if (isset($this->parametres['retour.tri'])) {
list($champ, $ordre) = $this->decouperParametreRetourTri();
if ($champ == 'retenu') {
$sql .= ", IF(num_nom = num_nom_retenu, '0', '1') AS nom_retenu_tri ";
}
}
 
return $sql;
}
 
public function decouperParametreRetourTri() {
$tri = array('', '');
if (isset($this->parametres['retour.tri'])) {
if (preg_match('/^(retenu)(?:,(ASC|DESC)|)$/', $this->parametres['retour.tri'], $match))
$tri[0] = $match[1];
$tri[1] = isset($match[2]) ? $match[2] : '';
}
return $tri;
}
 
public function retournerRequeteCondition() {
$condition = '';
if ($this->requete_condition) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
 
public function retournerOrderBy() {
$orderBy = array();
 
// Tri sur l'ensemble des résultats
if (isset($this->parametres['retour.tri'])) {
list($champ, $ordre) = $this->decouperParametreRetourTri();
if ($champ == 'retenu') {
$orderBy[] = "nom_retenu_tri $ordre";
}
}
// Tri par défaut
if ($this->format_reponse == 'noms') {
$orderBy[] = 'nom_sci ASC';
}
 
$sql = '';
if (count($orderBy) > 0) {
$sql = 'ORDER BY '.implode(', ', $orderBy).' ';
}
return $sql;
}
 
public function formerRequeteLimite() {
if ($this->format_reponse != 'noms' && $this->format_reponse != 'noms/id/relations/synonymie'
&& $this->format_reponse != 'noms/id/relations/homonymie') {
$this->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
$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;
}
 
/** Recupere le nombre total de résultat d'une requete lancée. */
public function recupererTotalResultat() {
$total = null;
$requete = 'SELECT count(*) as nombre FROM '.$this->table.$this->retournerRequeteCondition().$this->requete_group_by;
$res = $this->getBdd()->recuperer($requete);
if ($res) {
$total = $res['nombre'];
} else {
$e = 'Fct recupererTotalResultat() : <br/>Données introuvables dans la base';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
}
return $total;
}
 
 
//-------------------FONCTIONS POUR LE FORMATAGE EN JSON----------------------------------------------------------------
 
public function retournerResultatFormate($resultat) {
switch ($this->format_reponse) {
case 'noms/relations' :
$reponse = $this->formaterRelations($resultat[0]);
break;
case 'noms/id' : //ds CommunNomsTaxons
$reponse = $this->formaterId($resultat[0]);
break;
case 'noms/id/relations' :
$reponse = $this->formaterIdRelations($resultat[0]);
break;
case 'noms/id/relations/synonymie' :
$reponse = $this->formaterIdSynonymie($resultat);
break;
case 'noms/id/relations/homonymie' :
$reponse = $this->formaterIdHomonymie($resultat);
break;
case 'noms/stats/annees' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsAnnee($resultat);
break;
case 'noms/stats/rangs' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsRang($resultat);
break;
case 'noms/stats/initiales' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsInitiales($resultat);
break;
case 'noms' :
$reponse = $this->formaterNoms($resultat);
break;
}
return $reponse;
}
 
//+---------------------concerne les resultats pour des requetes de type noms/id-----------------------------+
 
public function formaterRelations($resultat) {
$num_nom = $resultat['num_nom'];
if (isset($this->ressources[3])) {
$url = Config::get('url_service').$this->service."/$num_nom/relations";
} else {
$type = $this->ressources[3];
$url = Config::get('url_service')."/$this->service/$num_nom/relations/$type";
}
$res = $this->consulterHref($url);
return $res;
}
 
public function formaterIdRelations($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
$retour_id_rel = array ('entete' => array()); //on initialise pr que l'entete apparaisse en premier lors de l'affichage
 
//on recupère le resultat de chaque relation (appel du WS correspondant)
$homonymes = $this->ajouterRelations('homonymie');
if (isset($homonymes)) $retour_id_rel['resultat']['homonymes'] = $homonymes;
$synonymes = $this->ajouterRelations('synonymie');
if (isset($synonymes)) $retour_id_rel['resultat']['synonymes'] = $synonymes;
 
//on renvoit null si il n'existe aucune relations (on efface l'entete en premier lieu)
if (!isset($retour_id_rel['resultat'])) {
$retour_id_rel = null;
} else { //on rajoute l'entete si des relations existent
$this->afficherDonnees('num_nom', $this->ressources[0]);
$retour_id_rel['entete'] = $this->table_retour;
$this->table_retour = array();
}
return $retour_id_rel;
}
 
/**
* Recupere les relations (type de la relation passée en paramètres :[type_relation] = synonymie, homonymie ou
* ) par l'appel du web service [version]/noms/#id/relations/[type_relation]
*/
public function ajouterRelations($relation) {
$version = str_replace(Config::get('bdd_table').'_', '', $this->table);
$res = null;
$parametres_url = '';
if ($this->parametres != array()) $parametres_url = '?'.http_build_query($this->parametres, '', '&');
$url = Config::get('url_service').'/'.$this->service.'/'.
$this->ressources[0].'/relations/'.
$relation.$parametres_url;
 
$relation = $this->consulterHref($url);
 
$res = $relation->resultat;
return $res;
}
 
 
public function formaterIdSynonymie($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$retour_id_syn = array();
if ($resultat[0]['num_nom_retenu'] == '') {
$retour_id_syn[] = 'nom_retenu N.D.';
} elseif (count($resultat) != 1) {
//on remplit d'abord l'entete du resultat
$this->table_retour['id'] = $this->ressources[0];
$this->afficherEnteteResultat('/'.$this->service.'/'.$this->ressources[0].'/relations/synonymie');
$retour_id_syn['entete'] = $this->table_retour;
$this->table_retour = array();
foreach ($resultat as $tab) {
//pour chaque basionyme, on recupère le résultat : num_nom, nom_sci, basionyme et num_nom_retenu :
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('basionyme', $tab['basionyme']);
$retour_id_syn['resultat'][$num] = $this->table_retour;
$this->table_retour = array();
}
if (!isset($retour_id_syn['resultat']) && !in_array('nom_retenu N.D.', $retour_id_syn)) {
$retour_id_syn = null; //on initialise le resultat à null
}
}
return $retour_id_syn;
}
 
public function formaterIdHomonymie($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
if (count($resultat) != 1) {
$this->table_retour['id'] = $this->ressources[0];
$this->afficherEnteteResultat($resultat, '/'.$this->service.'/'.$this->ressources[0].'/relations/homonymie');
$retour_id_hom['entete'] = $this->table_retour;
$this->table_retour = array();
foreach ($resultat as $homonyme) {
$this->resultat_req = $homonyme;
$id = $homonyme['num_nom'];
$this->afficherDonnees('num_nom', $id);
if ($homonyme['num_nom_retenu'] != '') {
$retenu = ($id == $homonyme['num_nom_retenu']) ? 'true' : 'false';
} else {
$retenu = 'absent';
}
$this->table_retour['retenu'] = $retenu;
$retour_id_hom['resultat'][$id] = $this->table_retour;
unset($retour_id_hom['resultat'][$id]['id']);
$this->table_retour = array();
}
} else {
$retour_id_hom = null;
}
return $retour_id_hom;
}
 
public function obtenirSynonymesParNumNomAvecInfosFlore($num_nom, $version='1_02') {
 
$champs_flore = 'flore_bonnier_num, flore_bonnier_rem,'.
'flore_cnrs_num, flore_cnrs_rem '.
'flore_fe_num, flore_fe_rem '.
'flore_coste_num, flore_coste_rem '.
'flore_fh_num, flore_fh_rem '.
'flore_fournier_num, flore_fournier_rem';
 
$requete = 'SELECT num_nom, nom_sci, '.$champs_flore.' '.
'FROM '.$this->table.' '.
'WHERE num_nom_retenu = '.
'('.
'SELECT num_nom_retenu FROM '.$this->table.' WHERE num_nom = "'.$num_nom.'"'.
')';
 
return $this->getBdd()->recupererTous($requete);
}
 
//+---------------------concerne les resultats pour des requetes de type /noms avec ou sans paramètres-------+
 
public function formaterNoms($resultat) {
if ($this->parametres['retour.format'] == 'oss') {
$reponse = $this->formaterEnOss($resultat); //Ds CommunNomsTaxons.php
} else {
$reponse = $this->formaterEnJsonMax($resultat);
}
return $reponse;
}
 
public function formaterEnJsonMax($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
 
// TODO : améliorer le tri des résultats
// ATTENTION : ce comportement est étrange
$masque = $this->recupererMasquePrincipal();
if (isset($masque) && !isset($this->parametres['retour.tri'])) {
// fonction du pauvre pour palier aux "." remplacés accidentellement par des "_"
$index = str_replace('masque_','masque.',$masque[0]);
//$resultat = $this->trierRechercheFloue($this->parametres[$index], $resultat, $masque[1]);
}
 
// Tri à la mode du CeL : lexicographique puis noms retenus (retour.tri = "alpharet")
if (isset($this->parametres['retour.tri']) && ($this->parametres['retour.tri'] == "alpharet")) {
usort($resultat, array($this, 'genrePuisNomsRetenusEnTete'));
}
 
$table_retour_json['entete'] = $this->remplirJsonEntete();
$table_retour_json['resultat'] = $this->remplirJsonResultat($resultat);
return $table_retour_json;
}
 
// Trie les éléments du tableau de résultats : le genre en tête, puis les noms retenus, puis le reste
// mais à partir du jeu de données retourné par SQL (indépendents du statut "retenu")
private function genrePuisNomsRetenusEnTete($a, $b) {
// On pourrait utiliser l'indice ['retenu'] mais il contient parfois "absent", qui est dur à traiter
$aEstRetenu = ($a['num_nom'] == $a['num_nom_retenu']);
$bEstRetenu = ($b['num_nom'] == $b['num_nom_retenu']);
$retour = 0;
 
// les noms retenus en premier ("inférieurs")
if ($aEstRetenu) {
if (! $bEstRetenu) {
$retour = -1;
}
} else {
if ($bEstRetenu) {
$retour = 1;
}
}
 
// en cas d'égalité on conserve le tri lexicographique - devrait faire sortir le genre en première position
// car il ne contient pas le nom d'auteur
if ($retour == 0) {
$retour = strcasecmp($a['nom_sci'], $b['nom_sci']);
}
 
return $retour;
}
 
public function remplirJsonResultat($resultat) {
$champs = null;
if (array_key_exists('retour.champs', $this->parametres)) {
$champs = explode(',', $this->parametres['retour.champs']);
}
 
// Structure des données: objet ou liste ?
$modeListe = false;
if (array_key_exists('retour.structure', $this->parametres)) {
$modeListe = ($this->parametres['retour.structure'] === "liste");
}
 
$noms = array();
foreach ($resultat as $tab) {
$this->table_retour = array();
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num); // ajoute le nom_sci, href et si le nom est retenu dans $this->table_retour
$retour = $this->table_retour;
$this->table_retour = array();
if ($champs != null) {
$reponse_id = $this->formaterId($tab);
$this->table_retour = array();
$this->ajouterChampsPersonnalises($champs, $reponse_id);
$retour = array_merge($retour, $this->table_retour);
}
if ($modeListe) {
$retour['num_nom'] = intval($num);
$noms[] = $retour;
} else {
$noms[$num] = $retour;
}
}
 
return $noms;
}
 
public function remplirJsonEntete() {
$entete = array();
if (isset($this->masque)) {
$this->table_retour['masque'] = implode('&', $this->masque);
}
parent::afficherEnteteResultat('/'.$this->service);
return $this->table_retour;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/isfan/Taxons.php
New file
0,0 → 1,522
<?php
 
// declare(encoding='UTF-8');// ou ISO-8859-15
/**
* Description :
* Classe Taxons.php permettant de fournir des informations sur les noms scientifiques retenu.
* Si l'url finit par /taxons on retourne une liste de noms latin et leurs identifiants (seulement les 100 premeiers noms par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /taxons?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, recherche, rang, distinct, retour.format, nl.format,
* nl.structure, 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 Taxons extends CommunNomsTaxons {
/** Permet de stocker la requete formulée taxons | taxons/#id | taxons/#id/#champ+#champ ...*/
protected $format_reponse = 'taxons';
protected $service = 'taxons';
protected $requete_champ = 'num_nom, nom_sci, num_nom_retenu, num_taxonomique, rang ';
protected $requete_condition = null;
protected $requete_group_by = ' ';
/** Permet de stocker les limite de la requete SQL (par défaut seul les 100 premiers résultats seront retournés).*/
protected $limite_requete = array('depart' => 0, 'limite' => 100);
protected $num_nom_taxon; //Stocke le num_nom du nom retenu du num_nom recherché
protected $presence_num_tax = true;
public function consulter($ressources, $parametres) {
return parent::consulter($ressources, $parametres);
}
public function traiterParametresSpecifiques() {
$this->requete_condition[] = 'num_nom = num_nom_retenu';
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'masque' :
$this->ajouterFiltreMasque('nom_sci', $val);
break;
case 'masque.nt' :
$this->requete_condition[] = "num_taxonomique IN ($val)";
$this->masque[] = "num_taxonomique=$val";
break;
case 'masque.rg':
$this->requete_condition[] = 'rang = '.$this->getBdd()->proteger($val);
$this->masque[] = "rang=$val";
break;
}
}
}
//------------------------------------------Fonction ressources---------------------------------------------------------------------
public function gererNumTax() {
if (!in_array('num_taxonomique', $this->champs_table)) {
$this->presence_num_tax = false;
$this->requete_champ = str_replace(', num_taxonomique ', '', $this->requete_champ);
} else {
$this->presence_num_tax = true;
}
}
public function traiterRessourcesIdentifiant() {
$this->format_reponse = 'taxons/id';
$this->traiterRessourceNtId();
$this->num_nom_taxon = $this->recupererNumNomTaxon(); //on recupere le taxon correspondant au num_nom recherché
if ($this->entete_http == '') {
$this->requete_condition[0] = 'num_nom = '.$this->getBdd()->proteger($this->num_nom_taxon);
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
//---------------- requete de type taxons/#id/#champ+#champ--------------------------------------
if ($this->ressources[1] != 'relations') { // SELECT *, nom_sci FROM bftfx_v2_00 WHERE num_nom = X;
$this->requete_champ = ' *, nom_sci ';
$this->format_reponse .= '/champ';
//---------------- requete de type taxons/#id/relations/#relation--------------------------------
} elseif ($this->ressources[1] == 'relations') {
$this->traiterRessourceIdRelations();
} else {
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> #id/relations </li> <li> #id/#champ+#champ </li> <li> #id/relations </li>
<li> #id/relations/inferieurs </li> <li> #id/relations/superieurs </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else { //--------------- requete de type taxons/#id-----------------------------------------------------
$this->requete_champ = ' *, nom_sci ';
}
}
}
public function traiterRessourceNtId() {
if (strrpos($this->ressources[0], 'nt:') !== false) {
if ($this->presence_num_tax) {
// SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = num_nom_retenu AND num_taxonomique = X;
$this->requete_condition[0] = ' num_taxonomique = '
.str_replace('nt:', '', $this->ressources[0]).' ';
} else {
$e = 'Erreur dans votre requête : </br> Le numéro taxonomique n\'existe pas dans ce projet';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else {
// SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = (SELECT num_nom_retenu FROM bdtfx_v2_00 WHERE num_nom = X);
$this->requete_condition[0] = 'num_nom = '.$this->ressources[0];
}
}
/** Permet de récupérer le num_nom du taxon recherché. Soit le numéro taxonomique est demandé (avec nt: )
* soit un num_nom dont on recherche le num_nom_retenu */
public function recupererNumNomTaxon() {
$identifiant = '';
if ($this->entete_http == '') {
//on récupere l'identifiant du taxon correspondant au num_nom ou num_taxonomique demandé pour pouvoir l'afficher
$req_tax = 'SELECT num_nom_retenu FROM '.$this->table.' WHERE '.$this->requete_condition[0];
$res_tax = $this->getBdd()->recuperer($req_tax);
//on recherche ensuite les identifiants des taxons supérieurs ou inférieurs
if ($res_tax && $res_tax != '') {
$identifiant = $res_tax['num_nom_retenu'];
} else {
$e = 'Le numéro de taxon ou l\'identifiant de nom correspondant au num_nom '
.$this->ressources[0].' n\'existe pas dans la base.';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
Debug::printr($req_tax);
}
}
return $identifiant;
}
public function traiterRessourceIdRelations() {
//----------------- requete de type taxons/#id/relations-------------------------------------------
// SELECT *, nom_sci FROM bftfx_v2_00 WHERE num_nom = X;
$this->format_reponse .= '/relations';
if (isset($this->ressources[2]) && !empty($this->ressources[2])) {
//------------- requete de type taxons/#id/relations/#relation--------------------------------
switch ($this->ressources[2]) {
case 'superieurs' :
$rel = 'recupererIdSup';
$this->format_reponse .= '/superieurs';
$this->traiterRessourceIdRelationInfSup($rel);
break;
case 'inferieurs' :
$rel = 'recupererIdInf';
$this->format_reponse .= '/inferieurs';
$this->traiterRessourceIdRelationInfSup($rel);
break;
case 'hierarchie' :
$rel = 'recupererIdHierarchie';
$this->format_reponse .= '/hierarchie';
$this->traiterRessourceIdRelationHierarchie($rel);
break;
default :
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> taxons/#id/relations </li><li> #id/relations/inferieurs </li>
<li> #id/relations/superieurs </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
}
}
public function traiterRessourceIdRelationHierarchie($rel) {
//Appel de la fct récupérerIdSup ou recupererIdInf : retourne les num_nom des noms inferieurs ou superieurs
$res_relation = $this->$rel();
//analyse du résultat retourné par la requete de recherche des identifiants correspondant aux taxons inf|sup :
if ($res_relation == '') {
//dans le cas ou la requete comporte des erreurs
$e = 'Fct traiterRessourceIdRelationInfSup : La requête forme comporte une erreur!';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
} elseif ($res_relation) {
//dans le cas ou une ou plusieurs relations est retournée, on récupère les identifiants ss la forme (id, id, id)
foreach ($res_relation as $ligne) $res[] = $ligne['num_nom'];
$res = implode(',',$res);
$this->requete_condition[0] = "num_nom IN ($res)";
$this->requete_champ .= ', rang, num_tax_sup ';
} else { //dans le cas ou aucune relation n'existe
$res = array($this->num_nom_taxon => null);
$this->corps_http = json_encode($res);
$this->entete_http = RestServeur::HTTP_CODE_OK;
}
}
public function recupererIdHierarchie() {
$req_relation = 'SELECT num_nom FROM '.$this->table.' '.
' WHERE hierarchie LIKE CONCAT('.
'(SELECT hierarchie FROM '.
$this->table.' '.
'WHERE num_nom = '.$this->getBdd()->proteger($this->num_nom_taxon).')'.
', '.$this->getBdd()->proteger($this->num_nom_taxon.'-%').
')';
$res_relation = $this->getBdd()->recupererTous($req_relation);
return $res_relation;
}
public function traiterRessourceIdRelationInfSup($rel) {
//Appel de la fct récupérerIdSup ou recupererIdInf : retourne les num_nom des noms inferieurs ou superieurs
$res_relation = $this->$rel();
//analyse du résultat retourné par la requete de recherche des identifiants correspondant aux taxons inf|sup :
if ($res_relation == '') { //dans le cas ou la requete comporte des erreurs
$e = 'Fct traiterRessourceIdRelationInfSup : La requête forme comporte une erreur!';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
} elseif ($res_relation) {
//dans le cas ou une ou plusieurs relations est retournée, on récupère les identifiants ss la forme (id, id, id)
foreach ($res_relation as $ligne) $res[] = $ligne['num_nom'];
$res = implode(',',$res);
$this->requete_condition[0] = "num_nom IN ($res)";
$this->requete_champ .= ', rang, num_tax_sup ';
} else { //dans le cas ou aucune relation n'existe
$res = array($this->num_nom_taxon => null);
$this->corps_http = json_encode($res);
$this->entete_http = RestServeur::HTTP_CODE_OK;
}
}
public function recupererIdInf() {
//SELECT num_nom FROM bfdtx_v2_00 WHERE num_tax_sup = (SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = X);
$req_relation = 'SELECT num_nom FROM '.$this->table
.' WHERE num_nom = num_nom_retenu AND num_tax_sup = (SELECT num_nom FROM '
.$this->table
.' WHERE '.implode(' AND ', $this->requete_condition).')';
$res_relation = $this->getBdd()->recupererTous($req_relation);
return $res_relation;
}
public function recupererIdSup() {
//SELECT num_nom FROM bfdtx_v2_00 WHERE num_nom = (SELECT num_tax_sup FROM bdtfx_v2_00 WHERE num_nom = X);
$this->requete_condition[] = "num_nom = num_nom_retenu" ;
$req_relation = 'SELECT num_tax_sup as num_nom FROM '.$this->table
.' WHERE '.implode(' AND ', $this->requete_condition);
$res_relation = $this->getBdd()->recupererTous($req_relation);
return $res_relation;
}
 
public function traiterRessourceStatsInitiales() {
// SELECT count(nom_sci) as nb, rang, left(nom_sci, 2) as lettre FROM bdtfx_v2_00 GROUP BY rang, left(nom_sci, 2);
$this->format_reponse = 'taxons/stats/initiales';
$this->requete_champ = 'count(nom_sci) as nb, rang, left(nom_sci, 2) as lettre ';
$this->requete_group_by = ' GROUP BY rang, left(nom_sci, 2) ';
}
public function traiterRessourceStatsRangs() {
// SELECT count(*) as nombre, rang FROM bdtfx_v2_00 [WHERE rang = 290] GROUP BY rang ORDER BY rang;
$this->format_reponse = 'taxons/stats/rangs';
$this->requete_champ = 'count(*) as nombre, rang ';
$this->requete_group_by = ' GROUP BY rang ORDER BY rang ';
}
public function traiterRessourceStatsAnnees() {
// SELECT count(*) as nombre, annee FROM bdtfx_v2_00 GROUP BY annee ORDER BY annee;
$this->format_reponse = 'taxons/stats/annees';
$this->requete_champ = 'count(*) as nombre, annee ';
$this->requete_group_by = ' GROUP BY annee ORDER BY annee ';
}
//-----------------------------FONCTIONS DASSEMBLAGE DE LA REQUETE-----------------------------------------------------
public function assemblerLaRequete() {
if ($this->format_reponse != 'taxons/stats/initiales') {
$this->mettreAuFormat(); //on remplace les nom_sci par les nom_sci_html
}
$requete = ' SELECT '.$this->requete_champ.
' FROM '.$this->table
.$this->retournerRequeteCondition()
.$this->requete_group_by
.$this->formerRequeteLimite();
return $requete;
}
public function formerRequeteLimite() {
if ($this->format_reponse != 'taxons' && $this->format_reponse != 'taxons/id/relations/homonymie') {
$this->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
$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 retournerRequeteCondition() {
$condition = '';
if ($this->requete_condition) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
public function recupererTotalResultat() {
$requete = 'SELECT count(*) as nombre FROM '.$this->table.$this->retournerRequeteCondition().$this->requete_group_by;
$res = $this->getBdd()->recuperer($requete);
if ($res) {
$total = $res['nombre'];
}
return $total;
}
 
//-------------------------FONCTIONS DE FORMATION DU RESULTAT-----------------------------------------------------------
/** Permet de récupérer le résultat à retourner propre à chaque requete et de l'encoder en json*/
public function retournerResultatFormate($resultat, $version) {
switch ($this->format_reponse) {
case 'taxons/id' ://ds CommunNomsTaxons
$reponse = $this->formaterId($resultat[0]);
break;
case 'taxons/id/champ' ://ds CommunNomsTaxons
$reponse = $this->formaterIdChamp($resultat[0]);
break;
case 'taxons/id/relations' :
$reponse = $this->formaterIdRelations($resultat[0],$version);
break;
case 'taxons/id/relations/superieurs' :
$reponse = $this->formaterIdSuperieur($resultat, $version);
break;
case 'taxons/id/relations/inferieurs' :
$reponse = $this->formaterIdInferieur($resultat);
break;
case 'taxons/id/relations/hierarchie' :
// le formatage de la hiérarchie est identique aux relations inférieures
$reponse = $this->formaterIdInferieur($resultat);
break;
case 'taxons/stats/annees' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsAnnee($resultat);
break;
case 'taxons/stats/rangs' ://ds CommunNomsTaxons
$reponse = $this->formaterStatsRang($resultat);
break;
case 'taxons/stats/initiales' ://ds CommunNomsTaxons
$reponse = $this->formaterStatsInitiales($resultat);
break;
case 'taxons' :
$reponse = $this->formatertaxons($resultat);
break;
}
return $reponse;
}
//----------------------concerne les resultats pour des requetes de type /noms avec ou sans paramètres--------------
public function formaterTaxons($resultat) {
if ($this->parametres['retour.format'] == 'oss') {
$reponse = $this->formaterEnOss($resultat);
} else {
$reponse = $this->formaterEnJsonMax($resultat);
}
return $reponse;
}
public function formaterEnJsonMax($resultat) {
//print_r($resultat);
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$masque = $this->recupererMasquePrincipal();
if (isset($masque)) $resultat = $this->trierRechercheFloue($this->parametres[$masque[0]], $resultat, $masque[1]);
if (isset($this->masque)) $this->table_retour['masque'] = implode('&', $this->masque);
$this->afficherEnteteResultat('/'.$this->service);
$table_retour_json['entete'] = $this->table_retour;
$this->table_retour = array();
//on remplit la table $table_retour_json['resultat']
$tab_tax_inf = $this->recupererListeTaxonInf($resultat);
foreach ($resultat as $tab) {
$num = $tab['num_nom'];
if (isset($this->parametres['masque.nt'])) $this->afficherDonnees('num_taxonomique', $tab['num_taxonomique']);
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherTaxonInfNb($num, $tab_tax_inf);
$resultat_json[$num] = $this->table_retour;
$this->table_retour = array(); //on vide le tableau table_retour
}
$table_retour_json['resultat'] = $resultat_json;
return $table_retour_json;
}
//--------------------concerne les resultats pour des requetes de type noms/id----------------------------------------
 
public function formaterIdRelations($resultat, $version) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
$retour_id_rel = array ('entete' => array()); //on initialise pr que l'entete apparaisse en premier
 
$superieurs = $this->ajouterRelations('superieurs'); //, $version);
if (isset($superieurs)) $retour_id_rel['resultat']['superieurs'] = $superieurs;
$inferieurs = $this->ajouterRelations('inferieurs', $version);
if (isset($inferieurs)) $retour_id_rel['resultat']['inferieurs'] = $inferieurs;
if (!isset($retour_id_rel['resultat'])) { //on renvoit un tableau null si il n'existe aucune relations
$retour_id_rel = 'null';
} else { //on rajoute l'entete si des relations existent
$this->afficherDonnees('num_nom', $this->num_nom_taxon); //$this->afficherEnteteResultat($resultat, '/'.$this->service.'/'.$this->ressources[0].'/relations/synonymie');
$retour_id_rel['entete'] = $this->table_retour;
$this->table_retour = array();
}
return $retour_id_rel;
}
public function ajouterRelations($relation, $version) {
$version = str_replace(Config::get('bdd_table').'_', '', $version);
$res = null;
$taxon = $this->num_nom_taxon;
$parametres_url = '';
if ($this->parametres != array()) $parametres_url = '?'.http_build_query($this->parametres, '', '&');
$url = Config::get('url_service').'/'
.$this->service.'/'.$version.'/'
.$this->ressources[0].'/relations/'
.$relation.$parametres_url;
$relation = $this->consulterHref($url);
if (isset($relation->resultat)) {
$res = $relation->resultat;
} elseif (isset($relation->$taxon)) { //pour les relations inf et sup
$res = $relation->$taxon;
}
return $res;
}
public function formaterIdSuperieur($resultat, $version) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$tab_relation = null; //si il n'existe aucune relation
$taxon_sup_traites = array();
if (($resultat) != '' ) {
//on recupere d'abord les rangs supérieurs
$sup = $resultat[0];
do {
$sup = $this->recupererIdSuperieur($sup['num_tax_sup'], $version);
if(!in_array($sup['num_nom'], $taxon_sup_traites)) {
$taxon_sup_traites[] = $sup['num_nom'];
} else {
$sup = null;
}
if ($sup['rang'] == '0') $sup['rang'] = '10'; //erreur dans la base
if (isset($sup)) $resultat[] = $sup;
} while ($sup != null);
krsort($resultat);
//on les affiche ensuite
foreach ($resultat as $tab) {
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('rang', $tab['rang']);
$tab_inf[$num] = $this->table_retour;
$tab_inf[$num]['num_nom'] = $tab['num_nom'];
$this->table_retour = array();
}
$tab_relation[$this->num_nom_taxon] = $tab_inf;
}
return $tab_relation;
}
public function recupererIdSuperieur($id, $version) {
$req = 'SELECT num_nom, num_nom_retenu, num_tax_sup, rang, nom_sci FROM '
.$version.' WHERE num_nom = '.$this->getBdd()->proteger($id);
$res = $this->getBdd()->recupererTous($req);
if ($res) {
$resultat = $res[0];
} else {
$resultat = null; //on return null si il n'y a pas de taxon superieur
}
return $resultat;
}
public function formaterIdInferieur($resultat) {
// Attention à l'ordre, on doit d'abord récupérer correpondance_champs avant champs_api
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$tab_relation = null;
if (($resultat) != array()) {
foreach ($resultat as $tab) {
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('rang', $tab['rang']);
$tab_inf[$num] = $this->table_retour;
$tab_inf[$num]['nom_sci'] = $tab['nom_sci'];
$tab_inf[$num]['num_nom'] = $tab['num_nom'];
$this->table_retour = array();
}
$tab_relation[$this->num_nom_taxon] = $tab_inf;
}
return $tab_relation;
}
public function afficherTaxonInfNb($num, $tab_tax_inf) {
foreach ($tab_tax_inf as $taxNb) {
if ($taxNb['num_tax_sup'] == $num) {
$this->table_retour['taxon_inferieur_nbre'] = $taxNb['nb'];
}
}
if (!isset($this->table_retour['taxon_inferieur_nbre'])) {
$this->table_retour['taxon_inferieur_nbre'] = '0';
}
}
public function recupererListeTaxonInf($resultat) {
// SELECT num_tax_sup, count(*) as nb FROM bdtfx_v2_00 WHERE num_tax_sup IN (id, id, id) AND num_nom = num_nom_retenu GROUP BY num_tax_sup';
foreach ($resultat as $tab) {
$tab_num[] = $tab['num_nom']; //on regroupe ici les id des taxons dont on cherche le nb de taxon inf
}
$req = 'SELECT num_tax_sup, count(*) as nb FROM '.$this->table
.' WHERE num_tax_sup IN ('.implode(',',$tab_num)
.') AND num_nom = num_nom_retenu GROUP BY num_tax_sup';
 
$res = $this->getBdd()->recupererTous($req);
if ($res) {
$resultat = $res;
} else {
$resultat = array(); //on retourne un tableau vide s'il n'y a pas de taxon inférieurs
}
return $resultat;
}
}
 
?>
/tags/v5.12-baouque/services/modules/0.1/sophy/Cartes.php
New file
0,0 → 1,164
<?php
/**
*
* Service Cartes
*
* Service renvoyant la carte de flore probable issue des données sophy
* (très simple, convertir un num tax en numéro fournier, puis construit l'url
* de la carte)
*
* Encodage en entrée : utf8
* Encodage en sortie : utf8
* @package eflore-projets
* @author Aurélien PERONNET <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 2014 Tela Botanica (accueil@tela-botanica.org)
*/
class SophyCartes {
const MIME_TEXT = 'text/plain';
const MIME_PNG = 'image/png';
const MIME_JSON = 'application/json';
private $types_cartes_autorises = array('flore-probable');
private $bdd;
private $format_retour;
private $type_num_demande;
private $num_demande;
public function consulter($ressources, $param) {
// Initialisation des variables
$this->ressources = $ressources;
$this->param = $param;
$this->traiterRessources();
$this->traiterParametres();
if($this->type_num_demande == "nn") {
//TODO: obtenir nt grâce aux autres services
$this->num_demande = $this->obtenirCorrespondanceNtPourNn($this->num_demande);
$this->type_num_demande = "nt";
}
$resultat = $this->obtenirCarteFloreProbable($this->num_demande);
return $resultat;
}
private function obtenirCarteFloreProbable($nt) {
$num_fournier = $this->obtenirCorrespondanceFournier($nt);
if($num_fournier == null) {
$message = "Aucune carte n'existe pour le numéro demandé";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $this->formerCarteFloreProbable($num_fournier);
}
public function formerCarteFloreProbable($num_fournier) {
 
$resultat = new ResultatService();
$url = sprintf(Config::get('chemin_cartes_tpl'), $num_fournier);
$resultat->corps = ($this->format_retour == self::MIME_PNG) ? self::getCartePng($url) : array('binaire.href' => $url);
$resultat->mime = ($this->format_retour == self::MIME_PNG) ? self::MIME_PNG : self::MIME_JSON;
 
return $resultat;
}
private static function getCartePng($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
private function traiterRessources() {
if(!in_array($this->ressources[0], $this->types_cartes_autorises)) {
$message = 'Erreur dans les parametres de requête : </br> '.
'Le type de carte '.$this->ressources[0].' est inconnu, <br />'.
'Les type autorisés sont : '.implode(',', $this->types_cartes_autorises);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
$matches = array();
if(preg_match("/([a-z]*).(nn|nt):([0-9]*)/", $this->ressources[1], $matches)) {
//TODO: quoi faire du référentiel
$this->type_num_demande = $matches[2];
$this->num_demande = $matches[3];
} else {
$message = 'Erreur dans les parametres de requête : </br> '.
'Le service s\'interroge sous la forme sophy/cartes/type_carte/bdtfx.nn:XXXX ou '.
'sophy/cartes/type_carte/bdtfx.nt:XXXX ';
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
}
private function traiterParametres() {
$formats = array('image/png', 'text/plain');
$this->format_retour = self::MIME_PNG;
if(isset($this->param['retour.format']) &&
!in_array($this->param['retour.format'], $formats)) {
$message = 'Erreur dans les parametres de recherche de votre requête : </br> '.
"Le paramètre retour.format ne peut prendre que les valeurs suivantes : ".implode(',', $formats)." ";
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
} else {
if(isset($this->param['retour.format'])) {
$this->format_retour = $this->param['retour.format'];
} else {
$this->format_retour = self::MIME_TEXT;
}
}
}
private function obtenirCorrespondanceFournier($num_tax) {
$requete = "SELECT * FROM sophy_fournier_bdnff ".
"WHERE sfb_id_num_bdnff = ".$this->getBdd()->proteger($num_tax);
$resultat = $this->getBdd()->recuperer($requete);
$num_fournier = null;
if(!empty($resultat)) {
$num_fournier = $resultat['sfb_id_num_fournier'];
}
return $num_fournier;
}
private function obtenirCorrespondanceNtPourNn($num_nom) {
// 90% de chances que ces cartes ne soient utilisées que bdtfx
// donc on se permet une requete directe dans la table
$requete = "SELECT num_taxonomique FROM ".Config::get('bdd_table_taxons')." ".
"WHERE num_nom = ".$this->getBdd()->proteger($num_nom);
 
$resultat = $this->getBdd()->recuperer($requete);
$num_tax = null;
if(!empty($resultat)) {
$num_tax = $resultat['num_taxonomique'];
}
return $num_tax;
}
//+----------------------------------------------------------------------------------------------------------------+
// 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;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtxa/Cartes.php
New file
0,0 → 1,90
<?php
// declare(encoding='UTF-8');
/**
* Classe implémentant l'API d'eFlore Cartes pour le projet bdtxa.
*
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Cartes
*
* @package eFlore/services
* @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-2012 Tela Botanica (accueil@tela-botanica.org)
*/
// TODO : Config et Outils sont des classes statiques qui doivent poser des pb pour les tests...
class BdtxaCartes {
 
private $parametres = array();
private $ressources = array();
 
public function consulter($ressources, $parametres) {
$this->parametres = $parametres;
$this->ressources = $ressources;
 
$this->analyserRessources();
$resultat = $this->executerSousService();
 
return $resultat;
}
 
private function analyserRessources() {
$nbreRessources = count($this->ressources);
if ($nbreRessources == 0) {
$message = "A implémenter : carte proportionnelle ensemble des infos";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
} else if ($nbreRessources == 1) {
if ($this->etreRessourceIdentifiants(0)) {
$this->sousService = 'Taxons';
} else if ($this->etreRessourceLegende(0)) {
$message = "A implémenter : légende carte proportionnelle ensemble des infos";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
} else {
$message = "La ressource n°1 '{$this->ressources[0]} indiquée n'est pas valable.";
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
} else if ($nbreRessources == 2) {
if ($this->etreRessourceIdentifiants(0) && $this->etreRessourceLegende(1)) {
$this->sousService = 'Legende';
}
}
}
 
private function etreRessourceIdentifiants($position) {
$ok = true;
if (isset($this->ressources[$position])) {
$ids = $this->ressources[$position];
$projetPattern = '(?:(?:(?:[A-Za-z0-9]+\.)?(?:nn|nt)?:)?(?:[0-9]+,)*[0-9]+)';
$patternComplet = "/^$projetPattern(?:;$projetPattern)*$/i";
$ok = preg_match($patternComplet, $ids) ? true : false;
}
return $ok;
}
 
private function etreRessourceLegende($position) {
$ok = true;
if (isset($this->ressources[$position])) {
$legende = $this->ressources[$position];
$ok = ($legende == 'legende') ? true : false;
}
return $ok;
}
 
private function executerSousService() {
if (isset($this->sousService)) {
$classe = $this->sousService.'Cartes';
require_once dirname(__FILE__).DS.'cartes'.DS.$classe.'.php';
$sousService = new $classe(new Conteneur());
$resultat = $sousService->consulter($this->ressources, $this->parametres);
} else {
$message = "L'analyse des ressources n'a pu aboutir à déterminer le sous service à executer.";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $resultat;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtxa/CommunNomsTaxons.php
New file
0,0 → 1,932
<?php
// declare(encoding='UTF-8');
/**
* Description :
* Classe CommunNomsTaxons.php
* 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-2011 Tela Botanica (accueil@tela-botanica.org)
*/
 
 
abstract class CommunNomsTaxons extends Commun {
 
/** Tableau de correspondance entre les noms des champs et les codes de l'ontologie.*/
private $relationsChampsCodesOntologie = null;
protected $table_retour; //Permet de stocker le tableau de résultat (non encodé en json)
protected $resultat_req; // Permet de stocker le résultat de la requete principale.
protected $compo_nom = null; //Stocke sous forme de tableau les composant du nom à ajouter au nom scientifique
protected $table;// Nom de la table dans laquelle on récupèrera les données dans les requetes SQL
protected $total_resultat = null;
/** Stocke le service appelé correspondant. Est utilisé principalement lors de l'affichage du href d'un synonyme
(ex id=12, basionyme num 25 est un synonyme) dans le service taxon */
protected $service_href = null;
protected $erreursParametres = null;
protected $sans_nom_sci = array('gen','sp','ssp','fam','au_ss','bib_ss');
private $bib_traitees = array();
private $ontologie = array();
 
//+------------------------------- PARAMÈTRES ---------------------------------------------------------------+
 
public function traiterParametres() {
$this->definirParametresParDefaut();
$this->verifierParametres();
 
if (isset($this->parametres) && count($this->parametres) > 0) {
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'ns.structure' :
$this->remplirTableCompositionNom($val);
if (in_array($val,$this->sans_nom_sci)){
$this->requete_champ = implode(', ',$this->compo_nom);
}else {
$this->requete_champ .= ' ,'.implode(', ',$this->compo_nom);
}
break;
case 'navigation.depart' :
$this->limite_requete['depart'] = $val;
break;
case 'navigation.limite' :
$this->limite_requete['limite'] = $val;
break;
}
}
$this->traiterParametresSpecifiques();
}
}
 
protected function definirParametresParDefaut() {
if (empty($this->parametres['recherche'])) {
$this->parametres['recherche'] = 'stricte';
}
if (empty($this->parametres['ns.format'])) {
$this->parametres['ns.format'] = 'txt';
}
if (empty($this->parametres['retour.format'])) {
$this->parametres['retour.format'] = 'max';
}
if (empty($this->parametres['ns.structure']) &&
$this->parametres['retour.format'] != 'oss') {
$this->parametres['ns.structure'] = 'au,an,bib';
}
}
 
 
public function verifierParametres() {
//$this->verifierParametresAPI();
 
$this->verifierParametre('recherche', 'stricte|floue|etendue|complete');
$this->verifierParametre('ns.format', 'htm|txt');
$this->verifierParametre('retour.format', 'min|max|oss|perso');
$this->verifierParametreAvecValeurMultipe('ns.structure', 'an|au|bib|ad|gen|sp|ssp|fam|au_ss|bib_ss');
 
/*if (count($this->erreursParametres) > 0) {
$m = 'Erreur dans votre requête : '.implode('<br/>', $this->erreursParametres);
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}*/
}
 
public function verifierParametresAPI() {
$parametresApi = $this->recupererTableauConfig('parametresAPI');
while (!is_null($parametre = key($this->parametres))) {
if (!in_array($parametre, $parametresApi)) {
$this->erreursParametres[] = "Le paramètre '$parametre' n'est pas pris en compte par cette version de l'API.";
}
next($this->parametres);
}
}
 
public function verifierParametre($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeur = $this->parametres[$parametre];
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
 
public function verifierParametreAvecValeurMultipe($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeursConcatenees = $this->parametres[$parametre];
$valeurs = explode(',', $valeursConcatenees);
foreach ($valeurs as $valeur) {
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
}
 
private function verifierValeursPermises($parametre, $valeur, $valeursPermises) {
if (!in_array($valeur, explode('|', $valeursPermises))) {
$this->erreursParametres[] = "Le paramètre '$parametre' ne peut pas prendre la valeur '$valeur'. Valeurs permises : $valeursPermises";
}
}
 
public function traiterParametresCommuns() {
 
}
 
public function ajouterFiltreMasque($nom_champ, $valeur) {
$valeur = explode(',',$valeur);
$conditions = array();
if ($nom_champ == 'annee' || $nom_champ == 'rang') {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ = ".$this->getBdd()->proteger($val);
}
} else {
if ($this->parametres['recherche'] == 'etendue') {
foreach ($valeur as $val) {
$val = $this->modifierValeur($val);
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
 
} elseif ($this->parametres['recherche'] == 'floue') {
foreach ($valeur as $val) {
$val = $this->getBdd()->proteger($val);
$conditions[] = "( SOUNDEX($nom_champ) = SOUNDEX($val))".
" OR ( SOUNDEX(REVERSE($nom_champ)) = SOUNDEX(REVERSE($val)))";
}
} else {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
}
}
$this->requete_condition[]= '('.implode(' OR ', $conditions ).')';
$this->masque[$nom_champ] = $nom_champ.'='.implode(',',$valeur);
}
 
private function modifierValeur($valeur) {
$valeur = $this->remplacerCaractereHybrideEtChimere($valeur);
$valeur = $this->preparerChainePourRechercheEtendue($valeur);
return $valeur;
}
 
private function remplacerCaractereHybrideEtChimere($valeur) {
$caracteres = array('×', '%D7', '+', '%2B');
$remplacements = array('x ','x ', '+', '+');
$valeur = str_replace($caracteres, $remplacements, $valeur);
return $valeur;
}
 
private function preparerChainePourRechercheEtendue($valeur) {
$valeur = str_replace(' ', '% ', trim($valeur));
$valeur = $valeur.'%';
return $valeur;
}
 
//+-------------------------------Fonctions d'analyse des ressources-------------------------------------+
 
private function etreRessourceId() {
$ok = false;
if ($this->estUnIdentifiant() && count($this->ressources) == 1) {
$ok = true;
}
return $ok;
}
 
public function traiterRessources() {
if (isset($this->ressources) && count($this->ressources) > 0) {
if ($this->ressources[0] == 'relations') {
$this->traiterRessourceIdRelations();
} elseif ($this->estUnIdentifiant()) { //l'identifiant peut etre de type /#id ou /nt:#id
$this->traiterRessourcesIdentifiant(); // dans le service noms ou taxons
} elseif ($this->ressources[0] == 'stats') { //ressource = noms/stats
$this->traiterRessourcesStats();
} else {
$e = 'Erreur dans votre requete </br> Ressources disponibles : <br/>
<li> /'.$this->service.'/#id (id : L\'identifiant du nom rechercher)</li>
<li> /'.$this->service.'/nt:#id (id : Numero du taxon recherche)</li>
<li> /'.$this->service.'/stats </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
}
 
public function traiterRessourcesStats() {
$this->format_reponse = $this->service.'/stats';
 
$e = "Erreur dans votre requête </br> Ressources disponibles : $this->service/stats/[annees|rangs|initiales]";
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
switch ($this->ressources[1]) {
case 'annees' :
$this->traiterRessourceStatsAnnees();
break;
case 'rangs' :
$this->traiterRessourceStatsRangs();
break;
case 'initiales' :
$this->traiterRessourceStatsInitiales();
break;
default :
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
} else {
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
/** Vérifie si la première valeur de la table de ressource est un identifiant :
* un numerique ou un numéro taxonomique sous la forme nt:xx */
public function estUnIdentifiant() {
return (is_numeric($this->ressources[0]) || (strrpos($this->ressources[0],'nt:') !== false
&& is_numeric(str_replace('nt:','',$this->ressources[0]))));
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonction d'analyse des parametres
 
/** Permet de remplir le tableau compo_nom. Il comprendra en fct du paramètre ns.structure les éléments à rajouter
* au nom_sci (annee, auteur, biblio ou addendum). */
public function remplirTableCompositionNom($valeur) {
$structure_nom = explode(',', $valeur);
foreach ($structure_nom as $structure) {
$structure = trim($structure);
$patterns = array('/^an$/', '/^au$/', '/^bib$/', '/^ad$/', '/^sp$/', '/^gen$/', '/^ssp$/','/^fam$/',
'/^au_ss$/','/^bib_ss$/');
$champs = array('annee', 'auteur', 'biblio_origine', 'nom_addendum', 'epithete_sp', 'genre',
'epithete_infra_sp','famille','auteur', 'biblio_origine');
 
// avec str_replace() 'sp' est inclu dans 'ssp', et la conversion pour 'ssp' est mauvaise
$this->compo_nom[$structure] = preg_replace($patterns, $champs, $structure);
}
}
 
public function mettreAuFormat() {
if ($this->parametres['ns.format'] == 'htm') {
if (strrpos($this->requete_champ, 'nom_sci_html as nom_sci') === false) {
$this->requete_champ = str_replace('nom_sci', 'nom_sci_html as nom_sci', $this->requete_champ);
}
}
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonctions de formatage
 
/** 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. */
public function recupererTableSignification($table) {
$tables = explode(',', $table);
foreach ($tables as $tab) {
if ($tab == 'champs_comp') {
$champ_bdnff_api = array_keys($this->champs_api); //on recupère le nom des champ ds la bdd
$this->champs_comp = array_diff($this->champs_table, $champ_bdnff_api);
} elseif ($tab == 'champs_api') {
foreach ($this->correspondance_champs as $key => $val) {
preg_match('/(hybride[.]parent_0[12](?:[.]notes)?|nom_sci[.][^.]+|[^.]+)(?:[.](id|code))?/', $val, $match);
$val = $match[1];
$this->champs_api[$key] = $val;
}
} else {
$this->$tab = $this->recupererTableauConfig($tab);
}
}
}
 
public function formaterEnOss($resultat) {
$table_nom = array();
$oss = '';
foreach ($resultat as $tab) {
if (isset($tab['nom_sci']) ) {
if (!in_array($tab['nom_sci'], $table_nom)) {
$table_nom[] = $tab['nom_sci'];
$oss[] = $tab['nom_sci'].' '.$this->ajouterCompositionNom($tab);
}
}else {
$res = $this->ajouterCompositionNom($tab);
if($res) {
$oss[] = $res;
}
}
 
}
 
if (isset($this->masque)) $masque = implode('&', $this->masque);
else $masque = 'Pas de masque';
$table_retour_oss = array($masque, $oss);
return $table_retour_oss;
}
 
public function afficherEnteteResultat($url_service) {
$this->table_retour['depart'] = $this->limite_requete['depart'];
$this->table_retour['limite'] = $this->limite_requete['limite'];
$this->table_retour['total'] = $this->total_resultat;
$url = $this->formulerUrl($this->total_resultat, $url_service);
if (isset($url['precedent']) && $url['precedent'] != '') {
$this->table_retour['href.precedent'] = $url['precedent'];
}
if (isset($url['suivant']) && $url['suivant'] != '') {
$this->table_retour['href.suivant'] = $url['suivant'];
}
}
 
public function afficherNomHrefRetenu($tab, $num) {
$this->resultat_req = $tab;
$this->afficherDonnees('num_nom', $num);
if ($this->parametres['retour.format'] == 'min') { // sinon est affiché ds afficherDonnees(num_nom, $val) ci-dessus
$this->table_retour['nom_sci'] = $tab['nom_sci'];
$this->table_retour['nom_sci_complet'] = $tab['nom_sci'].' '.$this->ajouterCompositionNom($tab);
}
if ($tab['num_nom_retenu'] != '') {
$retenu = ($tab['num_nom_retenu'] == $num) ? 'true' : 'false';
} else {
$retenu = 'absent';
}
$this->table_retour['retenu'] = $retenu;
unset($this->table_retour['id']);
}
 
 
//+------------------------------------------------------------------------------------------------------+
// Fonction de formatage pour les services /#id/
 
public function formaterId($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
 
foreach ($resultat as $cle => $valeur) {
if ($valeur != '') {
$this->afficherDonnees($cle, $valeur);
}
}
if (isset($this->parametres['retour.champs']) && $this->format_reponse == 'noms/id') {
$retour = $this->table_retour;
$this->table_retour = array();
$champs = explode(',', $this->parametres['retour.champs']);
$this->ajouterChampsPersonnalises($champs, $retour);
}
unset($this->table_retour['href']);
return $this->table_retour;
}
 
public function formaterIdChamp($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$reponse_id = $this->formaterId($resultat);
$this->table_retour = array();
$champs = explode(' ', $this->ressources[1]);
$this->ajouterChampsPersonnalises($champs, $reponse_id);
return $this->table_retour;
}
 
protected function ajouterChampsPersonnalises($champs, $reponse_id) {
$champs_a_libeller = array('nom_retenu', 'rang', 'basionyme', 'hybride', 'hybride.parent_01',
'hybride.parent_02', 'presence', 'tax_sup', 'statut_origine', 'statut_culture', 'statut_introduction');
$champs_forces = array('rang'); // même s'ils sont dans "à libeller", on les prend quand même en brut, en plus
if (! is_null($champs) && is_array($champs) && count($champs) > 0) {
foreach ($champs as $champ) {
if ($this->verifierValiditeChamp($champ)) {
if (strrpos($champ, '.*') !== false) {
$this->afficherPointEtoile($champ, $reponse_id);
} elseif (in_array($champ, $champs_a_libeller)) {
$this->table_retour[$champ.'.libelle'] =
(isset($reponse_id[$champ.'.libelle'])) ? $reponse_id[$champ.'.libelle'] : null;
} else {
$champ = $this->trouverChampBddCorrespondant($champ);
$this->table_retour[$champ] = (isset($reponse_id[$champ])) ? $reponse_id[$champ] : null;
}
// champs bruts en plus, ajouté pour obtenir le rang, mais retourne rang.code avec du kk dedans :-/
if (in_array($champ, $champs_forces)) {
$champ = $this->trouverChampBddCorrespondant($champ);
$this->table_retour[$champ] = (isset($reponse_id[$champ])) ? $reponse_id[$champ] : null;
}
}
}
}
}
 
public function afficherPointEtoile($champ, $reponse) {
preg_match('/^([^.]+\.)\*$/', $champ, $match);
if ($match[1] == 'nom_sci') {
$this->afficherNomSciPointEpithete($this->resultat_req);
} else {
foreach ($reponse as $chp => $valeur) {
if (strrpos($chp, $match[1]) !== false) {
if ($valeur != '') {
$this->table_retour[$chp] = $valeur;
} else {
$this->table_retour[$chp] = null;
}
}
}
}
}
 
public function decomposerNomChamp($champ) {
$decomposition = false;
if (preg_match('/^(?:([^.]+\.parent_0[12]|[^.]+))(?:\.(.+))?$/', $champ, $match)) {
$radical_champ = $match[1];
$suffixe = (isset($match[2])) ? $match[2] : "";
$decomposition = array($radical_champ, $suffixe);
}
return $decomposition;
}
 
public function verifierValiditeChamp($champ) {
$decomposition = $this->decomposerNomChamp($champ);
$validite_ressource = true;
if ($decomposition) {
list($radical, $suffixe) = $decomposition;
$champs_complementaire = array('nom_retenu_complet', 'basionyme_complet');
// on verifie si le nom du champ existe bien
if (!$this->estChampApi($radical) && !$this->estChampComplementaire($radical)) {
if (!in_array($radical, $champs_complementaire)) {
$validite_ressource = false;
$e = 'Le champ "'.$radical.'" n\'existe pas dans la base. <br/><br/>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} elseif ($this->estUnPoint($champ)) {
$validite_ressource = $this->verifierValiditeSuffixe($suffixe, $radical);
}
}
return $validite_ressource;
}
 
public function estChampApi($radical_champ) {
$champ_api_ok = false;
if (in_array($radical_champ, $this->champs_api) || in_array($radical_champ, $this->correspondance_champs)) {
$champ_api_ok = true;
}
return $champ_api_ok;
}
 
public function estChampComplementaire($radical_champ) {
$champ_complementaire_ok = in_array($radical_champ, $this->champs_comp) ? true : false;
return $champ_complementaire_ok;
}
 
public function verifierValiditeSuffixe($suffixe, $radical_champ) {
$validite_ressource = true;
if ($this->correspondAUnId($radical_champ) || $radical_champ == 'id') {
$this->verificationSuffixesIdentifiant($suffixe, $radical_champ, $validite_ressource);
} elseif ($this->correspondAUnCode($radical_champ)) {
$this->verificationSuffixesCodes($suffixe, $radical_champ, $validite_ressource);
} elseif ($radical_champ == 'nom_sci') {
if ($suffixe != '*') {
$validite_ressource = false;
$m = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/>
Les suffixes possibles sont les suivants : <li> * </li>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
} else {
$validite_ressource = false;
$m = 'Erreur : Le paramètre "'.$radical_champ.'" ne peut pas présenter de suffixe. <br/><br/>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
return $validite_ressource;
}
 
public function verificationSuffixesCodes(&$suffixe, &$radical_champ, &$validite_ressource ) {
if (!in_array($suffixe, array('*', 'code', 'href', 'details'))) {
$validite_ressource = false;
$e = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'.<br/> Les suffixes '
.'possibles sont les suivants : <li> .* </li><li> .code </li><li> .href </li><li> .details </li>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
public function verificationSuffixesIdentifiant(&$suffixe, &$radical_champ, &$validite_ressource) {
if ((strrpos($radical_champ, 'parent') !== false && !in_array($suffixe, array('*', 'id', 'href', 'details', 'notes')))
|| !in_array($suffixe, array('*', 'id', 'href', 'details')) && strrpos($radical_champ, 'parent') === false) {
$validite_ressource = false;
$e = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/> Les suffixes '
.'possibles sont les suivants : <li> .* </li><li> .id </li><li> .href </li><li> .details </li>'
.'<li> .notes (seulement pour les hybride.parent)';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
 
//------------------------------fonction de formatage pour les services /stats/-----------------------------------------
 
public function formaterStatsAnnee($resultat) {
foreach ($resultat as $cle_annee) {
$annee = ($cle_annee['annee'] != '') ? $cle_annee['annee'] : 'ND';
$nb = $cle_annee['nombre'];
$retour_stats_annee[$annee] = $nb;
}
return $retour_stats_annee;
}
 
public function formaterStatsRang($resultat) {
foreach ($resultat as $rangs) {
if ($rangs['rang'] != 0) {
$rang = $rangs['rang'];
if ($this->parametres['retour.format'] == 'max') {
$retour_rang[$rang]['rang'] = $this->ajouterSignificationCode('rang',$rang);
}
$nombre = $rangs['nombre'];
$retour_rang[$rang]['nombre'] = $nombre;
}
}
return $retour_rang;
}
 
public function formaterStatsInitiales($resultat) {
$rang = null;
$table_rang = array();
foreach ($resultat as $tuple) {
if ($tuple['rang'] != 0) {
$this->memoriserRang($table_rang, $tuple, $rang);
if ($tuple['lettre'] == 'x ') {
$this->ajouterHybrideChimere('hybride', $rang, $tuple);
} elseif ($tuple['lettre'] == '+ ') {
$this->ajouterHybrideChimere('chimere', $rang, $tuple);
} else {
$l = substr($tuple['lettre'], 0, 1);
if (isset($this->table_retour[$rang][$l])) {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] += floatval($tuple['nb']);
} else {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] = floatval($tuple['nb']);
}
}
}
}
return $this->table_retour;
}
 
public function memoriserRang(&$table_rang, $tuple, &$rang) {
if (is_array($table_rang)) {
if (!in_array($tuple['rang'], $table_rang)) {
$rang = $tuple['rang'];
$table_rang[] = $rang;
if ($this->parametres['retour.format'] == 'max') {
$rang = $this->ajouterSignificationCode('rang', $rang);
}
}
}
}
 
public function ajouterHybrideChimere($groupe, &$rang, &$tuple) {
if (isset($this->table_retour[$rang][str_replace('hybride', 'hyb', $groupe)])) {
$this->table_retour[$rang][$groupe] += floatval($tuple['nb']);
} else {
$this->table_retour[$rang][$groupe] = floatval($tuple['nb']);
}
}
 
//-----------------------------Fonctions d'affichage utiliser dans les fonctions de formatage---------------------------
 
public function afficherDonnees($champApi, $valeur) {
$champBdd = $this->trouverChampBddCorrespondant($champApi);
if ($this->parametres['retour.format'] == 'min') {
if ($champApi == 'nom_sci') {
$valeur = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req);
}
if ($champApi == 'nom_sci_html') {
$valeur = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req, 'htm');
}
$this->table_retour[$champBdd] = $valeur;
} else {
$this->afficherToutesLesInfos($champBdd, $valeur);
}
}
 
public function trouverChampBddCorrespondant($champApi) {
if (array_key_exists($champApi, $this->champs_api)) {
$champBdd = $this->correspondance_champs[$champApi];
} else {
$champBdd = $champApi;
}
return $champBdd;
}
 
public function afficherToutesLesInfos($nom_champ_api, $valeur) {
if ($this->presentePlusieursId($nom_champ_api, $valeur)) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'details', $valeur);
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif (strrpos($nom_champ_api, 'parent') !== false && strrpos($nom_champ_api, 'notes') !== false) {
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif (($this->correspondAUnId($nom_champ_api) || $nom_champ_api == 'id' && $valeur != '0')) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'id,signification,href', $valeur);
 
} elseif ($this->correspondAUnCode($nom_champ_api)) {
preg_match('/^([^.]+)(?:\.code)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'code,signification,href', $valeur);
 
} elseif ($nom_champ_api == 'nom_sci_html') {
$this->table_retour['nom_sci_html'] = $valeur;
$this->table_retour['nom_sci_html_complet'] = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req, 'htm');
}elseif ($nom_champ_api != 'nom_sci') {
$this->table_retour[$nom_champ_api] = $valeur;
}
}
 
public function presentePlusieursId($ressource, $valeur = null) {
if ($valeur) {
$presente = strrpos($ressource, 'proparte') !== false && strrpos($valeur, ',') !== false;
} else { //pour la vérification du champ, on ignore alors la valeur de la ressource
$presente = strrpos($ressource, 'proparte') !== false;
}
return $presente;
}
 
public function afficherInfosPrecises($champ, $suffixe, $valeur) {
$suffixes = explode(',', $suffixe);
//on initialise au service appelé. Sera potentiellement modifié dans la fonction afficherSignification()
$this->service_href = $this->service;
foreach ($suffixes as $suffixe) {
switch ($suffixe) {
case 'id' :
$this->table_retour[str_replace('id.id', 'id', $champ.'.id')] = $valeur;
break;
case 'details' :
$this->afficherTableDetails($champ, $valeur);
break;
case 'signification' :
$this->afficherSignification($champ, $valeur);
break;
case 'href' :
$url = $this->creerUrl($champ, $valeur);
$this->table_retour[str_replace('id.href', 'href', $champ.'.href')] = $url;
break;
case 'code' :
$this->table_retour[$champ.'.code'] = $this->obtenirCode($champ, $valeur);
break;
case 'notes' :
$this->table_retour[$champ.'.notes'] = $this->resultat_req[str_replace('.', '_', $champ).'_notes'];
break;
default : break;
}
}
}
 
public function afficherTableDetails($nom_champ_api, $valeur) {
$tab_id = explode(',', $valeur);
$tab_res = $this->table_retour;
$this->table_retour = array();
foreach ($tab_id as $id) {
$this->afficherInfosPrecises($nom_champ_api, 'id,signification,href', $id);
$tab_res[$nom_champ_api.'.details'][] = $this->table_retour;
$this->table_retour = array();
}
$this->table_retour = $tab_res;
}
 
private function obtenirCode($champ, $valeur) {
$code = $this->transformerChampEnCode($champ);
return "bdnt.$code:$valeur";
}
 
private function transformerChampEnCode($champ) {
if (is_null($this->relationsChampsCodesOntologie)) {
$this->relationsChampsCodesOntologie = Outils::recupererTableauConfig('ChampsCodesOntologie');
}
 
$code = $champ;
if (array_key_exists($champ, $this->relationsChampsCodesOntologie)) {
$code = $this->relationsChampsCodesOntologie[$champ];
}
return $code;
}
 
public function creerUrl($champ, $valeur) {
if ($this->correspondAUnId($champ) || $champ == 'id') {
$service = $this->service_href;
$url = $this->ajouterHref($service, $valeur);
} else {
$code = $this->transformerChampEnCode($champ);
$url = $this->ajouterHrefAutreProjet('ontologies', "$code:", $valeur, 'bdnt');
}
return $url;
}
 
public function afficherSignification($champ, $valeur) {
if ($champ == 'id' && isset($this->resultat_req['nom_sci']) && $this->resultat_req['num_nom'] == $valeur) {
//si le nom_sci du num_nom que l'on veut afficher est déjà dans la table de résultat :
$this->table_retour['nom_sci'] = $this->resultat_req['nom_sci'];
$this->table_retour['nom_sci_complet'] = $this->resultat_req['nom_sci'].' '.
$this->ajouterCompositionNom($this->resultat_req);
} elseif ($this->correspondAUnId($champ) || $champ == 'id') {
$nom = $this->recupererNomSci($valeur);
if ($nom != array()) {
$this->table_retour[$champ.'.libelle'] = $nom['nom_sci'];
$this->table_retour[$champ.'_html'] = $nom['nom_sci_html'];
$this->table_retour[$champ.'_complet'] = $nom['nom_sci_complet'];
$this->table_retour[$champ.'_html_complet'] = $nom['nom_sci_complet_html'];
$this->service_href = $nom['service'];
}
} elseif ($this->correspondAUnCode($champ)) {
$this->table_retour[$champ.'.libelle'] = $this->ajouterSignificationCode($champ, $valeur);
}
}
 
/** Permet d'afficher les élements nomenclatural du nom_sci lors de l'appel dans le service noms/id/champ du champ^nom_sci.*/
public function afficherNomSciPointEpithete($resultat) {
$tab_nom_sci = array('nom_supra_generique', 'genre', 'epithete_infra_generique', 'epithete_sp',
'type_epithete', 'epithete_infra_sp', 'cultivar_groupe', 'cultivar', 'nom_commercial');
foreach ($tab_nom_sci as $compo_nom) {
if (isset($resultat[$compo_nom]) && !empty($resultat[$compo_nom])) {
$this->table_retour['nom_sci.'.$compo_nom] = $resultat[$compo_nom];
}
}
}
 
public function ajouterSignificationCode($champ, $valeur) {
if($this->termeOntologieEstEnCache($champ, $valeur)) {
$nom_code = $this->obtenirTermeOntologieParCache($champ, $valeur);
} else {
$code = $this->transformerChampEnCode($champ);
if (preg_match('/^([^_-]+)(?:_|-)([^_-]+)$/', $code, $match)) {
$code = $match[1].ucfirst($match[2]);
}
$url = Config::get('url_ontologie').$code.':'.$valeur.'/nom';
try {
$res = $this->consulterHref($url); //dans commun.php
$nom_code = $valeur;
if (is_object($res)) {
$nom_code = $res->nom;
}
$this->mettreEnCacheOntologie($champ, $valeur, $nom_code);
} catch (Exception $e) {
$nom_code = '';
}
}
return $nom_code;
}
 
public function recupererNomSci($id) {
$nom = array();
if ($id != 0) {
if ($this->compo_nom == null) {
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html FROM '.$this->table.' WHERE num_nom = '.$id;
} else { //on ajoute à la requete sql, les champs de ns.structure
//print_r($this->compo_nom);
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html, '.implode(', ', $this->compo_nom)
.' FROM '.$this->table
.' WHERE num_nom = '.$id;
}
if ($this->parametres['ns.format'] == 'htm') {
$req = str_replace('nom_sci', 'nom_sci_html as nom_sci', $req);
}
$res = $this->getBdd()->recuperer($req);
if ($res) {
$nom['nom_sci'] = $res['nom_sci'];
$nom['nom_sci_html'] = $res['nom_sci_html'];
$nom['nom_sci_complet'] = $res['nom_sci'].' '.$this->ajouterCompositionNom($res);
$nom['nom_sci_complet_html'] = $res['nom_sci_html'].' '.$this->ajouterCompositionNom($res, 'htm');
$nom['service'] = ($res['num_nom_retenu'] == $id && $this->service == 'taxons') ? 'taxons' : 'noms';
}
}
return $nom;
}
 
/** Permet de retourner une chaine de caractère composée des parametres du nom (ns.structure : annnée, auteur,
* bibilio et addendum). A ajouter au nom scientifique */
public function ajouterCompositionNom($tab_res, $format = '') {
$format = ($format == '') ? $this->parametres['ns.format'] : $format;
 
$nom = '';
if (isset($this->compo_nom)) {
if ($format == 'htm') {
$format = array(
'au' => '<span class="auteur">%s</span>',
'an' => '[<span class="annee">%s</span>]',
'an_bib' => '[<span class="annee">%s</span>, <span class="biblio">%s</span>]',
'bib' => '[<span class="biblio">%s</span>]',
'ad' => '[<span class="adendum">%s</span>]');
} else {
$format = array(
'au' => '%s',
'an' => '[%s]',
'an_bib' => '[%s, %s]',
'bib' => '[%s]',
'ad' => '[%s]',
'gen' => '%s',
'sp' => '%s',
'ssp' => '%s',
'fam' => '%s',
'au_ss' => '%s',
'bib_ss' => '%s');
}
$compo_nom = array();
 
foreach ($this->compo_nom as $key => $champ) {
if (isset($tab_res[$champ]) && !empty($tab_res[$champ])) {
$compo_nom[$key] = $tab_res[$champ];
}
}
$nom_complet = $this->formerNomComplet($compo_nom, $format);
$nom = implode(' ', $nom_complet);
}
return rtrim($nom, ' ');
}
 
 
public function formerNomComplet($compo_nom, $format) {
$nom_complet = array();
extract($compo_nom);
if (isset($au)) $nom_complet[] = sprintf($format['au'], $au);
if (isset($an)) {
if (isset($bib)) {
$nom_complet[] = sprintf($format['an_bib'], $an, $bib);
} else {
$nom_complet[] = sprintf($format['an'], $an);
}
} elseif (isset($bib)) {
$nom_complet[] = sprintf($format['bib'], $bib);
}
if (isset($ad)) $nom_complet[] = sprintf($format['ad'], $ad);
if (isset($gen)) $nom_complet[] = sprintf($format['gen'], $gen);
if (isset($ssp)) $nom_complet[] = sprintf($format['ssp'], $ssp);
if (isset($sp)) $nom_complet[] = sprintf($format['sp'], $sp);
if (isset($fam)) $nom_complet[] = sprintf($format['fam'], $fam);
if (isset($au_ss)) $nom_complet[] = sprintf($format['au_ss'], $au_ss);
if (isset($bib_ss)) {
$bibl = $this->tronquerBiblio($bib_ss);
//simule un 'select distinct' sur les biblio tronquées
if (!isset($this->bib_traitees[$bibl])) {
$nom_complet[] = sprintf($format['bib_ss'],$bibl );
$this->bib_traitees[$bibl] = 1;
}
}
return $nom_complet;
}
 
public function tronquerBiblio($valeur){
$bib = '';
if(strpos($valeur,',') !== false) {
$bib = explode(',',$valeur);
}
if(strpos($bib[0],';') !== false) {
 
$bib[0] = strstr($bib[0],';');
$bib[0] = str_replace('; ','',$bib[0]);
}
return $bib[0];
}
 
 
 
public function correspondAUnCode($key) {
return (strrpos($key, '.code') !== false) || (in_array($key.'.code', $this->correspondance_champs));
}
 
public function correspondAUnId($key) {
return (strrpos($key, '.id') !== false) || (in_array($key.'.id', $this->correspondance_champs));
}
 
public function estUnPoint($key) {
if (strrpos($key, 'hybride.parent') !== false) {
$key = str_replace('hybride.parent', 'hybride_parent', $key);
}
return (strrpos($key, '.') !== false);
}
 
public function recupererMasquePrincipal() {
$masque = null;
$tab_masque = array(
'masque' => 'nom_sci',
'masque_sg' => 'nom_supra_generique',
'masque_gen' => 'genre',
'masque_sp' => 'epithete_sp',
'masque_ssp' => 'epithete_infra_sp',
'masque_au' => 'auteur',
'masque_an' => 'annee',
'masque_bib' => 'biblio_origine',
'masque_ad' => 'addendum',
'masque_rg' => 'rang');
$liste_masque = array();
 
if (isset($this->masque['num_nom'])) {
$liste_masque[] = $this->masque['num_nom'];
}
 
foreach ($tab_masque as $key => $filtre) {
if (isset($this->masque[$filtre])) {
if (!isset($masque) && !in_array($filtre, array('rang', 'annee'))) {
$masque = array($key, $filtre);
}
$liste_masque[] = $this->masque[$filtre];
}
}
$this->masque = $liste_masque;
return $masque;
}
 
private function mettreEnCacheOntologie($categorie, $valeur, $correspondance) {
if(!isset($this->ontologie[$categorie])) {
$this->ontologie[$categorie] = array();
}
if(!isset($this->ontologie[$categorie][$valeur])) {
$this->ontologie[$categorie][$valeur] = array();
}
$this->ontologie[$categorie][$valeur] = $correspondance;
}
 
private function termeOntologieEstEnCache($categorie, $valeur) {
return array_key_exists($categorie, $this->ontologie) && array_key_exists($valeur, $this->ontologie[$categorie]);
}
 
private function obtenirTermeOntologieParCache($categorie, $valeur) {
return $this->ontologie[$categorie][$valeur];
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtxa/cartes/LegendeCartes.php
New file
0,0 → 1,112
<?php
// declare(encoding='UTF-8');
/**
* Gère le sous-service Legende de Cartes.
*
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Cartes
*
* @package eFlore/services
* @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-2012 Tela Botanica (accueil@tela-botanica.org)
*/
// TODO : Config et Outils sont des classes statiques qui doivent poser des pb pour les tests...
class LegendeCartes {
 
private $parametres = array();
private $ressources = array();
 
const MIME_JSON = 'application/json';
const PRESENCE_CHOROLOGIE = '15';
 
private $formatsSupportes = array(self::MIME_JSON);
private $tableOntologie = '';
private $ontologies = '';
private $legende = array();
 
public function __construct(Conteneur $conteneur) {
$this->Bdd = $conteneur->getBdd();
$this->tableOntologie = $conteneur->getParametre('bdd_table_ontologies');
}
 
public function consulter($ressources, $parametres) {
//$tpsDebut = microtime(true);
$this->parametres = $parametres;
$this->ressources = $ressources;
 
$this->definirValeurParDefautDesParametres();
$this->verifierParametres();
 
$resultat = $this->obtenirResultat();
 
return $resultat;
}
 
private function definirValeurParDefautDesParametres() {
if (isset($this->parametres['retour']) == false) {
$this->parametres['retour'] = self::MIME_JSON;
}
}
 
private function verifierParametres() {
$erreurs = array();
 
if (isset($this->parametres['retour']) == false) {
$erreurs[] = "Le paramètre type de retour 'retour' est obligatoire.";
}
if ($this->verifierValeurParametreRetour() == false) {
$erreurs[] = "Le type de retour '{$this->parametres['retour']}' n'est pas supporté.";
}
 
if (count($erreurs) > 0) {
$message = implode('<br />', $erreurs);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
}
 
private function verifierValeurParametreRetour() {
return in_array($this->parametres['retour'], $this->formatsSupportes);
}
 
private function obtenirResultat() {
$this->chargerOntologies();
$this->chargerLegende();
 
$resultat = new ResultatService();
$resultat->corps = $this->legende;
$resultat->mime = $this->parametres['retour'];
 
return $resultat;
}
 
private function chargerOntologies() {
$requete = "SELECT * FROM {$this->tableOntologie} ";
$resultats = $this->Bdd->recupererTous($requete);
 
if (!is_array($resultats) || count($resultats) <= 0) {
$message = "Les données d'ontologies n'ont pu être chargées pour la ressource demandée";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
foreach ($resultats as $ontologie) {
$this->ontologies[$ontologie['id']] = Commun::extraireComplementsOntologies($ontologie);
}
}
 
private function chargerLegende() {
foreach ($this->ontologies as $ontologie) {
if ($ontologie['classe_id'] == self::PRESENCE_CHOROLOGIE) {
$this->legende[] = array(
'code' => $ontologie['code'],
'couleur' => $ontologie['legende'],
'nom' => $ontologie['nom'],
'description' => $ontologie['description']);
}
}
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtxa/cartes/TaxonsCartes.php
New file
0,0 → 1,472
<?php
// declare(encoding='UTF-8');
/**
* Gère le sous-service Taxons de Cartes.
*
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Cartes
*
* @package eFlore/services
* @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-2012 Tela Botanica (accueil@tela-botanica.org)
*/
// TODO : Config et Outils sont des classes statiques qui doivent poser des pb pour les tests...
class TaxonsCartes {
 
private $parametres = array();
private $ressources = array();
 
const CODE_REFTAX_DEFAUT = 'bdtxa';
const TYPE_ID_DEFAUT = 'nn';
const CARTE_DEFAUT = 'antilles';
const FORMAT_DEFAUT = '587x550';
const VERSION_DEFAUT = '+';
const MIME_SVG = 'image/svg+xml';
const MIME_PNG = 'image/png';
const PRESENCE_CHOROLOGIE = '15';
 
private $config = array();
private $convertisseur = '';
private $cheminCartesBase = '';
private $formatsSupportes = array(self::MIME_SVG, self::MIME_PNG);
private $reftaxSupportes = array(self::CODE_REFTAX_DEFAUT);
private $UrlNavigation = null;
private $taxonsDemandes = array();
private $imgLargeur = 0;
private $imgHauteur = 0;
private $tableMeta = '';
private $tableOntologie = '';
private $tableChorodep = '';
private $metadonnees = '';
private $ontologies = '';
private $priorites = '';
private $version = '';
private $legende = array();
private $donnees = array();
 
 
public function __construct(Conteneur $conteneur) {
$this->Bdd = $conteneur->getBdd();
$this->tableOntologie = $conteneur->getParametre('bdd_table_ontologies');
$this->config = $conteneur->getParametre('Cartes');
$this->convertisseur = $this->config['convertisseur'];
$this->tableMeta = $conteneur->getParametre('bdd_table_meta');
$this->tableOntologie = $conteneur->getParametre('bdd_table_ontologies');
$this->cheminCartesBase = $this->config['chemin'];
$cacheOptions = array('mise_en_cache' => $this->config['cache_miseEnCache'],
'stockage_chemin' => $this->config['cache_stockageChemin'],
'duree_de_vie' => $this->config['cache_dureeDeVie']);
$this->cache = $conteneur->getCacheSimple($cacheOptions);
}
 
public function consulter($ressources, $parametres) {
$this->parametres = $parametres;
$this->ressources = $ressources;
 
$this->definirValeurParDefautDesParametres();
$this->verifierParametres();
 
$resultat = $this->obtenirResultat();
 
return $resultat;
}
 
private function definirValeurParDefautDesParametres() {
if (isset($this->parametres['retour']) == false) {
$this->parametres['retour'] = self::MIME_SVG;
}
if (isset($this->parametres['retour.format']) == false) {
$this->parametres['retour.format'] = self::FORMAT_DEFAUT;
}
if (isset($this->parametres['version.projet']) == false) {
$this->parametres['version.projet'] = self::VERSION_DEFAUT;
}
}
 
private function verifierParametres() {
$erreurs = array();
 
if (isset($this->parametres['retour']) == false) {
$erreurs[] = "Le paramètre type de retour 'retour' est obligatoire.";
}
if ($this->verifierValeurParametreRetour() == false) {
$erreurs[] = "Le type de retour '{$this->parametres['retour']}' n'est pas supporté.";
}
if (isset($this->parametres['retour.format']) == false) {
$erreurs[] = "Le paramètre de format de retour 'retour.format' est obligatoire.";
}
if ($this->verifierValeurParametreFormat() == false) {
$erreurs[] = "Le type de format '{$this->parametres['retour.format']}' n'est pas supporté.".
"Veuillez indiquer un nombre entier correspondant à la largeur désirée pour la carte.";
}
if ($this->verifierValeurParametreVersionProjet() == false) {
$erreurs[] = "Le format de version.projet '{$this->parametres['version.projet']}' n'est pas supporté.".
"Veuillez indiquer le code '+' (=dernière version) ou une année sur 4 chiffres séparé d'un mois ".
"sur deux chiffres par un point. Ex. : 2012.01";
}
 
if (count($erreurs) > 0) {
$message = implode('<br />', $erreurs);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
}
 
private function verifierValeurParametreRetour() {
return in_array($this->parametres['retour'], $this->formatsSupportes);
}
 
private function verifierValeurParametreFormat() {
if ($ok = preg_match('/^([0-9]+)$/', $this->parametres['retour.format'], $match)) {
$this->imgLargeur = $match[1];
} else if ($ok = preg_match('/^([0-9]+)x([0-9]+)$/', $this->parametres['retour.format'], $match)) {
$this->imgLargeur = $match[1];
$this->imgHauteur = $match[2];
}
return $ok;
}
private function verifierValeurParametreVersionProjet() {
$ok = (preg_match('/^(?:[+]|[0-9]{4}\.[0-9]{2})$/', $this->parametres['version.projet']) == 0) ? false : true;
return $ok;
}
 
private function obtenirResultat() {
$this->analyserIdentifiants();
$this->verifierIdentifiants();
 
$this->chargerMetadonnees();
$this->definirVersion();
$this->tableChorodep = 'bdtxa_v'.str_replace('.', '_', $this->version);
$this->chargerOntologies();
$this->chargerLegende();
$this->chargerPrioritesLegende();
$this->chargerDonnees();
$svg = $this->genererSVG();
$img = ($this->parametres['retour'] == self::MIME_PNG) ? $this->convertirEnPNG($svg) : $svg;
 
$resultat = new ResultatService();
$resultat->corps = $img;
$resultat->mime = $this->parametres['retour'];
 
return $resultat;
}
 
private function analyserIdentifiants() {
$ids = $this->ressources[0];
if (preg_match('/^[0-9]+$/', $ids)) {
$this->taxonsDemandes[self::CODE_REFTAX_DEFAUT]['nn'][] = $ids;
} else {
// ceci contient potentiellement des formes ref_tax1.nn:1,2;ref_tax2.nt:3,4
$projetsListeEtNumNoms = explode(';', $ids);
if (count($projetsListeEtNumNoms) > 0) {
foreach ($projetsListeEtNumNoms as $projetEtNumNoms) {
$projetEtNumNoms = (strpos($projetEtNumNoms, ':')) ? $projetEtNumNoms : self::CODE_REFTAX_DEFAUT.'.nn:'.$projetEtNumNoms;
list($projetEtType, $numNoms) = explode(':', $projetEtNumNoms);
 
$projetEtType = (strpos($projetEtType, '.')) ? $projetEtType : self::CODE_REFTAX_DEFAUT.'.'.$projetEtType;
list($projet, $type) = explode('.', $projetEtType);
 
$this->taxonsDemandes[$projet][$type] = explode(',', $numNoms);
}
}
}
}
 
private function verifierIdentifiants() {
foreach (array_keys($this->taxonsDemandes) as $reftax) {
$ok = in_array($reftax, $this->reftaxSupportes);
if ($ok == false) {
$message = "Le reférentiel taxonomique '$reftax' n'est pas pris en compte par ce projet.";
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
}
}
 
private function chargerMetadonnees() {
$requete = 'SELECT * '.
"FROM {$this->tableMeta} ".
"ORDER BY date_creation DESC ";
$resultats = $this->Bdd->recupererTous($requete);
 
if (!is_array($resultats) || count($resultats) <= 0) {
$message = "Les méta-données n'ont pu être chargée pour la ressource demandée";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
$this->metadonnees = $resultats;
}
 
private function definirVersion() {
if ($this->parametres['version.projet'] == '+') {
$this->version = $this->metadonnees[0]['version'];
} else {
$this->version = $this->parametres['version.projet'];
}
}
 
private function chargerOntologies() {
$requete = 'SELECT * '.
"FROM {$this->tableOntologie} WHERE classe_id = (SELECT id FROM eflore_ontologies WHERE code ='presenceChorologie')";
$resultats = $this->Bdd->recupererTous($requete);
 
if (!is_array($resultats) || count($resultats) <= 0) {
$message = "Les données de légende n'ont pu être chargées pour la ressource demandée";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
foreach ($resultats as $ontologie) {
$this->ontologies[$ontologie['id']] = Commun::extraireComplementsOntologies($ontologie);
}
}
 
private function chargerLegende() {
foreach ($this->ontologies as $ontologie) {
if ($ontologie['classe_id'] == self::PRESENCE_CHOROLOGIE) {
$this->legende[$ontologie['code']] = $ontologie['legende'];
}
}
}
 
private function chargerPrioritesLegende() {
foreach ($this->ontologies as $ontologie) {
if ($ontologie['classe_id'] == self::PRESENCE_CHOROLOGIE && isset($ontologie['priorite'])) {
$this->priorites[$ontologie['code']] = $ontologie['priorite'];
}
}
}
 
private function chargerDonnees() {
$conditions = $this->getConditions();
$requete = 'SELECT nom_sci, `presence_Guadeloupe`, `presence_Martinique`, `presence_Saint_Martin`, '.
"`presence_La_Desirade`, `presence_Saint_Barthelemy`, `presence_Marie_Galante`, ".
"`presence_Les-Saintes` ".
"FROM {$this->tableChorodep} ".
(isset($conditions) ? 'WHERE '.implode(' AND ', $conditions) : '');
$resultat = $this->Bdd->recupererTous($requete);
$this->donnees = $resultat;
}
 
private function getConditions() {
$conditions = null;
if ($nnListe = $this->getListeNumNom()) {
$conditions[] = "num_nom IN ($nnListe) ";
}
if ($ntListe = $this->getListeNumTax()) {
$conditions[] = "num_tax IN ($ntListe) ";
}
return $conditions;
}
 
private function getListeNumNom() {
$nnListe = null;
$refTax = self::CODE_REFTAX_DEFAUT;
if (isset($this->taxonsDemandes[$refTax])) {
$nnProteges = array();
if (isset($this->taxonsDemandes[$refTax]['nn'])) {
foreach ($this->taxonsDemandes[$refTax]['nn'] as $nn) {
$nnProteges[] = $this->Bdd->proteger($nn);
}
$nnListe = implode(',', $nnProteges);
}
}
return $nnListe;
}
 
private function getListeNumTax() {
$ntListe = null;
$refTax = self::CODE_REFTAX_DEFAUT;
if (isset($this->taxonsDemandes[$refTax])) {
$ntProteges = array();
if (isset($this->taxonsDemandes[$refTax]['nt'])) {
foreach ($this->taxonsDemandes[$refTax]['nt'] as $nt) {
$ntProteges[] = $this->Bdd->proteger($nt);
}
$ntListe = implode(',', $ntProteges);
}
}
return $ntListe;
}
 
private function genererSVG() {
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->validateOnParse = true;
 
$fichierCarteSvg = $this->cheminCartesBase.self::CARTE_DEFAUT.'.svg';
$dom->load($fichierCarteSvg);
 
$racineElement = $dom->documentElement;
$racineElement->setAttribute('width', $this->imgLargeur);
if ($this->imgHauteur != 0) {
$racineElement->setAttribute('height', $this->imgHauteur);
}
 
$css = $this->creerCssCarte();
$styleElement = $dom->getElementsByTagName('style')->item(0);
$css = $styleElement->nodeValue.$css;
$txtCss = $dom->createCDATASection($css);
$styleElement->nodeValue = '';
$styleElement->appendChild($txtCss);
 
$titre = $this->creerTitre();
$titreCdata = $dom->createCDATASection($titre);
$titreElement = $dom->getElementsByTagName('title')->item(0);
$titreElement->nodeValue = '';
$titreElement->appendChild($titreCdata);
 
$taxonTitre = $this->creerTitreTaxon();
$taxonCdata = $dom->createCDATASection($taxonTitre);
$xpath = new DOMXPath($dom);
$taxonTitreEl = $xpath->query("//*[@id='titre-taxon']")->item(0);
$taxonTitreEl->nodeValue = '';
$taxonTitreEl->setAttribute('title', $taxonTitre);
$taxonTitreEl->appendChild($taxonCdata);
 
$svg = $dom->saveXML();
return $svg;
}
 
private function creerCssCarte() {
$css = '';
$this->getZonesPriorites();
$zonesCouleurs = $this->getZonesCouleurs();
foreach ($zonesCouleurs as $couleur => $zonesClasses) {
$classes = implode(', ', $zonesClasses);
$css .= "$classes {"."\n"."fill:$couleur;"."\n"."}"."\n";
}
return $css;
}
 
private function getZonesPriorites() {
$this->zones = array();
$zonesPrioritaires = array();
foreach ($this->donnees as $donnee) {
foreach ($donnee as $zoneId => $codeLegende) {
if (preg_match('/^presence_(.)*$/i', $zoneId)) {
$zoneId = $this->formaterZoneId($zoneId);
if (array_key_exists($codeLegende, $this->priorites)) {
$priorite = $this->priorites[$codeLegende];
if (array_key_exists($zoneId, $zonesPrioritaires) == false) {
$zonesPrioritaires[$zoneId] = 0;
}
if ($priorite > $zonesPrioritaires[$zoneId]) {
$zonesPrioritaires[$zoneId] = $priorite;
$this->zones[$zoneId] = $codeLegende;
}
}
}
}
}
}
 
private function formaterZoneId($zoneId) {
$zoneId = strtolower(str_replace('presence_', '', $zoneId));
$zoneId = str_replace('-', '_', $zoneId);
return $zoneId;
}
 
private function getZonesCouleurs() {
$zones = array();
ksort($this->zones);
foreach ($this->zones as $zoneId => $codeLegende) {
if (array_key_exists($codeLegende, $this->legende)) {
$couleur = $this->legende[$codeLegende];
$zones[$couleur][] = strtolower('.'.sprintf('%02s', $zoneId));
}
}
return $zones;
}
 
private function creerTitre() {
$titre = "Carte en cours d'élaboration";
if ($this->donnees != array()) {
$titre .= ' pour '.$this->creerTitreTaxon();
}
return $titre;
}
 
private function creerTitreTaxon() {
$titre = '';
$noms = array();
foreach ($this->donnees as $donnee) {
$noms[] = $donnee['nom_sci'];
}
$titre = implode(', ', $noms);
return $titre;
}
 
private function convertirEnPNG($svg) {
$png = null;
if (isset($this->convertisseur)) {
if ($this->convertisseur == 'imagick') {
if (extension_loaded('imagick')) {
$png = $this->convertirEnPNGAvecImageMagick($svg);
} else {
$message = "Impossible de générer l'image sur le serveur. Extenssion ImageMagick abscente.";
$code = RestServeur::HTTP_CODE_ERREUR;
throw new Exception($message, $code);
}
} else if ($this->convertisseur == 'rsvg') {
$png = Commun::convertirEnPNGAvecRsvg($this->getIdFichier(), $this->config['cache_stockageChemin'], $svg);
} else {
$message = "Le convertisseur indiqué '{$this->convertisseur}' ne fait pas parti de la liste ".
"des convertisseurs disponibles : imagick, rsvg.";
$code = RestServeur::HTTP_CODE_ERREUR;
throw new Exception($message, $code);
}
} else {
$message = "Veuillez indiquer le convertisseur de svg à utiliser pour le service.";
$code = RestServeur::HTTP_CODE_ERREUR;
throw new Exception($message, $code);
}
return $png;
}
 
private function convertirEnPNGAvecImageMagick($svg) {
$convertisseur = new Imagick();
$convertisseur->setBackgroundColor(new ImagickPixel('transparent'));
$convertisseur->readImageBlob($svg);
$convertisseur->setImageFormat('png32');
$convertisseur->resizeImage($this->imgLargeur, $this->imgHauteur, imagick::FILTER_LANCZOS, 0, true);
$png = $convertisseur->getImageBlob();
$convertisseur->clear();
$convertisseur->destroy();
return $png;
}
 
private function getIdFichier() {
$id = '';
foreach ($this->taxonsDemandes as $reftax => $ids) {
$id[] = $reftax;
foreach ($ids as $type => $vals) {
$id[] = $type;
$id[] = implode('-', $vals);
}
}
$id = implode('-', $id);
return $id;
}
 
public function getParametreTableau($cle) {
$tableau = array();
$parametre = $this->config[$cle];
if (empty($parametre) === false) {
$tableauPartiel = explode(',', $parametre);
$tableauPartiel = array_map('trim', $tableauPartiel);
foreach ($tableauPartiel as $champ) {
if (strpos($champ, '=') === false) {
$tableau[] = trim($champ);
} else {
list($cle, $val) = explode('=', $champ);
$tableau[trim($cle)] = trim($val);
}
}
}
return $tableau;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtxa/Noms.php
New file
0,0 → 1,733
<?php
// declare(encoding='UTF-8');
/**
* Classe permettant de fournir des informations sur les noms scientifiques.
* Si l'url finit par /noms on retourne une liste de noms latin et leurs identifiants (seulement les 100 premeiers noms par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /noms?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, masque.gen (nom de genre), masque.sp (épithète d'espèce), masque.ssp (épithète infra-spécifique),
* masque.au (auteur du nom), masque.an (année de publication du nom), masque.bib (réf biblio de la publi d'origine du nom), masque.ad (nomen addendum),
* masque.nn (identifiant du nom), recherche, rang, distinct, retour.format, nl.format, nl.structure, navigation.depart et navigation.limite.
* Les différentes requetes :
* - noms | noms/relations/#projet/#id_projet | noms/#id | noms/#id/#champ+#champ
* - noms/#id/relations | noms/#id/relations/synonymie | noms/#id/relations/homonymie | noms/#id/relations/flores
* - noms/stats/rangs | noms/stats/annees | noms/stats/initiales
*
* @package bdtfx
* @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 $Id$
* @copyright 1999-2011 Tela Botanica (accueil@tela-botanica.org)
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Noms
*/
 
class Noms extends CommunNomsTaxons {
 
protected $format_reponse = 'noms'; // Permet de stocker la requete formulée
protected $service = 'noms';
protected $serviceNom = 'noms';
protected $requete_champ = 'num_nom, nom_sci, num_nom_retenu';
protected $requete_condition = null;
protected $requete_group_by = '';
/** Permet de stocker les limite de la requete SQL (par défaut seul les 100 premiers résultats seront retournés).*/
protected $limite_requete = array('depart' => 0, 'limite' => 100);
protected $distinct = null; // Valeur du paramètre de requete distinct (=0|1)
 
public function consulter($ressources, $parametres) {
return parent::consulter($ressources, $parametres);
}
 
//+----------------FONCTION D'ANALYSE DES PARAMETRES---------------------------------------------------------+
 
public function traiterParametresSpecifiques() {
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'masque' :
$champ = isset($this->parametres['recherche']) && ($this->parametres['recherche'] == 'etendue') ?
'CONCAT(nom_sci," ",auteur)' : 'nom_sci';
$this->ajouterFiltreMasque($champ, $val);
break;
case 'masque.sg' :
$this->ajouterFiltreMasque('nom_supra_generique', $val);
break;
case 'masque.gen' :
$this->ajouterFiltreMasque('genre', $val);
break;
case 'masque.sp' :
$this->ajouterFiltreMasque('epithete_sp', $val);
break;
case 'masque.ssp' :
$this->ajouterFiltreMasque('epithete_infra_sp',$val);
break;
case 'masque.au' :
$this->ajouterFiltreMasque('auteur', $val);
break;
case 'masque.an' :
$this->ajouterFiltreMasque('annee', $val);
break;
case 'masque.bib' :
$this->ajouterFiltreMasque('biblio_origine',$val);
break;
case 'masque.ad' :
$this->ajouterFiltreMasque('nom_addendum', $val);
break;
case 'masque.nn' :
$this->requete_condition []= 'num_nom IN ('.$val.')';
$this->masque['num_nom'] = "num_nom=$val";
break;
case 'masque.nt' :
$this->requete_condition []= 'num_tax IN ('.$val.')';
$this->masque['num_tax'] = "num_tax=$val";
break;
case 'masque.rg' :
$this->ajouterFiltreMasque('rang', $val);
break;
case 'retour.champs' :
$this->verifierParamChamps($param, $val);
break;
case 'distinct' :
$this->ajouterNomDistinct($val);
break;
case 'masque.fam' :
$this->ajouterFiltreMasque('famille', $val);
break;
case 'masque.sto' :
$this->ajouterFiltreMasque('statut_origine', $val);
break;
case 'masque.sti' :
$this->ajouterFiltreMasque('statut_introduction', $val);
break;
case 'masque.stc' :
$this->ajouterFiltreMasque('statut_culture', $val);
break;
case 'masque.and' :
$this->requete_condition []= " annee >= ".$this->getBdd()->proteger($val);
break;
case 'masque.anf' :
$this->requete_condition []= " annee <= ".$this->getBdd()->proteger($val);
break;
case 'masque.prgua' :
$this->ajouterFiltreMasque('presence_Guadeloupe', $val);
break;
case 'masque.prmar' :
$this->ajouterFiltreMasque('presence_Martinique', $val);
break;
case 'masque.prstm' :
$this->ajouterFiltreMasque('presence_Saint_Martin', $val);
break;
case 'masque.prdes' :
$this->ajouterFiltreMasque('presence_La_Desirade', $val);
break;
case 'masque.prstb' :
$this->ajouterFiltreMasque('presence_Saint_Barthelemy', $val);
break;
case 'masque.prmga' :
$this->ajouterFiltreMasque('presence_Marie_Galante', $val);
break;
case 'masque.prsai' :
$this->ajouterFiltreMasque('presence_Les-Saintes', $val);
break;
}
}
}
 
public function verifierParamChamps($param, $val) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$champs_demandes = explode(',', $val);
$champs_verifies = array();
$champs_api = array_flip($this->champs_api);
$champs_supp = array('nom_retenu_complet'=>'num_nom_retenu', 'basionyme_complet'=>'basionyme');
$champs_api = array_merge($champs_api, $champs_supp);
foreach ($champs_demandes as $champ) {
if (array_key_exists($champ, $champs_api)) {
$champs_verifies[] = $champs_api[$champ];
}
}
if (count($champs_verifies) > 0) {
$this->requete_champ .= ', '.implode(',', $champs_verifies);
}
}
 
/** Permet de rajouter à la requete sql le parametre distinct. N'est utilisé qu'avec le format oss */
public function ajouterNomDistinct($distinct) {
if (isset($distinct)) {
if ($distinct == 1 && $this->parametres['retour.format'] == 'oss') {
$this->distinct = ' distinct ';
} elseif ($distinct == 1 && $this->parametres['retour.format'] != 'oss') {
$e = 'Erreur dans votre requête </br> L\'utilisation du paramètre distinct ne se fait que sous
le format oss';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
}
 
//-----------------FONCTION D'ANALYSE DES RESSOURCES--------------------------------------------------------------------
 
public function traiterRessourcesIdentifiant() {
//on initialise la condition de la requete sql et le format de réponse
$this->requete_condition = array(); //on vide la table dans le cas de plusieurs version
$this->requete_condition[] = 'num_nom = '.$this->getBdd()->proteger($this->ressources[0]);
$this->format_reponse = $this->service.'/id';
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
if ($this->ressources[1] == 'relations') {
$this->traiterRessourceIdRelations();
} else {
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> noms/#id/relations </li> <li> noms/#id/#champ+#champ </li>
<li> noms/#id/relations/synonymie </li> <li> noms/#id/relations/flores </li>
<li> noms/#id/relations/homonymie </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else { // requete de type noms/#id : rajout du nom_sci pour récupérer le format html par la fct mettreAuFormat()
$this->requete_champ = ' *, nom_sci ';
}
}
 
public function traiterRessourceRelations() {
$this->format_reponse .= '/relations';
$projet = $this->ressources[1];
$num_nom = $this->ressources[2];
if (strrpos($num_nom, 'nn.coste') !== false) {
list($p, $nn) = explode('=', $num_nom);
$num_nom = $nn;
}
$champ = "flore_$projet"."_num";
if (isset($this->ressources[3])) {
$type = $this->ressources[3];
if (!in_array($type, array('homonymie', 'synonymie', 'flores'))) {
$e = "Les types disponibles pour les noms sont homonymie, synonymie et flores";
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
$this->requete_champ = ' num_nom ';
$this->requete_condition = array();
$this->requete_condition[] = "$champ = ".$this->getBdd()->proteger($num_nom);
}
 
public function traiterRessourceIdRelations() {
$this->format_reponse .= '/relations';
if (isset($this->ressources[2]) && !empty($this->ressources[2])) {
// requete de type noms/#id/relations/#relation
switch ($this->ressources[2]) {
case 'synonymie' :
$this->traiterRessourceIdSynonymie();
break;
case 'flores' :
$this->traiterRessourceIdFlores();
break;
case 'homonymie' :
$this->traiterRessourceIdHomonymie();
break;
default :
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> noms/#id/relations </li> <li> noms/#id/relations/synonymie </li>
<li> noms/#id/relations/flores </li> <li> noms/#id/relations/homonymie </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
}
}
 
public function traiterRessourceIdSynonymie() {
// SELECT num_nom, nom_sci, num_nom_retenu, basionyme FROM bdtfx_v2_00 WHERE num_nom = X LIMIT 0,100;
$this->format_reponse .= '/synonymie';
if (strrpos($this->requete_champ, ', basionyme') === false) {
$this->requete_champ .= ', basionyme ';
}
if (strrpos($this->requete_champ, ', num_type') === false) {
$this->requete_champ .= ', num_type ';
}
$this->requete_condition[0] = 'num_nom_retenu = '.
'(SELECT num_nom_retenu FROM '.$this->table.' WHERE '.$this->requete_condition[0].')';
}
 
public function traiterRessourceIdHomonymie() {
// SELECT num_nom, nom_sci, num_nom_retenu FROM bdtfx_v2_00 WHERE nom_sci = (SELECT nom_sci FROM bdtfx_v2_00 WHERE num_nom = X);
$this->format_reponse .= '/homonymie';
$this->requete_condition[0] = 'nom_sci = (SELECT nom_sci FROM '.$this->table
.' WHERE '.$this->requete_condition[0].')';
}
 
public function traiterRessourceIdFlores() {
$champ_flores = '';
foreach ($this->champs_table as $champ) {
if (preg_match('/^flore_.*$/', $champ)) {
$champ_flores .= ', '.$champ;
}
}
$this->format_reponse .= '/flores';
$this->requete_champ = 'num_nom'.$champ_flores;
}
 
public function traiterRessourceStatsRangs() {
// SELECT count(*) as nombre, rang FROM bdtfx_v2_00 [WHERE rang = 290] GROUP BY rang ORDER BY rang;
$this->format_reponse .= '/rangs';
$this->requete_champ = 'count(*) as nombre, rang ';
$this->requete_group_by = ' GROUP BY rang ORDER BY rang ';
}
 
public function traiterRessourceStatsAnnees() {
// SELECT count(*) as nombre, annee FROM bdtfx_v2_00 GROUP BY annee ORDER BY annee;
$this->format_reponse .= '/annees';
$this->requete_champ = 'count(*) as nombre, annee ';
$this->requete_condition = null;
$this->requete_group_by = ' GROUP BY annee ORDER BY annee ';
}
 
public function traiterRessourceStatsInitiales() {
// SELECT count(left( nom_sci, 2 )) as nb, rang, left(nom_sci, 2) as lettre GROUP BY rang, left(nom_sci, 2);
$this->format_reponse .= '/initiales';
$this->requete_champ = 'count(left( nom_sci, 2 )) as nb, rang, left(nom_sci, 2) as lettre ';
$this->requete_group_by = ' GROUP BY rang, left(nom_sci, 2)';
}
 
//-----------------------------FONCTIONS DASSEMBLAGE DE LA REQUETE-----------------------------------------------------
 
public function assemblerLaRequete() {
if ( strrpos($this->format_reponse, 'noms/stats/') === false ) {
$this->mettreAuFormat(); //Ds CommunNomsTaxons.php
}
$requete = 'SELECT '.$this->retournerChamps().' '.
"FROM {$this->table} ".
$this->retournerRequeteCondition().' '.
$this->requete_group_by.' '.
$this->retournerOrderBy().' '.
$this->formerRequeteLimite();
return $requete;
}
 
public function retournerChamps() {
$sql = '';
if ($this->distinct) {
$sql .= $this->distinct.' ';
}
if ($this->requete_champ) {
$sql .= $this->requete_champ.' ';
}
 
// Champs "virtuels" pour tier sur l'ensemble des résultats
if (isset($this->parametres['retour.tri'])) {
list($champ, $ordre) = $this->decouperParametreRetourTri();
if ($champ == 'retenu') {
$sql .= ", IF(num_nom = num_nom_retenu, '0', '1') AS nom_retenu_tri ";
}
}
 
return $sql;
}
 
public function decouperParametreRetourTri() {
$tri = array('', '');
if (isset($this->parametres['retour.tri'])) {
if (preg_match('/^(retenu)(?:,(ASC|DESC)|)$/', $this->parametres['retour.tri'], $match))
$tri[0] = $match[1];
$tri[1] = isset($match[2]) ? $match[2] : '';
}
return $tri;
}
 
public function retournerRequeteCondition() {
$condition = '';
if ($this->requete_condition) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
 
public function retournerOrderBy() {
$orderBy = array();
 
// Tri sur l'ensemble des résultats
if (isset($this->parametres['retour.tri'])) {
list($champ, $ordre) = $this->decouperParametreRetourTri();
if ($champ == 'retenu') {
$orderBy[] = "nom_retenu_tri $ordre";
}
}
// Tri par défaut
if ($this->format_reponse == 'noms') {
$orderBy[] = 'nom_sci ASC';
}
 
$sql = '';
if (count($orderBy) > 0) {
$sql = 'ORDER BY '.implode(', ', $orderBy).' ';
}
return $sql;
}
 
public function formerRequeteLimite() {
if ($this->format_reponse != 'noms' && $this->format_reponse != 'noms/id/relations/synonymie'
&& $this->format_reponse != 'noms/id/relations/homonymie') {
$this->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
$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;
}
 
/** Recupere le nombre total de résultat d'une requete lancée. */
public function recupererTotalResultat() {
$total = null;
$requete = 'SELECT count(*) as nombre FROM '.$this->table.$this->retournerRequeteCondition().$this->requete_group_by;
$res = $this->getBdd()->recuperer($requete);
if ($res) {
$total = $res['nombre'];
} else {
$e = 'Fct recupererTotalResultat() : <br/>Données introuvables dans la base';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
}
return $total;
}
 
 
//-------------------FONCTIONS POUR LE FORMATAGE EN JSON----------------------------------------------------------------
 
public function retournerResultatFormate($resultat) {
switch ($this->format_reponse) {
case 'noms/relations' :
$reponse = $this->formaterRelations($resultat[0]);
break;
case 'noms/id' : //ds CommunNomsTaxons
$reponse = $this->formaterId($resultat[0]);
break;
case 'noms/id/relations' :
$reponse = $this->formaterIdRelations($resultat[0]);
break;
case 'noms/id/relations/synonymie' :
$reponse = $this->formaterIdSynonymie($resultat);
break;
case 'noms/id/relations/homonymie' :
$reponse = $this->formaterIdHomonymie($resultat);
break;
case 'noms/id/relations/flores' : //ds CommunsNomsTaxons
$reponse = $this->formaterIdFlores($resultat[0]);
break;
case 'noms/stats/annees' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsAnnee($resultat);
break;
case 'noms/stats/rangs' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsRang($resultat);
break;
case 'noms/stats/initiales' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsInitiales($resultat);
break;
case 'noms' :
$reponse = $this->formaterNoms($resultat);
break;
}
return $reponse;
}
 
//+---------------------concerne les resultats pour des requetes de type noms/id-----------------------------+
 
public function formaterRelations($resultat) {
$num_nom = $resultat['num_nom'];
if (isset($this->ressources[3])) {
$url = Config::get('url_service').$this->service."/$num_nom/relations";
} else {
$type = $this->ressources[3];
$url = Config::get('url_service')."/$this->service/$num_nom/relations/$type";
}
$res = $this->consulterHref($url);
return $res;
}
 
public function formaterIdRelations($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
$retour_id_rel = array ('entete' => array()); //on initialise pr que l'entete apparaisse en premier lors de l'affichage
 
//on recupère le resultat de chaque relation (appel du WS correspondant)
$flores = $this->ajouterRelations('flores');
if (isset($flores)) $retour_id_rel['resultat']['flores'] = $flores;
$homonymes = $this->ajouterRelations('homonymie');
if (isset($homonymes)) $retour_id_rel['resultat']['homonymes'] = $homonymes;
$synonymes = $this->ajouterRelations('synonymie');
if (isset($synonymes)) $retour_id_rel['resultat']['synonymes'] = $synonymes;
 
//on renvoit null si il n'existe aucune relations (on efface l'entete en premier lieu)
if (!isset($retour_id_rel['resultat'])) {
$retour_id_rel = null;
} else { //on rajoute l'entete si des relations existent
$this->afficherDonnees('num_nom', $this->ressources[0]);
$retour_id_rel['entete'] = $this->table_retour;
$this->table_retour = array();
}
return $retour_id_rel;
}
 
/**
* Recupere les relations (type de la relation passée en paramètres :[type_relation] = synonymie, homonymie ou
* flores) par l'appel du web service [version]/noms/#id/relations/[type_relation]
*/
public function ajouterRelations($relation) {
$version = str_replace(Config::get('bdd_table').'_', '', $this->table);
$res = null;
$parametres_url = '';
if ($this->parametres != array()) $parametres_url = '?'.http_build_query($this->parametres, '', '&');
$url = Config::get('url_service').'/'.$this->service.'/'.
$this->ressources[0].'/relations/'.
$relation.$parametres_url;
 
$relation = $this->consulterHref($url);
 
$res = $relation->resultat;
return $res;
}
 
 
public function formaterIdSynonymie($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$retour_id_syn = array();
if ($resultat[0]['num_nom_retenu'] == '') {
$retour_id_syn[] = 'nom_retenu N.D.';
} elseif (count($resultat) != 1) {
//on remplit d'abord l'entete du resultat
$this->table_retour['id'] = $this->ressources[0];
$this->afficherEnteteResultat('/'.$this->service.'/'.$this->ressources[0].'/relations/synonymie');
$retour_id_syn['entete'] = $this->table_retour;
$this->table_retour = array();
foreach ($resultat as $tab) {
//pour chaque basionyme, on recupère le résultat : num_nom, nom_sci, basionyme et num_nom_retenu :
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('basionyme', $tab['basionyme']);
$retour_id_syn['resultat'][$num] = $this->table_retour;
$this->table_retour = array();
}
if (!isset($retour_id_syn['resultat']) && !in_array('nom_retenu N.D.', $retour_id_syn)) {
$retour_id_syn = null; //on initialise le resultat à null
}
}
return $retour_id_syn;
}
 
public function formaterIdHomonymie($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
if (count($resultat) != 1) {
$this->table_retour['id'] = $this->ressources[0];
$this->afficherEnteteResultat($resultat, '/'.$this->service.'/'.$this->ressources[0].'/relations/homonymie');
$retour_id_hom['entete'] = $this->table_retour;
$this->table_retour = array();
foreach ($resultat as $homonyme) {
$this->resultat_req = $homonyme;
$id = $homonyme['num_nom'];
$this->afficherDonnees('num_nom', $id);
if ($homonyme['num_nom_retenu'] != '') {
$retenu = ($id == $homonyme['num_nom_retenu']) ? 'true' : 'false';
} else {
$retenu = 'absent';
}
$this->table_retour['retenu'] = $retenu;
$retour_id_hom['resultat'][$id] = $this->table_retour;
unset($retour_id_hom['resultat'][$id]['id']);
$this->table_retour = array();
}
} else {
$retour_id_hom = null;
}
return $retour_id_hom;
}
 
public function obtenirSynonymesParNumNomAvecInfosFlore($num_nom, $version='1_02') {
 
$champs_flore = 'flore_bonnier_num, flore_bonnier_rem,'.
'flore_cnrs_num, flore_cnrs_rem '.
'flore_fe_num, flore_fe_rem '.
'flore_coste_num, flore_coste_rem '.
'flore_fh_num, flore_fh_rem '.
'flore_fournier_num, flore_fournier_rem';
 
$requete = 'SELECT num_nom, nom_sci, '.$champs_flore.' '.
'FROM '.$this->table.' '.
'WHERE num_nom_retenu = '.
'('.
'SELECT num_nom_retenu FROM '.$this->table.' WHERE num_nom = "'.$num_nom.'"'.
')';
 
return $this->getBdd()->recupererTous($requete);
}
 
public function formaterIdFlores($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp,noms_projets');
$this->resultat_req = $resultat;
$id = array_shift($resultat);
$reponse['entete']['id'] = $id;
$synonymes_flores = $this->obtenirSynonymesParNumNomAvecInfosFlore($this->ressources[0]);
if(is_array($synonymes_flores)) {
foreach ($synonymes_flores as $synonyme) {
$nom_sci = $synonyme['nom_sci'];
$num_nom = $synonyme['num_nom'];
unset($synonyme['nom_sci']);
unset($synonyme['num_nom']);
foreach ($synonyme as $flores => $valeur) {
if ($valeur != '' && $valeur != '0') {
$this->afficherInfosFlore($synonyme, $flores, $valeur, $nom_sci, $num_nom);
}
}
}
}
 
if ($this->table_retour != array()) {
$reponse['resultat'] = $this->table_retour;
$this->table_retour = array();
} else {
$reponse = null;
}
return $reponse;
}
 
public function getNomCompletFlore($flore) {
return Config::get($flore.'_texte');
}
 
public function afficherInfosFlore(&$resultat, $flores, $valeur, $nom_sci, $num_nom) {
$flore = substr($flores,0,strrpos($flores, '_'));
$projet = $this->noms_projets[$flore];
 
//TODO voir si l'on peut factoriser les affectations à la table retour
// et simplifier ce gros pavé
if (strrpos($flores, 'num') !== false) {
if (preg_match('/^([0-9]+)(?:[.]syn[^a-z]*|(.*))?$/', $valeur, $match)) {
$this->table_retour[$num_nom][$flore]['id'] = $match[1];
if ($projet == 'coste') {
$this->table_retour[$num_nom][$flore]['href'] = $this->ajouterHrefAutreProjet('noms', 'nn_coste:', $match[1], $projet);
}
if (isset($match[2]) && $match[2] != '') $this->table_retour[$num_nom][$flore]['cle'] = $match[2];
$this->table_retour[$num_nom][$flore]['nom_flore'] = $this->getNomCompletFlore($flore);
$this->table_retour[$num_nom][$flore]['nom_sci'] = $nom_sci;
}
if (isset($resultat[$flore.'_rem']) && !empty($resultat[$flore.'_rem'])) {
$this->table_retour[$num_nom][$flore]['remarque'] = $resultat[$flore.'_rem'];
$this->table_retour[$num_nom][$flore]['nom_flore'] = $this->getNomCompletFlore($flore);
$this->table_retour[$num_nom][$flore]['nom_sci'] = $nom_sci;
unset($resultat[$flore.'_rem']);
}
} elseif (strrpos($flores,'belge') !== false) {
if (preg_match('/^([0-9]+) (R|S)?$/', $valeur, $match)) {
if (isset($match[2])) $type = ($match[2] == 'R') ? 'taxons' : 'synonyme';
$this->table_retour[$num_nom][$flore]['page'] = $match[1];
$this->table_retour[$num_nom][$flore]['type'] = $type;
$this->table_retour[$num_nom][$flore]['nom_flore'] = $this->getNomCompletFlore($flore);
$this->table_retour[$num_nom][$flore]['nom_sci'] = $nom_sci;
}
}
}
 
//+---------------------concerne les resultats pour des requetes de type /noms avec ou sans paramètres-------+
 
public function formaterNoms($resultat) {
if ($this->parametres['retour.format'] == 'oss') {
$reponse = $this->formaterEnOss($resultat); //Ds CommunNomsTaxons.php
} else {
$reponse = $this->formaterEnJsonMax($resultat);
}
return $reponse;
}
 
public function formaterEnJsonMax($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
 
// TODO : améliorer le tri des résultats
// ATTENTION : ce comportement est étrange
$masque = $this->recupererMasquePrincipal();
if (isset($masque) && !isset($this->parametres['retour.tri'])) {
// fonction du pauvre pour palier aux "." remplacés accidentellement par des "_"
$index = str_replace('masque_','masque.',$masque[0]);
//$resultat = $this->trierRechercheFloue($this->parametres[$index], $resultat, $masque[1]);
}
 
// Tri à la mode du CeL : lexicographique puis noms retenus (retour.tri = "alpharet")
if (isset($this->parametres['retour.tri']) && ($this->parametres['retour.tri'] == "alpharet")) {
usort($resultat, array($this, 'genrePuisNomsRetenusEnTete'));
}
 
$table_retour_json['entete'] = $this->remplirJsonEntete();
$table_retour_json['resultat'] = $this->remplirJsonResultat($resultat);
return $table_retour_json;
}
 
// Trie les éléments du tableau de résultats : le genre en tête, puis les noms retenus, puis le reste
// mais à partir du jeu de données retourné par SQL (indépendents du statut "retenu")
private function genrePuisNomsRetenusEnTete($a, $b) {
// On pourrait utiliser l'indice ['retenu'] mais il contient parfois "absent", qui est dur à traiter
$aEstRetenu = ($a['num_nom'] == $a['num_nom_retenu']);
$bEstRetenu = ($b['num_nom'] == $b['num_nom_retenu']);
$retour = 0;
 
// les noms retenus en premier ("inférieurs")
if ($aEstRetenu) {
if (! $bEstRetenu) {
$retour = -1;
}
} else {
if ($bEstRetenu) {
$retour = 1;
}
}
 
// en cas d'égalité on conserve le tri lexicographique - devrait faire sortir le genre en première position
// car il ne contient pas le nom d'auteur
if ($retour == 0) {
$retour = strcasecmp($a['nom_sci'], $b['nom_sci']);
}
 
return $retour;
}
 
public function remplirJsonResultat($resultat) {
$champs = null;
if (array_key_exists('retour.champs', $this->parametres)) {
$champs = explode(',', $this->parametres['retour.champs']);
}
 
// Structure des données: objet ou liste ?
$modeListe = false;
if (array_key_exists('retour.structure', $this->parametres)) {
$modeListe = ($this->parametres['retour.structure'] === "liste");
}
 
$noms = array();
foreach ($resultat as $tab) {
$this->table_retour = array();
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num); // ajoute le nom_sci, href et si le nom est retenu dans $this->table_retour
$retour = $this->table_retour;
$this->table_retour = array();
if ($champs != null) {
$reponse_id = $this->formaterId($tab);
$this->table_retour = array();
$this->ajouterChampsPersonnalises($champs, $reponse_id);
$retour = array_merge($retour, $this->table_retour);
}
if ($modeListe) {
$retour['num_nom'] = intval($num);
$noms[] = $retour;
} else {
$noms[$num] = $retour;
}
}
 
return $noms;
}
 
public function remplirJsonEntete() {
$entete = array();
if (isset($this->masque)) {
$this->table_retour['masque'] = implode('&', $this->masque);
}
parent::afficherEnteteResultat('/'.$this->service);
return $this->table_retour;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtxa/Taxons.php
New file
0,0 → 1,521
<?php
 
// declare(encoding='UTF-8');// ou ISO-8859-15
/**
* Description :
* Classe Taxons.php permettant de fournir des informations sur les noms scientifiques retenu.
* Si l'url finit par /taxons on retourne une liste de noms latin et leurs identifiants (seulement les 100 premeiers noms par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /taxons?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, recherche, rang, distinct, retour.format, nl.format,
* nl.structure, 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 Taxons extends CommunNomsTaxons {
/** Permet de stocker la requete formulée taxons | taxons/#id | taxons/#id/#champ+#champ ...*/
protected $format_reponse = 'taxons';
protected $service = 'taxons';
protected $requete_champ = 'num_nom, nom_sci, num_nom_retenu, num_tax as num_taxonomique ';
protected $requete_condition = null;
protected $requete_group_by = ' ';
/** Permet de stocker les limite de la requete SQL (par défaut seul les 100 premiers résultats seront retournés).*/
protected $limite_requete = array('depart' => 0, 'limite' => 100);
protected $num_nom_taxon; //Stocke le num_nom du nom retenu du num_nom recherché
protected $presence_num_tax = true;
public function consulter($ressources, $parametres) {
return parent::consulter($ressources, $parametres);
}
public function traiterParametresSpecifiques() {
$this->requete_condition[] = 'num_nom = num_nom_retenu';
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'masque' :
$this->ajouterFiltreMasque('nom_sci', $val);
break;
case 'masque.nt' :
$this->requete_condition[] = "num_tax IN ($val)";
$this->masque[] = "num_tax=$val";
break;
case 'masque.rg':
$this->requete_condition[] = 'rang = '.$this->getBdd()->proteger($val);
$this->masque[] = "rang=$val";
break;
}
}
}
//------------------------------------------Fonction ressources---------------------------------------------------------------------
public function gererNumTax() {
if (!in_array('num_taxonomique', $this->champs_table)) {
$this->presence_num_tax = false;
$this->requete_champ = str_replace(', num_tax ', '', $this->requete_champ);
} else {
$this->presence_num_tax = true;
}
}
public function traiterRessourcesIdentifiant() {
$this->format_reponse = 'taxons/id';
$this->traiterRessourceNtId();
$this->num_nom_taxon = $this->recupererNumNomTaxon(); //on recupere le taxon correspondant au num_nom recherché
if ($this->entete_http == '') {
$this->requete_condition[0] = 'num_nom = '.$this->getBdd()->proteger($this->num_nom_taxon);
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
//---------------- requete de type taxons/#id/#champ+#champ--------------------------------------
if ($this->ressources[1] != 'relations') { // SELECT *, nom_sci FROM bftfx_v2_00 WHERE num_nom = X;
$this->requete_champ = ' *, nom_sci ';
$this->format_reponse .= '/champ';
//---------------- requete de type taxons/#id/relations/#relation--------------------------------
} elseif ($this->ressources[1] == 'relations') {
$this->traiterRessourceIdRelations();
} else {
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> #id/relations </li> <li> #id/#champ+#champ </li> <li> #id/relations </li>
<li> #id/relations/inferieurs </li> <li> #id/relations/superieurs </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else { //--------------- requete de type taxons/#id-----------------------------------------------------
$this->requete_champ = ' *, nom_sci ';
}
}
}
public function traiterRessourceNtId() {
if (strrpos($this->ressources[0], 'nt:') !== false) {
if ($this->presence_num_tax) {
// SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = num_nom_retenu AND num_taxonomique = X;
$this->requete_condition[0] = ' num_tax = '
.str_replace('nt:', '', $this->ressources[0]).' ';
} else {
$e = 'Erreur dans votre requête : </br> Le numéro taxonomique n\'existe pas dans ce projet';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else {
// SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = (SELECT num_nom_retenu FROM bdtfx_v2_00 WHERE num_nom = X);
$this->requete_condition[0] = 'num_nom = '.$this->ressources[0];
}
}
/** Permet de récupérer le num_nom du taxon recherché. Soit le numéro taxonomique est demandé (avec nt: )
* soit un num_nom dont on recherche le num_nom_retenu */
public function recupererNumNomTaxon() {
$identifiant = '';
if ($this->entete_http == '') {
//on récupere l'identifiant du taxon correspondant au num_nom ou num_taxonomique demandé pour pouvoir l'afficher
$req_tax = 'SELECT num_nom_retenu FROM '.$this->table.' WHERE '.$this->requete_condition[0];
$res_tax = $this->getBdd()->recuperer($req_tax);
//on recherche ensuite les identifiants des taxons supérieurs ou inférieurs
if ($res_tax && $res_tax != '') {
$identifiant = $res_tax['num_nom_retenu'];
} else {
$e = 'Le numéro de taxon ou l\'identifiant de nom correspondant au num_nom '
.$this->ressources[0].' n\'existe pas dans la base.';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
Debug::printr($req_tax);
}
}
return $identifiant;
}
public function traiterRessourceIdRelations() {
//----------------- requete de type taxons/#id/relations-------------------------------------------
// SELECT *, nom_sci FROM bftfx_v2_00 WHERE num_nom = X;
$this->format_reponse .= '/relations';
if (isset($this->ressources[2]) && !empty($this->ressources[2])) {
//------------- requete de type taxons/#id/relations/#relation--------------------------------
switch ($this->ressources[2]) {
case 'superieurs' :
$rel = 'recupererIdSup';
$this->format_reponse .= '/superieurs';
$this->traiterRessourceIdRelationInfSup($rel);
break;
case 'inferieurs' :
$rel = 'recupererIdInf';
$this->format_reponse .= '/inferieurs';
$this->traiterRessourceIdRelationInfSup($rel);
break;
case 'hierarchie' :
$rel = 'recupererIdHierarchie';
$this->format_reponse .= '/hierarchie';
$this->traiterRessourceIdRelationHierarchie($rel);
break;
default :
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> taxons/#id/relations </li><li> #id/relations/inferieurs </li>
<li> #id/relations/superieurs </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
}
}
public function traiterRessourceIdRelationHierarchie($rel) {
//Appel de la fct récupérerIdSup ou recupererIdInf : retourne les num_nom des noms inferieurs ou superieurs
$res_relation = $this->$rel();
//analyse du résultat retourné par la requete de recherche des identifiants correspondant aux taxons inf|sup :
if ($res_relation == '') {
//dans le cas ou la requete comporte des erreurs
$e = 'Fct traiterRessourceIdRelationInfSup : La requête forme comporte une erreur!';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
} elseif ($res_relation) {
//dans le cas ou une ou plusieurs relations est retournée, on récupère les identifiants ss la forme (id, id, id)
foreach ($res_relation as $ligne) $res[] = $ligne['num_nom'];
$res = implode(',',$res);
$this->requete_condition[0] = "num_nom IN ($res)";
$this->requete_champ .= ', rang, num_tax_sup ';
} else { //dans le cas ou aucune relation n'existe
$res = array($this->num_nom_taxon => null);
$this->corps_http = json_encode($res);
$this->entete_http = RestServeur::HTTP_CODE_OK;
}
}
public function recupererIdHierarchie() {
$req_relation = 'SELECT num_nom FROM '.$this->table.' '.
' WHERE hierarchie LIKE CONCAT('.
'(SELECT hierarchie FROM '.
$this->table.' '.
'WHERE num_nom = '.$this->getBdd()->proteger($this->num_nom_taxon).')'.
', '.$this->getBdd()->proteger($this->num_nom_taxon.'-%').
')';
$res_relation = $this->getBdd()->recupererTous($req_relation);
return $res_relation;
}
public function traiterRessourceIdRelationInfSup($rel) {
//Appel de la fct récupérerIdSup ou recupererIdInf : retourne les num_nom des noms inferieurs ou superieurs
$res_relation = $this->$rel();
//analyse du résultat retourné par la requete de recherche des identifiants correspondant aux taxons inf|sup :
if ($res_relation == '') { //dans le cas ou la requete comporte des erreurs
$e = 'Fct traiterRessourceIdRelationInfSup : La requête forme comporte une erreur!';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
} elseif ($res_relation) {
//dans le cas ou une ou plusieurs relations est retournée, on récupère les identifiants ss la forme (id, id, id)
foreach ($res_relation as $ligne) $res[] = $ligne['num_nom'];
$res = implode(',',$res);
$this->requete_condition[0] = "num_nom IN ($res)";
$this->requete_champ .= ', rang, num_tax_sup ';
} else { //dans le cas ou aucune relation n'existe
$res = array($this->num_nom_taxon => null);
$this->corps_http = json_encode($res);
$this->entete_http = RestServeur::HTTP_CODE_OK;
}
}
public function recupererIdInf() {
//SELECT num_nom FROM bfdtx_v2_00 WHERE num_tax_sup = (SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = X);
$req_relation = 'SELECT num_nom FROM '.$this->table
.' WHERE num_nom = num_nom_retenu AND num_tax_sup = (SELECT num_nom FROM '
.$this->table
.' WHERE '.implode(' AND ', $this->requete_condition).')';
$res_relation = $this->getBdd()->recupererTous($req_relation);
return $res_relation;
}
public function recupererIdSup() {
//SELECT num_nom FROM bfdtx_v2_00 WHERE num_nom = (SELECT num_tax_sup FROM bdtfx_v2_00 WHERE num_nom = X);
$this->requete_condition[] = "num_nom = num_nom_retenu" ;
$req_relation = 'SELECT num_tax_sup as num_nom FROM '.$this->table
.' WHERE '.implode(' AND ', $this->requete_condition);
$res_relation = $this->getBdd()->recupererTous($req_relation);
return $res_relation;
}
 
public function traiterRessourceStatsInitiales() {
// SELECT count(nom_sci) as nb, rang, left(nom_sci, 2) as lettre FROM bdtfx_v2_00 GROUP BY rang, left(nom_sci, 2);
$this->format_reponse = 'taxons/stats/initiales';
$this->requete_champ = 'count(nom_sci) as nb, rang, left(nom_sci, 2) as lettre ';
$this->requete_group_by = ' GROUP BY rang, left(nom_sci, 2) ';
}
public function traiterRessourceStatsRangs() {
// SELECT count(*) as nombre, rang FROM bdtfx_v2_00 [WHERE rang = 290] GROUP BY rang ORDER BY rang;
$this->format_reponse = 'taxons/stats/rangs';
$this->requete_champ = 'count(*) as nombre, rang ';
$this->requete_group_by = ' GROUP BY rang ORDER BY rang ';
}
public function traiterRessourceStatsAnnees() {
// SELECT count(*) as nombre, annee FROM bdtfx_v2_00 GROUP BY annee ORDER BY annee;
$this->format_reponse = 'taxons/stats/annees';
$this->requete_champ = 'count(*) as nombre, annee ';
$this->requete_group_by = ' GROUP BY annee ORDER BY annee ';
}
//-----------------------------FONCTIONS DASSEMBLAGE DE LA REQUETE-----------------------------------------------------
public function assemblerLaRequete() {
if ($this->format_reponse != 'taxons/stats/initiales') {
$this->mettreAuFormat(); //on remplace les nom_sci par les nom_sci_html
}
$requete = ' SELECT '.$this->requete_champ.
' FROM '.$this->table
.$this->retournerRequeteCondition()
.$this->requete_group_by
.$this->formerRequeteLimite();
return $requete;
}
public function formerRequeteLimite() {
if ($this->format_reponse != 'taxons' && $this->format_reponse != 'taxons/id/relations/homonymie') {
$this->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
$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 retournerRequeteCondition() {
$condition = '';
if ($this->requete_condition) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
public function recupererTotalResultat() {
$requete = 'SELECT count(*) as nombre FROM '.$this->table.$this->retournerRequeteCondition().$this->requete_group_by;
$res = $this->getBdd()->recuperer($requete);
if ($res) {
$total = $res['nombre'];
}
return $total;
}
 
//-------------------------FONCTIONS DE FORMATION DU RESULTAT-----------------------------------------------------------
/** Permet de récupérer le résultat à retourner propre à chaque requete et de l'encoder en json*/
public function retournerResultatFormate($resultat, $version) {
switch ($this->format_reponse) {
case 'taxons/id' ://ds CommunNomsTaxons
$reponse = $this->formaterId($resultat[0]);
break;
case 'taxons/id/champ' ://ds CommunNomsTaxons
$reponse = $this->formaterIdChamp($resultat[0]);
break;
case 'taxons/id/relations' :
$reponse = $this->formaterIdRelations($resultat[0],$version);
break;
case 'taxons/id/relations/superieurs' :
$reponse = $this->formaterIdSuperieur($resultat, $version);
break;
case 'taxons/id/relations/inferieurs' :
$reponse = $this->formaterIdInferieur($resultat);
break;
case 'taxons/id/relations/hierarchie' :
// le formatage de la hiérarchie est identique aux relations inférieures
$reponse = $this->formaterIdInferieur($resultat);
break;
case 'taxons/stats/annees' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsAnnee($resultat);
break;
case 'taxons/stats/rangs' ://ds CommunNomsTaxons
$reponse = $this->formaterStatsRang($resultat);
break;
case 'taxons/stats/initiales' ://ds CommunNomsTaxons
$reponse = $this->formaterStatsInitiales($resultat);
break;
case 'taxons' :
$reponse = $this->formatertaxons($resultat);
break;
}
return $reponse;
}
//----------------------concerne les resultats pour des requetes de type /noms avec ou sans paramètres--------------
public function formaterTaxons($resultat) {
if ($this->parametres['retour.format'] == 'oss') {
$reponse = $this->formaterEnOss($resultat);
} else {
$reponse = $this->formaterEnJsonMax($resultat);
}
return $reponse;
}
public function formaterEnJsonMax($resultat) {
//print_r($resultat);
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$masque = $this->recupererMasquePrincipal();
if (isset($masque)) $resultat = $this->trierRechercheFloue($this->parametres[$masque[0]], $resultat, $masque[1]);
if (isset($this->masque)) $this->table_retour['masque'] = implode('&', $this->masque);
$this->afficherEnteteResultat('/'.$this->service);
$table_retour_json['entete'] = $this->table_retour;
$this->table_retour = array();
//on remplit la table $table_retour_json['resultat']
$tab_tax_inf = $this->recupererListeTaxonInf($resultat);
foreach ($resultat as $tab) {
$num = $tab['num_nom'];
if (isset($this->parametres['masque.nt'])) $this->afficherDonnees('num_taxonomique', $tab['num_taxonomique']);
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherTaxonInfNb($num, $tab_tax_inf);
$resultat_json[$num] = $this->table_retour;
$this->table_retour = array(); //on vide le tableau table_retour
}
$table_retour_json['resultat'] = $resultat_json;
return $table_retour_json;
}
//--------------------concerne les resultats pour des requetes de type noms/id----------------------------------------
 
public function formaterIdRelations($resultat, $version) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
$retour_id_rel = array ('entete' => array()); //on initialise pr que l'entete apparaisse en premier
 
$superieurs = $this->ajouterRelations('superieurs'); //, $version);
if (isset($superieurs)) $retour_id_rel['resultat']['superieurs'] = $superieurs;
$inferieurs = $this->ajouterRelations('inferieurs', $version);
if (isset($inferieurs)) $retour_id_rel['resultat']['inferieurs'] = $inferieurs;
if (!isset($retour_id_rel['resultat'])) { //on renvoit un tableau null si il n'existe aucune relations
$retour_id_rel = 'null';
} else { //on rajoute l'entete si des relations existent
$this->afficherDonnees('num_nom', $this->num_nom_taxon); //$this->afficherEnteteResultat($resultat, '/'.$this->service.'/'.$this->ressources[0].'/relations/synonymie');
$retour_id_rel['entete'] = $this->table_retour;
$this->table_retour = array();
}
return $retour_id_rel;
}
public function ajouterRelations($relation, $version) {
$version = str_replace(Config::get('bdd_table').'_', '', $version);
$res = null;
$taxon = $this->num_nom_taxon;
$parametres_url = '';
if ($this->parametres != array()) $parametres_url = '?'.http_build_query($this->parametres, '', '&');
$url = Config::get('url_service').'/'
.$this->service.'/'.$version.'/'
.$this->ressources[0].'/relations/'
.$relation.$parametres_url;
$relation = $this->consulterHref($url);
if (isset($relation->resultat)) {
$res = $relation->resultat;
} elseif (isset($relation->$taxon)) { //pour les relations inf et sup
$res = $relation->$taxon;
}
return $res;
}
public function formaterIdSuperieur($resultat, $version) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$tab_relation = null; //si il n'existe aucune relation
$taxon_sup_traites = array();
if (($resultat) != '' ) {
//on recupere d'abord les rangs supérieurs
$sup = $resultat[0];
do {
$sup = $this->recupererIdSuperieur($sup['num_tax_sup'], $version);
if(!in_array($sup['num_nom'], $taxon_sup_traites)) {
$taxon_sup_traites[] = $sup['num_nom'];
} else {
$sup = null;
}
if ($sup['rang'] == '0') $sup['rang'] = '10'; //erreur dans la base
if (isset($sup)) $resultat[] = $sup;
} while ($sup != null);
krsort($resultat);
//on les affiche ensuite
foreach ($resultat as $tab) {
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('rang', $tab['rang']);
$tab_inf[$num] = $this->table_retour;
$tab_inf[$num]['num_nom'] = $tab['num_nom'];
$this->table_retour = array();
}
$tab_relation[$this->num_nom_taxon] = $tab_inf;
}
return $tab_relation;
}
public function recupererIdSuperieur($id, $version) {
$req = 'SELECT num_nom, num_nom_retenu, num_tax_sup, rang, nom_sci FROM '
.$version.' WHERE num_nom = '.$this->getBdd()->proteger($id);
$res = $this->getBdd()->recupererTous($req);
if ($res) {
$resultat = $res[0];
} else {
$resultat = null; //on return null si il n'y a pas de taxon superieur
}
return $resultat;
}
public function formaterIdInferieur($resultat) {
// Attention à l'ordre, on doit d'abord récupérer correpondance_champs avant champs_api
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$tab_relation = null;
if (($resultat) != array()) {
foreach ($resultat as $tab) {
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('rang', $tab['rang']);
$tab_inf[$num] = $this->table_retour;
$tab_inf[$num]['nom_sci'] = $tab['nom_sci'];
$tab_inf[$num]['num_nom'] = $tab['num_nom'];
$this->table_retour = array();
}
$tab_relation[$this->num_nom_taxon] = $tab_inf;
}
return $tab_relation;
}
public function afficherTaxonInfNb($num, $tab_tax_inf) {
foreach ($tab_tax_inf as $taxNb) {
if ($taxNb['num_tax_sup'] == $num) {
$this->table_retour['taxon_inferieur_nbre'] = $taxNb['nb'];
}
}
if (!isset($this->table_retour['taxon_inferieur_nbre'])) {
$this->table_retour['taxon_inferieur_nbre'] = '0';
}
}
public function recupererListeTaxonInf($resultat) {
// SELECT num_tax_sup, count(*) as nb FROM bdtfx_v2_00 WHERE num_tax_sup IN (id, id, id) AND num_nom = num_nom_retenu GROUP BY num_tax_sup';
foreach ($resultat as $tab) {
$tab_num[] = $tab['num_nom']; //on regroupe ici les id des taxons dont on cherche le nb de taxon inf
}
$req = 'SELECT num_tax_sup, count(*) as nb FROM '.$this->table
.' WHERE num_tax_sup IN ('.implode(',',$tab_num)
.') AND num_nom = num_nom_retenu GROUP BY num_tax_sup';
$res = $this->getBdd()->recupererTous($req);
if ($res) {
$resultat = $res;
} else {
$resultat = array(); //on retourne un tableau vide s'il n'y a pas de taxon inférieurs
}
return $resultat;
}
}
 
?>
/tags/v5.12-baouque/services/modules/0.1/cel/Images.php
New file
0,0 → 1,544
<?php
// declare(encoding='UTF-8');
/**
* Classe implémentant l'API d'eFlore Images pour le projet CEL.
*
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Images
*
* @package eFlore/services
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @author Aurélien PERONNET <aurelien@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)
*/
// TODO : Config et Outils sont des classes statiques qui doivent poser des pb pour les tests...
class Images extends Commun {
 
protected $parametres = array();
protected $ressources = array();
private $Bdd;
 
const CODE_REFTAX_DEFAUT = 'bdtfx';
const TAILLE_IMG_DEFAUT = 'M';
const MIME_JPEG = 'image/jpeg';
const MIME_JSON = 'application/json';
 
private $tpl_url_img;
protected $config = array();
private $cheminImagesBase = '';
private $formats_supportes = array(self::MIME_JPEG, self::MIME_JSON);
private $tris_supportes = array('date');
private $retour_champs = array('determination.nom_sci' => 'nom_sel', 'determination.nom_sci.code' => 'nom_sel_nn',
'station.lieudit' => 'lieudit', 'station', 'milieu');
private $code_ref_tax_demande = null;
private $ref_tax_demande = array();
private $infosImages = array();
private $nbreImages = 0;
private $Utilisateurs = null;
private $UrlNavigation = null;
 
public function __construct(Bdd $bdd = null, Array $config = null, Utilisateurs $utilisateurs = null, Url $url = null) {
$this->config = is_null($config) ? Config::get('Images') : $config;
$this->Bdd = is_null($bdd) ? new Bdd() : $bdd;
$this->Utilisateurs = is_null($utilisateurs) ? new Utilisateurs() : $utilisateurs;
$this->UrlNavigation = is_null($url) ? new Url($this->config['urlService']) : $url;
$this->cheminImagesBase = $this->config['chemin'];
$this->tpl_url_img = $this->config['urlImagesTpl'];
}
 
public function consulter($ressources, $parametres) {
//$tpsDebut = microtime(true);
$this->parametres = $parametres;
$this->ressources = $ressources;
 
$this->definirValeurParDefautDesParametres();
$this->verifierParametres();
 
$resultat = new ResultatService();
if ($this->parametres['retour'] == self::MIME_JPEG) {
if (@$this->parametres['retour.tri'] == 'date') { // recherche la plus vieille image du CEL
$id_image_a_renvoyer = $this->obtenirIdPremiereImage();
} else {
$id_image_a_renvoyer = $this->obtenirIdImageAuHasard();
}
$resultat->corps = $this->recupererImageBinaire($id_image_a_renvoyer);
} else if ($this->parametres['retour'] == self::MIME_JSON) {
if (isset($this->ressources[0])) {
$this->chargerInfosImage();
$this->extraireIdentitesAuteurs();
$resultat->corps = $this->formaterInfosImage($this->infosImages[0]);
} else {
$this->chargerListeImages();
$this->chargerNbreImagesTotal();
$resultat->corps = $this->formaterListeImages();
}
}
$resultat->mime = $this->parametres['retour'];
 
return $resultat;
}
//+---------------------------FONCTION D'ANALYSE DES PARAMETRES---------------------------------------------------------+
private function definirValeurParDefautDesParametres() {
if (isset($this->parametres['retour']) == false) {
$this->parametres['retour'] = self::MIME_JSON;
}
if (isset($this->parametres['retour.format']) == false) {
$this->parametres['retour.format'] = 'M';
}
if (isset($this->parametres['navigation.depart']) == false) {
$this->parametres['navigation.depart'] = 0;
}
if (isset($this->parametres['navigation.limite']) == false) {
$this->parametres['navigation.limite'] = 100;
}
if (isset($this->parametres['referentiel']) == false) {
$this->parametres['referentiel'] = self::CODE_REFTAX_DEFAUT;
}
}
 
private function verifierParametres() {
$erreurs = array();
 
if (!isset($this->ressources[0])) {
if (isset($this->parametres['masque.nn']) == false) {
$erreurs[] = "Le paramètre masque.nn est obligatoire.";
} else {
$this->analyserMasqueNn();
if ($this->verifierMasqueNnAutorisePourRetourJPEG() == false) {
$erreurs[] = "Le paramètre masque.nn peut contenir une seule valeur numérique pour l'instant pour le format de retour image/jpeg.";
} else if ($this->verifierValeurParametreMasqueNn() == false) {
$erreurs[] = "Le paramètre masque.nn est mal formé.";
}
}
}
if (isset($this->parametres['retour']) == false) {
$erreurs[] = "Le paramètre type de retour 'retour' est obligatoire.";
}
if ($this->verifierValeurParametreRetour() == false) {
$erreurs[] = "Le type de retour '{$this->parametres['retour']}' n'est pas supporté";
}
if (isset($this->parametres['retour.format']) == false) {
$erreurs[] = "Le paramètre de format de retour 'retour.format' est obligatoire.";
}
if ($this->verifierValeurParametreFormat() == false) {
$erreurs[] = "Le type de format '{$this->parametres['retour.format']}' n'est pas supporté";
}
if (isset($this->parametres['retour.tri'])){
if ($this->verifierValeurParametreTri() == false) {
$erreurs[] = "Le type de tri '{$this->parametres['retour.tri']}' n'est pas supporté";
}
}
 
if (isset($this->parametres['retour.champs'])){
if ($this->verifierValeurParametreRetourChamps() == false) {
$erreurs[] = "Le champs '{$this->parametres['retour.champs']}' n'existe pas";
}
}
 
if ($this->verifierValeurParametreNavigationDepart() == false) {
$erreurs[] = "Le paramètre 'navigation.depart' doit possèder un valeur numérique.";
}
if ($this->verifierValeurParametreNavigationLimite() == false) {
$erreurs[] = "Le paramètre 'navigation.limite' doit possèder un valeur numérique supérieure à 0.";
}
 
if (count($erreurs) > 0) {
$message = implode('<br />', $erreurs);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
}
 
private function verifierMasqueNnAutorisePourRetourJPEG() {
$ok = true;
$masque = $this->parametres['masque.nn'];
$retour = $this->parametres['retour'];
 
if ($retour == self::MIME_JPEG) {
$ok = is_numeric($masque) ? true : false;
}
return $ok;
}
 
private function verifierValeurParametreMasqueNn() {
$nn = $this->parametres['masque.nn'];
$projetPattern = '(?:(?:[A-Z0-9]+:)?(?:[0-9]+,)*[0-9]+)';
$patternComplet = "/^$projetPattern(?:;$projetPattern)*$/i";
$ok = preg_match($patternComplet, $nn) ? true : false;
return $ok;
}
 
private function verifierValeurParametreRetour() {
return in_array($this->parametres['retour'], $this->formats_supportes);
}
 
private function verifierValeurParametreFormat() {
$formats = Outils::recupererTableauConfig('Images.formats');
$ok = array_key_exists($this->parametres['retour.format'], $formats);
return $ok;
}
 
private function verifierValeurParametreTri() {
return in_array($this->parametres['retour.tri'], $this->tris_supportes);
}
 
private function verifierValeurParametreRetourChamps() {
$ok = false;
$liste_champs = preg_split(',', $this->parametres['retour.champs']);
foreach ($liste_champs as $champs) {
$ok[$champs] = array_key_exists($champs, $this->retour_champs);
}
return $ok;
}
 
private function verifierValeurParametreNavigationDepart() {
$depart = $this->parametres['navigation.depart'];
$ok = is_numeric($depart) ? true : false;
return $ok;
}
 
private function verifierValeurParametreNavigationLimite() {
$limite = $this->parametres['navigation.limite'];
$ok = (is_numeric($limite) && $limite != 0) ? true : false;
return $ok;
}
 
private function analyserMasqueNn() {
$nn = $this->parametres['masque.nn'];
if (preg_match('/^[0-9]+$/', $nn)) {
$this->ref_tax_demande[$this->parametres['referentiel']][] = $nn;
} else {
// ceci contient potentiellement des formes ref_tax1:nn1,nn2;ref_tax2:nn3,nn4
$projetsListeEtNumNoms = explode(';', $nn);
if (count($projetsListeEtNumNoms) > 0) {
foreach ($projetsListeEtNumNoms as $projetEtNumNoms) {
$projetEtNumNoms = (strpos($projetEtNumNoms, ':')) ? $projetEtNumNoms : $this->parametres['referentiel'].':'.$projetEtNumNoms;
list($projet, $numNoms) = explode(':', $projetEtNumNoms);
$this->ref_tax_demande[$projet] = explode(',', $numNoms);
}
}
}
}
 
 
//+---------------------------------------- REQUETES ---------------------------------------------------------------+
private function obtenirIdImageAuHasard() {
$refTax = $this->parametres['referentiel'];
$numNom = $this->Bdd->proteger($this->ref_tax_demande[$refTax][0]);
 
$requete = 'SELECT ci.id_image AS id_image '.
'FROM cel_images AS ci '.
' LEFT JOIN cel_obs AS co '.
'ON (ci.ce_observation = co.id_observation) '.
'WHERE co.transmission = 1 '.
" AND co.nom_ret_nn IN ($numNom)";
" AND co.nom_referentiel = ".$this->Bdd->proteger($refTax) . ' -- ' . __FILE__ . ':' . __LINE__;
 
$resultat = $this->Bdd->recupererTous($requete);
 
if (!is_array($resultat) || count($resultat) <= 0) {
$message = "Aucune image ne correspond au numéro numenclatural $refTax:$numNom";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
$id_image_hasard = $resultat[array_rand($resultat)]['id_image'];
return $id_image_hasard;
}
 
private function obtenirIdPremiereImage() {
$refTax = $this->parametres['referentiel'];
$numNom = $this->Bdd->proteger($this->ref_tax_demande[$refTax][0]);
$requete = 'SELECT ci.id_image AS id_image '.
'FROM cel_images AS ci'.
' LEFT JOIN cel_obs AS co '.
' ON (ci.ce_observation = co.id_observation) '.
'WHERE co.transmission = 1 '.
" AND co.nom_ret_nn IN ($numNom) ".
' AND ci.date_prise_de_vue != "0000-00-00" '.
' AND co.nom_referentiel LIKE '.$this->Bdd->proteger($refTax.'%').' '.
' ORDER BY ci.date_prise_de_vue ASC '.
'LIMIT 1' . ' -- ' . __FILE__ . ':' . __LINE__;
 
$resultat = $this->Bdd->recupererTous($requete);
 
if (!is_array($resultat) || count($resultat) <= 0) {
$message = "Aucune image ne correspond au numéro numenclatural $refTax:$numNom";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
$id_image_hasard = $resultat[0]['id_image'];
return $id_image_hasard;
}
 
private function chargerInfosImage() {
$requete = 'SELECT SQL_CALC_FOUND_ROWS '.
' ci.id_image AS id_img, co.date_observation AS date, '.
' co.id_observation AS id_obs, '.
' ci.courriel_utilisateur AS utilisateur_courriel, '.
' nom_sel, nom_sel_nn, '.
' zone_geo, ce_zone_geo, lieudit, station, milieu '.
'FROM cel_images AS ci'.
' LEFT JOIN cel_obs AS co '.
' ON (ci.ce_observation = co.id_observation) '.
'WHERE ci.id_image = '.$this->ressources[0].
' AND co.id_observation IS NOT NULL' . ' -- ' . __FILE__ . ':' . __LINE__;
 
$this->infosImages = $this->Bdd->recupererTous($requete);
}
 
private function chargerListeImages() {
$refTax = $this->parametres['referentiel'];
$numNomListe = implode(',', $this->ref_tax_demande[$refTax]);
$depart = $this->parametres['navigation.depart'];
$limite = $this->parametres['navigation.limite'];
 
//TODO: modifier la requete lors du passage à la nouvelle base de données pour faire quelque chose
// du numéro nomenclatural + modifier les champs appelés pour le nouveau format
$requete = 'SELECT SQL_CALC_FOUND_ROWS '.
' co.id_observation AS id_obs, co.courriel_utilisateur AS utilisateur_courriel, co.zone_geo, co.ce_zone_geo, '.
' co.nom_sel, co.nom_sel_nn, '.
' ci.id_image AS id_img, co.date_observation AS date '.
(isset($this->parametres['retour.champs']) ? ', '.$this->parametres['retour.champs'] : '').
'FROM cel_images AS ci'.
' LEFT JOIN cel_obs AS co '.
' ON (ci.ce_observation = co.id_observation) '.
$this->formerRequeteConditions($numNomListe).' '.
'GROUP BY id_img '.
$this->formerRequeteTri().
"LIMIT $depart,$limite " . ' -- ' . __FILE__ . ':' . __LINE__;
 
$this->infosImages = $this->Bdd->recupererTous($requete);
}
 
private function formerRequeteConditions($numNomListe) {
$refTax = $this->parametres['referentiel'];
$where[] = " co.transmission = 1 AND co.nom_ret_nn IN ($numNomListe) ";
$where[] = " co.nom_referentiel LIKE ".$this->Bdd->proteger($refTax."%").' ';
return ' WHERE '.implode(' AND ', $where);
}
 
private function formerRequeteTri() {
$order = '';
if (isset($this->parametres['retour.tri']) && $this->parametres['retour.tri'] == 'date') {
$order = ' ORDER BY co.date_observation ASC ';
}
return $order;
}
 
private function chargerNbreImagesTotal() {
$requete = 'SELECT FOUND_ROWS() AS nbre ';
$resultats = $this->Bdd->recuperer($requete);
$this->nbreImages = (int) $resultats['nbre'];
}
 
//+---------------------------------------CHEMIN ET CONVERSION--------------------------------------------------------+
private function recupererImageBinaire($id_image) {
$image = '';
$chemin = $this->obtenirCheminImage($id_image);
$image = file_get_contents($chemin);
if ($image === false) {
$message = "L'image demandée est introuvable sur le serveur : $chemin";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $image;
}
 
private function obtenirCheminImage($idImage) {
$nom = $this->convertirIdImageVersNomFichier($idImage);
$dossier = $this->convertirIdImageVersChemin($idImage);
return $dossier.'/'.$nom;
}
 
private function convertirIdImageVersNomFichier($idImage) {
$codeImage = $this->construireCodeImage($idImage);
$nom_fichier = $codeImage.'.jpg';
return $nom_fichier;
}
 
private function convertirIdImageVersChemin($idImage) {
$codeImage = $this->construireCodeImage($idImage);
list($dossierNiveau1, $dossierNiveau2, $idFichier, $format) = explode('_', $codeImage);
$chemin_sur_serveur = $this->cheminImagesBase.'/'.$dossierNiveau1.'/'.$dossierNiveau2.'/'.$format;
return $chemin_sur_serveur;
}
 
private function construireCodeImage($idImage) {
$codeImage = sprintf('%09s', $idImage);
$codeImage = wordwrap($codeImage, 3, '_', true);
$format = $this->parametres['retour.format'];
$codeImage .= '_'.$format;
return $codeImage;
}
 
//+------------------------------------FORMATAGE LISTE----------------------------------------------------------------+
private function formaterListeImages() {
$entete = $this->construireEntete();
$resultats = $this->construireResultats();
 
$resultat = array('entete' => $entete, 'resultats' => $resultats);
return $resultat;
}
 
private function construireEntete() {
$entete = array('masque' => '', 'depart' => 0, 'limite' => 100, 'total' => 0);
 
$entete['masque'] = $this->recupererMasque();
$entete['depart'] = (int) $this->parametres['navigation.depart'];
$entete['limite'] = (int) $this->parametres['navigation.limite'];
$entete['total'] = $this->nbreImages;
if ($hrefPrecedent = $this->recupererHrefPrecedent()) {
$entete['href.precedent'] = $hrefPrecedent;
}
if ($hrefSuivant = $this->recupererHrefSuivant()) {
$entete['href.suivant'] = $hrefSuivant;
}
return $entete;
}
 
private function recupererMasque() {
$masqueEntete = '';
if ($masqueNn = $this->parametres['masque.nn']) {
$masqueEntete = "nn=$masqueNn";
}
return $masqueEntete;
}
 
private function recupererHrefPrecedent() {
$departActuel = $this->parametres['navigation.depart'];
$limite = $this->parametres['navigation.limite'];
$departPrecedent = $departActuel - $limite;
$url = null;
if ($departPrecedent >= 0) {
$url = $this->obtenirUrlNavigation($departPrecedent, $limite);
}
return $url;
}
 
private function recupererHrefSuivant() {
$departActuel = $this->parametres['navigation.depart'];
$limite = $this->parametres['navigation.limite'];
$departSuivant = $departActuel + $limite;
$url = null;
if ($departSuivant < $this->nbreImages) {
$url = $this->obtenirUrlNavigation($departSuivant, $limite);
}
return $url;
}
 
private function obtenirUrlNavigation($depart, $limite) {
$parametres = array(
'navigation.depart' => $depart,
'navigation.limite' => $limite);
if (isset($this->parametres['masque.nn'])) {
$parametres['masque.nn'] = $this->parametres['masque.nn'];
}
$this->UrlNavigation->setRequete($parametres);
$url = $this->UrlNavigation->getURL();
return $url;
}
 
private function construireResultats() {
$resultats = array();
$this->extraireIdentitesAuteurs();
foreach ($this->infosImages as $img) {
$info = $this->formaterInfosImage($img);
$id = $img['id_img'];
$info['href'] = $this->config['urlService'].'/'.$id;
if (!isset($resultats[$id])) {
$resultats[$id] = $info;
} else {
throw new Exception("Double : $id");
}
}
return $resultats;
}
 
private function formaterInfosImage($img) {
$info = array();
$info['date'] = $img['date'];
$info['mime'] = self::MIME_JPEG;
$info['auteur.libelle'] = $this->Utilisateurs->getIntitule($img['utilisateur_courriel']);
$info['auteur.id'] = $this->Utilisateurs->getId($img['utilisateur_courriel']);
$info['binaire.href'] = $this->formaterUrlImage($img);
$info['observation.id'] = $img['id_obs'];
if (isset($img['nom_sel'])) {
$info['determination.libelle'] = $this->formaterDetermination($img);
$info['determination.nom_sci'] = $img['nom_sel'];
$info['determination.nom_sci.code'] = $this->formaterNomSciCode($img);
}
$info = array_merge($info, $this->formaterStation($img));
return $info;
}
 
private function extraireIdentitesAuteurs() {
$courriels = array();
foreach ($this->infosImages as $img) {
$courriels[] = $img['utilisateur_courriel'];
}
// pour Acer monspessulanum L. Sapindaceae, cela divise par 9 le nombre
// de courriels (213 => 23)
$courriels = array_values(array_unique($courriels, SORT_STRING));
$this->Utilisateurs->setCourriels($courriels);
// XXX: webservices: /service:annuaire:utilisateur/identite-par-courriel/ [/bibliotheque/Utilisateurs.php]
$this->Utilisateurs->chargerIdentites();
}
 
private function formaterUrlImage($infos) {
$format = $this->parametres['retour.format'];
$id = sprintf('%09s', $infos['id_img']).$format;
$url = sprintf($this->tpl_url_img, $id);
return $url;
}
 
private function formaterDetermination($infos) {
$auteur = $this->Utilisateurs->getIntitule($infos['utilisateur_courriel']);
return $infos['nom_sel']."[Dét. : $auteur]";
}
 
private function formaterNomSciCode($infos) {
return $this->parametres['referentiel'].'.'.$infos['nom_sel_nn'];
}
 
private function formaterStation($infos) {
$station = array();
if (isset($infos['zone_geo']) && $commune = $this->formaterCommune($infos)) {
$station['station.commune'] = $commune;
}
if (isset($infos['lieudit']) && $this->avoirContenu($infos['lieudit'])) {
$station['station.lieudit'] = $infos['lieudit'];
}
if (isset($infos['station']) && $this->avoirContenu($infos['station'])) {
$station['station.station'] = $infos['station'];
}
 
if (isset($infos['milieu']) && $this->avoirContenu($infos['milieu'])) {
$station['station.milieu'] = $infos['milieu'];
}
if (count($station) >= 1) {
$station['station.libelle'] = implode(' > ', $station);
}
return $station;
}
 
private function formaterCommune($infos) {
$commune = array();
if ($this->avoirContenu($infos['zone_geo'])) {
$commune[] = $infos['zone_geo'];
}
if (isset($infos['ce_zone_geo']) && $this->avoirContenu($infos['ce_zone_geo']) && $infos['ce_zone_geo'] != 'INSEE-C:') {
$commune[] = '('.substr(str_replace('INSEE-C:','',$infos['ce_zone_geo']), 0, 2).')';
}
return implode(' ', $commune);
}
 
private function avoirContenu($info) {
return !($info == null || $info == '' || $info == '000null');
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bibliobota/Publications.php
New file
0,0 → 1,330
<?php
// declare(encoding='UTF-8');
/**
* Classe implémentant l'API d'eFlore Publications pour le projet Biblio bota.
*
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Publications
*
* @package eFlore/services
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @author Aurélien PERONNET <aurelien@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)
*/
// TODO : Config et Outils sont des classes statiques qui doivent poser des pb pour les tests...
class Publications extends Commun {
 
protected $parametres;
protected $ressources;
private $Bdd;
protected $config;
private $nbrePublications;
private $masque_taxon;
protected $service = 'publications';
public function __construct(Bdd $bdd = null, Array $config = null, Utilisateurs $utilisateurs = null, Url $url = null) {
$this->Bdd = is_null($bdd) ? new Bdd() : $bdd;
$this->UrlNavigation = is_null($url) ? new Url($this->config['url_service']) : $url;
}
 
public function consulter($ressources, $parametres) {
$resultat = new ResultatService();
$this->parametres = $parametres;
$this->ressources = $ressources;
 
$this->definirValeurParDefautDesParametres();
$this->verifierParametres();
$this->recupererParametresMasque();
$this->chargerNbrePublicationsTotal();
$publications = $this->getPublications($this->masque_taxon);
$resultat->corps = $this->formaterPublications($publications);
 
return $resultat;
}
 
public function getPublications($cherche) {
$depart = $this->parametres['navigation.depart'];
$limite = $this->parametres['navigation.limite'];
$tab_mots = preg_split('~ ~', $cherche, -1, PREG_SPLIT_NO_EMPTY);
$sql = 'SELECT DISTINCT B_C_CRAI, B_C_NOMCOMPLET, B_C_ABREGE, ' .
' B_F_NUMERO, B_F_TITRE, B_F_DATE, B_F_CRAICOLL, '.
' B_SER_SOUSTITRE, '.
' B_A_PAGEDEBUT, B_A_PAGEFIN, B_A_CRAIFASC, B_A_CRAISERIE, ' .
' B_D_ID, B_D_LABEL, ' .
' B_S_IDSTR, B_S_NOM, ' .
' B_AS_LIBELLE, '.
' biblio_serie.*, biblio_item.*, biblio_item_typlog.*, biblio_item_typphy.* '.
'FROM biblio_item '.
' LEFT JOIN biblio_aut_saisie ON (b_i_auteursaisie = b_as_id) '.
' LEFT JOIN biblio_article ON (b_i_iditem = b_a_idart) '.
' LEFT JOIN biblio_fasc ON '.
' (B_F_CRAICOLL = B_A_CRAICOLL '.
' AND B_F_CRAISERIE = B_A_CRAISERIE '.
' AND B_F_NUMERO = B_A_CRAIFASC)' .
' LEFT JOIN biblio_serie ON ' .
' (b_f_craicoll = b_ser_craicoll ' .
' AND b_f_craiserie = b_ser_idserie) '.
' LEFT JOIN biblio_collection ON (b_ser_craicoll = b_c_crai) '.
' LEFT JOIN biblio_str ON (B_C_LKSTR = B_S_IDSTR) '.
' LEFT JOIN biblio_domaine_lier ON (b_i_iditem = b_dl_iditem) ' .
' LEFT JOIN biblio_domaine ON (b_dl_iddom = b_d_id) ' .
' LEFT JOIN biblio_item_typphy ON (b_i_typphy = b_ip_id) ' .
' LEFT JOIN biblio_item_typlog ON (b_i_typlog = b_il_id) ' .
' WHERE B_I_TYPLOG = 1 AND B_I_TYPPHY = 2 AND B_I_CACHER = 0 '.
' AND B_D_ID = 1 ';
foreach ($tab_mots as $mot) {
$sql .= " AND (B_I_TITRE LIKE '%$mot%' ".
" OR B_I_RESUMCLE LIKE '%$mot%' ".
" OR B_I_COMMENT LIKE '%$mot%') ";
}
$sql .= 'ORDER BY B_I_AUTEURS LIMIT '.$depart.', '.$limite;
 
$publications = $this->Bdd->recupererTous($sql);
return $publications;
}
function formaterPublications($publications) {
$resultats = array();
foreach($publications as $publication) {
$id_a = $publication['B_I_IDITEM'];
$titre = $publication['B_I_TITRE'];
$auteurs = $publication['B_I_AUTEURS'];
$geo = $publication['B_I_GEO'];
$langue = $publication['B_I_LANGUE'];
$resum = $publication['B_I_RESUMCLE'];
$image = $publication['B_I_IMAGE'];
$comment = $publication['B_I_COMMENT'];
// Table Auteur Saisie
$saisie = $publication['B_AS_LIBELLE'];
// Table Domaine
$domaine_id = $publication['B_D_ID'];
$domaine_nom = $publication['B_D_LABEL'];
// Table Collection
$coll_nom = $publication['B_C_NOMCOMPLET'];
$coll_abreviation = $publication['B_C_ABREGE'];
// Table S�rie
$serie_titre = $publication['B_SER_SOUSTITRE'];
// Table Fascicule
$craicoll = $publication['B_F_CRAICOLL'];
$date = $publication['B_F_DATE'];
$fascicule_titre = $publication['B_F_TITRE'];
// Table Article
$craifasc = $publication['B_A_CRAIFASC'];
$craiserie = $publication['B_A_CRAISERIE'];
$page_debut = $publication['B_A_PAGEDEBUT'];
$page_fin = $publication['B_A_PAGEFIN'];
// Table Structure
$nomstr = $publication['B_S_NOM'];
// Formatage de la chaine de publication
$chainePublication = "";
if (isset($domaine_nom)) {
$chainePublication .= '<span class="texte_inactif">['.$domaine_nom.']</span>';
}
if (isset($auteurs)) {
$chainePublication .= $auteurs;
}
if (isset($titre)) {
$chainePublication .= " - <strong>$titre</strong>";
}
if (isset($date)) {
$chainePublication .= " - $date";
}
 
if (isset($mots_cles)) {
$chainePublication .= " - <em>$mots_cles</em>";
}
if (isset($page_debut)) {
$chainePublication .= ", p. $page_debut";
if (isset($page_fin)) {
$chainePublication .= "- $page_fin";
}
}
if (isset($geo)) {
$chainePublication .= " - Départ./Région : <em>$geo</em>";
}
if (isset($structure)) {
$chainePublication .= " - $structure";
}
if (isset($coll_nom)) {
$chainePublication .= ", $coll_nom";
}
if (isset($craiserie)) {
$chainePublication .= ", $craiserie";
}
if (isset($lien)) {
$chainePublication .= ", <a class=\"lien_ext\" href=\"$lien_url\">$fascicule_titre</a>";
} else {
$chainePublication .= ", $fascicule_titre";
}
if (isset($saisie_auteur)) {
$chainePublication .= " - <span class=\"texte_inactif\">Saisie : $saisie_auteur - Art. n°$article_id</span>";
}
$resultats[$id_a]['reference_html'] = $chainePublication;
}
$retour = array('entete' => $this->construireEntete(), 'resultats' => $resultats);
return $retour;
}
private function definirValeurParDefautDesParametres() {
if (isset($this->parametres['navigation.depart']) == false) {
$this->parametres['navigation.depart'] = 0;
}
if (isset($this->parametres['navigation.limite']) == false) {
$this->parametres['navigation.limite'] = 10;
}
}
 
private function verifierParametres() {
$erreurs = array();
if ($this->verifierValeurParametreNavigationDepart() == false) {
$erreurs[] = "Le paramètre 'navigation.depart' doit possèder un valeur numérique.";
}
if ($this->verifierValeurParametreNavigationLimite() == false) {
$erreurs[] = "Le paramètre 'navigation.limite' doit possèder un valeur numérique supérieure à 0.";
}
 
if (count($erreurs) > 0) {
$message = implode('<br />', $erreurs);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
}
 
private function verifierValeurParametreNavigationDepart() {
$depart = $this->parametres['navigation.depart'];
$ok = is_numeric($depart) ? true : false;
return $ok;
}
 
private function verifierValeurParametreNavigationLimite() {
$limite = $this->parametres['navigation.limite'];
$ok = (is_numeric($limite) && $limite != 0) ? true : false;
return $ok;
}
 
private function recupererParametresMasque() {
if (isset($this->parametres['masque.taxon'])) {
$this->masque_taxon = $this->parametres['masque.taxon'];
} else {
$this->masque_taxon = "";
}
}
 
private function chargerNbrePublicationsTotal() {
$tab_mots = preg_split('~ ~', $this->masque_taxon, -1, PREG_SPLIT_NO_EMPTY);
$requete = 'SELECT COUNT(B_I_IDITEM) AS nbre '.
'FROM biblio_item '.
' LEFT JOIN biblio_aut_saisie ON (b_i_auteursaisie = b_as_id) '.
' LEFT JOIN biblio_article ON (b_i_iditem = b_a_idart) '.
' LEFT JOIN biblio_fasc ON '.
' (B_F_CRAICOLL = B_A_CRAICOLL '.
' AND B_F_CRAISERIE = B_A_CRAISERIE '.
' AND B_F_NUMERO = B_A_CRAIFASC)' .
' LEFT JOIN biblio_serie ON ' .
' (b_f_craicoll = b_ser_craicoll ' .
' AND b_f_craiserie = b_ser_idserie) '.
' LEFT JOIN biblio_collection ON (b_ser_craicoll = b_c_crai) '.
' LEFT JOIN biblio_str ON (B_C_LKSTR = B_S_IDSTR) '.
' LEFT JOIN biblio_domaine_lier ON (b_i_iditem = b_dl_iditem) ' .
' LEFT JOIN biblio_domaine ON (b_dl_iddom = b_d_id) ' .
' LEFT JOIN biblio_item_typphy ON (b_i_typphy = b_ip_id) ' .
' LEFT JOIN biblio_item_typlog ON (b_i_typlog = b_il_id) ' .
' WHERE B_I_TYPLOG = 1 AND B_I_TYPPHY = 2 AND B_I_CACHER = 0 '.
' AND B_D_ID = 1 ';
foreach ($tab_mots as $mot) {
$requete .= " AND (B_I_TITRE LIKE '%$mot%' ".
" OR B_I_RESUMCLE LIKE '%$mot%' ".
" OR B_I_COMMENT LIKE '%$mot%') ";
}
$resultats = $this->Bdd->recuperer($requete);
$this->nbrePublications = (int) $resultats['nbre'];
}
 
private function construireEntete() {
$entete = array('masque' => '', 'depart' => 0, 'limite' => 10, 'total' => 0);
 
$entete['masque'] = $this->recupererMasque();
$entete['depart'] = (int) $this->parametres['navigation.depart'];
$entete['limite'] = (int) $this->parametres['navigation.limite'];
$entete['total'] = $this->nbrePublications;
if ($hrefPrecedent = $this->recupererHrefPrecedent()) {
$entete['href.precedent'] = $hrefPrecedent;
}
if ($hrefSuivant = $this->recupererHrefSuivant()) {
$entete['href.suivant'] = $hrefSuivant;
}
return $entete;
}
 
private function recupererMasque() {
$masqueEntete = '';
if ($this->masque_taxon) {
$masqueEntete = "masque.taxon=$this->masque_taxon";
}
return $masqueEntete;
}
private function recupererHrefPrecedent() {
$departActuel = $this->parametres['navigation.depart'];
$limite = $this->parametres['navigation.limite'];
$departPrecedent = $departActuel - $limite;
$url = null;
if ($departPrecedent >= 0) {
$url = $this->obtenirUrlNavigation($departPrecedent, $limite, array('masque.taxon' => $this->masque_taxon));
}
return $url;
}
 
private function recupererHrefSuivant() {
$departActuel = $this->parametres['navigation.depart'];
$limite = $this->parametres['navigation.limite'];
$departSuivant = $departActuel + $limite;
$url = null;
if ($departSuivant < $this->nbrePublications) {
$url = $this->obtenirUrlNavigation($departSuivant, $limite, array('masque.taxon' => $this->masque_taxon));
}
return $url;
}
 
private function obtenirUrlNavigation($depart, $limite, $parametresAdditionnels) {
$parametres = array(
'navigation.depart' => $depart,
'navigation.limite' => $limite);
if ($parametresAdditionnels != null) {
$parametres = array_merge($parametres, $parametresAdditionnels);
}
$this->UrlNavigation->setRequete($parametres);
$url = $this->UrlNavigation->getURL();
return $url;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtfx/CommunNomsTaxons.php
New file
0,0 → 1,954
<?php
// declare(encoding='UTF-8');
/**
* Description :
* Classe CommunNomsTaxons.php
* 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-2011 Tela Botanica (accueil@tela-botanica.org)
*/
 
 
abstract class CommunNomsTaxons extends Commun {
 
/** Tableau de correspondance entre les noms des champs et les codes de l'ontologie.*/
private $relationsChampsCodesOntologie = null;
protected $table_retour; //Permet de stocker le tableau de résultat (non encodé en json)
protected $resultat_req; // Permet de stocker le résultat de la requete principale.
protected $compo_nom = null; //Stocke sous forme de tableau les composant du nom à ajouter au nom scientifique
protected $table;// Nom de la table dans laquelle on récupèrera les données dans les requetes SQL
protected $total_resultat = null;
/** Stocke le service appelé correspondant. Est utilisé principalement lors de l'affichage du href d'un synonyme
(ex id=12, basionyme num 25 est un synonyme) dans le service taxon */
protected $service_href = null;
protected $erreursParametres = null;
protected $sans_nom_sci = array('gen','sp','ssp','fam','au_ss','bib_ss');
private $bib_traitees = array();
private $ontologie = array();
 
//+------------------------------- PARAMÈTRES ---------------------------------------------------------------+
 
public function traiterParametres() {
$this->definirParametresParDefaut();
$this->verifierParametres();
 
if (isset($this->parametres) && count($this->parametres) > 0) {
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'ns.structure' :
$this->remplirTableCompositionNom($val);
if (in_array($val,$this->sans_nom_sci)){
$this->requete_champ = implode(', ',$this->compo_nom);
}else {
$this->requete_champ .= ' ,'.implode(', ',$this->compo_nom);
}
break;
case 'navigation.depart' :
$this->limite_requete['depart'] = $val;
break;
case 'navigation.limite' :
$this->limite_requete['limite'] = $val;
break;
}
}
$this->traiterParametresSpecifiques();
}
}
 
protected function definirParametresParDefaut() {
if (empty($this->parametres['recherche'])) {
$this->parametres['recherche'] = 'stricte';
}
if (empty($this->parametres['ns.format'])) {
$this->parametres['ns.format'] = 'txt';
}
if (empty($this->parametres['retour.format'])) {
$this->parametres['retour.format'] = 'max';
}
if (empty($this->parametres['ns.structure']) &&
$this->parametres['retour.format'] != 'oss') {
$this->parametres['ns.structure'] = 'au,an,bib,bib_excl';
}
}
 
 
public function verifierParametres() {
//$this->verifierParametresAPI();
 
$this->verifierParametre('recherche', 'stricte|floue|etendue|complete');
$this->verifierParametre('ns.format', 'htm|txt');
$this->verifierParametre('retour.format', 'min|max|oss|perso');
$this->verifierParametreAvecValeurMultipe('ns.structure', 'an|au|bib|ad|gen|sp|ssp|fam|au_ss|bib_ss|bib_excl');
 
/*if (count($this->erreursParametres) > 0) {
$m = 'Erreur dans votre requête : '.implode('<br/>', $this->erreursParametres);
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}*/
}
 
public function verifierParametresAPI() {
$parametresApi = $this->recupererTableauConfig('parametresAPI');
while (!is_null($parametre = key($this->parametres))) {
if (!in_array($parametre, $parametresApi)) {
$this->erreursParametres[] = "Le paramètre '$parametre' n'est pas pris en compte par cette version de l'API.";
}
next($this->parametres);
}
}
 
public function verifierParametre($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeur = $this->parametres[$parametre];
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
 
public function verifierParametreAvecValeurMultipe($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeursConcatenees = $this->parametres[$parametre];
$valeurs = explode(',', $valeursConcatenees);
foreach ($valeurs as $valeur) {
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
}
 
private function verifierValeursPermises($parametre, $valeur, $valeursPermises) {
if (!in_array($valeur, explode('|', $valeursPermises))) {
$this->erreursParametres[] = "Le paramètre '$parametre' ne peut pas prendre la valeur '$valeur'. Valeurs permises : $valeursPermises";
}
}
 
public function traiterParametresCommuns() {
 
}
 
public function ajouterFiltreMasque($nom_champ, $valeur) {
$orig_val = $valeur;
$valeur = explode(',',$valeur);
$conditions = array();
if ($nom_champ == 'annee' || $nom_champ == 'rang') {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ = ".$this->getBdd()->proteger($val);
}
} else {
if ($this->parametres['recherche'] == 'etendue') {
foreach ($valeur as $val) {
$val = $this->modifierValeur($val);
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
 
} elseif ($this->parametres['recherche'] == 'floue') {
foreach ($valeur as $val) {
$val = $this->getBdd()->proteger($val);
$conditions[] = "( SOUNDEX($nom_champ) = SOUNDEX($val))".
" OR ( SOUNDEX(REVERSE($nom_champ)) = SOUNDEX(REVERSE($val)))";
}
// utile pour la détermination à partir d'un nom retenu (concat(nom_sci,auteur)) lors
// d'un import depuis le CEL
} elseif ($this->parametres['recherche'] == 'concat' && $nom_champ == 'nom_sci') {
$conditions[] = "CONCAT(nom_sci, ' ', auteur) = " . $this->getBdd()->proteger($orig_val);
 
} else {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
}
}
$this->requete_condition[]= '('.implode(' OR ', $conditions ).')';
$this->masque[$nom_champ] = $nom_champ.'='.implode(',',$valeur);
}
 
private function modifierValeur($valeur) {
$valeur = $this->remplacerCaractereHybrideEtChimere($valeur);
$valeur = $this->preparerChainePourRechercheEtendue($valeur);
return $valeur;
}
 
private function remplacerCaractereHybrideEtChimere($valeur) {
$caracteres = array('×', '%D7', '+', '%2B');
$remplacements = array('x ','x ', '+', '+');
$valeur = str_replace($caracteres, $remplacements, $valeur);
return $valeur;
}
 
private function preparerChainePourRechercheEtendue($valeur) {
$valeur = str_replace(' ', '% ', trim($valeur));
$valeur = $valeur.'%';
return $valeur;
}
 
//+-------------------------------Fonctions d'analyse des ressources-------------------------------------+
 
private function etreRessourceId() {
$ok = false;
if ($this->estUnIdentifiant() && count($this->ressources) == 1) {
$ok = true;
}
return $ok;
}
 
public function traiterRessources() {
if (isset($this->ressources) && count($this->ressources) > 0) {
if ($this->ressources[0] == 'relations') {
$this->traiterRessourceIdRelations();
} elseif ($this->estUnIdentifiant()) { //l'identifiant peut etre de type /#id ou /nt:#id
$this->traiterRessourcesIdentifiant(); // dans le service noms ou taxons
} elseif ($this->ressources[0] == 'stats') { //ressource = noms/stats
$this->traiterRessourcesStats();
} else {
$e = 'Erreur dans votre requete </br> Ressources disponibles : <br/>
<li> /'.$this->service.'/#id (id : L\'identifiant du nom rechercher)</li>
<li> /'.$this->service.'/nt:#id (id : Numero du taxon recherche)</li>
<li> /'.$this->service.'/stats </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
}
 
public function traiterRessourcesStats() {
$this->format_reponse = $this->service.'/stats';
 
$e = "Erreur dans votre requête </br> Ressources disponibles : $this->service/stats/[annees|rangs|initiales]";
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
switch ($this->ressources[1]) {
case 'annees' :
$this->traiterRessourceStatsAnnees();
break;
case 'rangs' :
$this->traiterRessourceStatsRangs();
break;
case 'initiales' :
$this->traiterRessourceStatsInitiales();
break;
default :
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
} else {
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
/** Vérifie si la première valeur de la table de ressource est un identifiant :
* un numerique ou un numéro taxonomique sous la forme nt:xx */
public function estUnIdentifiant() {
return (is_numeric($this->ressources[0]) || (strrpos($this->ressources[0],'nt:') !== false
&& is_numeric(str_replace('nt:','',$this->ressources[0]))));
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonction d'analyse des parametres
 
/** Permet de remplir le tableau compo_nom. Il comprendra en fct du paramètre ns.structure les éléments à rajouter
* au nom_sci (annee, auteur, biblio ou addendum). */
public function remplirTableCompositionNom($valeur) {
$structure_nom = explode(',', $valeur);
 
foreach ($structure_nom as $structure) {
$structure = trim($structure);
$patterns = array('/^an$/', '/^au$/', '/^bib$/', '/^ad$/', '/^sp$/', '/^gen$/', '/^ssp$/','/^fam$/',
'/^au_ss$/','/^bib_ss$/','/^bib_excl$/');
$champs = array('annee', 'auteur', 'biblio_origine', 'nom_addendum', 'epithete_sp', 'genre',
'epithete_infra_sp','famille','auteur', 'biblio_origine','source_biblio_exclure');
 
// avec str_replace() 'sp' est inclu dans 'ssp', et la conversion pour 'ssp' est mauvaise
$this->compo_nom[$structure] = preg_replace($patterns, $champs, $structure);
}
}
 
public function mettreAuFormat() {
if ($this->parametres['ns.format'] == 'htm') {
if (strrpos($this->requete_champ, 'nom_sci_html as nom_sci') === false) {
$this->requete_champ = str_replace('nom_sci', 'nom_sci_html as nom_sci', $this->requete_champ);
}
}
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonctions de formatage
 
/** 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. */
public function recupererTableSignification($table) {
$tables = explode(',', $table);
foreach ($tables as $tab) {
if ($tab == 'champs_comp') {
$champ_bdnff_api = array_keys($this->champs_api); //on recupère le nom des champ ds la bdd
$this->champs_comp = array_diff($this->champs_table, $champ_bdnff_api);
} elseif ($tab == 'champs_api') {
foreach ($this->correspondance_champs as $key => $val) {
preg_match('/(hybride[.]parent_0[12](?:[.]notes)?|nom_sci[.][^.]+|[^.]+)(?:[.](id|code))?/', $val, $match);
$val = $match[1];
$this->champs_api[$key] = $val;
}
} else {
$this->$tab = $this->recupererTableauConfig($tab);
}
}
}
 
public function formaterEnOss($resultat) {
$table_nom = array();
$oss = '';
foreach ($resultat as $tab) {
if (isset($tab['nom_sci']) ) {
if (!in_array($tab['nom_sci'], $table_nom)) {
$table_nom[] = $tab['nom_sci'];
$oss[] = $tab['nom_sci'].' '.$this->ajouterCompositionNom($tab);
}
}else {
$res = $this->ajouterCompositionNom($tab);
if($res) {
$oss[] = $res;
}
}
 
}
 
if (isset($this->masque)) $masque = implode('&', $this->masque);
else $masque = 'Pas de masque';
$table_retour_oss = array($masque, $oss);
return $table_retour_oss;
}
 
public function afficherEnteteResultat($url_service) {
$arr = array(
'depart' => $this->limite_requete['depart'],
'limite' => $this->limite_requete['limite'],
'total' => $this->total_resultat);
 
if (isset($this->masque))
$arr['masque'] = implode('&', $this->masque);
 
$url = $this->formulerUrl($this->total_resultat, $url_service);
if (isset($url['precedent']) && $url['precedent'] != '') {
$arr['href.precedent'] = $url['precedent'];
}
if (isset($url['suivant']) && $url['suivant'] != '') {
$arr['href.suivant'] = $url['suivant'];
}
return $arr;
}
 
public function afficherNomHrefRetenu($tab, $num) {
$this->resultat_req = $tab;
$this->afficherDonnees('num_nom', $num);
if ($this->parametres['retour.format'] == 'min') { // sinon est affiché ds afficherDonnees(num_nom, $val) ci-dessus
$this->table_retour['nom_sci'] = $tab['nom_sci'];
$this->table_retour['nom_sci_complet'] = $tab['nom_sci'].' '.$this->ajouterCompositionNom($tab);
}
if ($tab['num_nom_retenu'] != '') {
$retenu = ($tab['num_nom_retenu'] == $num) ? 'true' : 'false';
} else {
$retenu = 'absent';
}
$this->table_retour['retenu'] = $retenu;
// Pourquoi ce unset ? JPM - 28-03-2013
unset($this->table_retour['id']);
}
 
 
//+------------------------------------------------------------------------------------------------------+
// Fonction de formatage pour les services /#id/
 
public function formaterId($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
 
foreach ($resultat as $cle => $valeur) {
if ($valeur != '') {
$this->afficherDonnees($cle, $valeur);
}
}
if (isset($this->parametres['retour.champs']) && $this->format_reponse == 'noms/id') {
$retour = $this->table_retour;
$this->table_retour = array();
$champs = explode(',', $this->parametres['retour.champs']);
$this->ajouterChampsPersonnalises($champs, $retour);
}
unset($this->table_retour['href']);
return $this->table_retour;
}
 
public function formaterIdChamp($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$reponse_id = $this->formaterId($resultat);
$this->table_retour = array();
$champs = explode(' ', $this->ressources[1]);
$this->ajouterChampsPersonnalises($champs, $reponse_id);
return $this->table_retour;
}
 
protected function ajouterChampsPersonnalises($champs, $reponse_id) {
$champs_a_libeller = array('nom_retenu', 'rang', 'basionyme', 'hybride', 'hybride.parent_01',
'hybride.parent_02', 'presence', 'tax_sup', 'statut_origine', 'statut_culture', 'statut_introduction');
$champs_forces = array('rang'); // même s'ils sont dans "à libeller", on les prend quand même en brut, en plus
if (! is_null($champs) && is_array($champs) && count($champs) > 0) {
foreach ($champs as $champ) {
if ($this->verifierValiditeChamp($champ)) {
if (strrpos($champ, '.*') !== false) {
$this->afficherPointEtoile($champ, $reponse_id);
} elseif (in_array($champ, $champs_a_libeller)) {
$this->table_retour[$champ.'.libelle'] =
(isset($reponse_id[$champ.'.libelle'])) ? $reponse_id[$champ.'.libelle'] : null;
} else {
$champ = $this->trouverChampBddCorrespondant($champ);
$this->table_retour[$champ] = (isset($reponse_id[$champ])) ? $reponse_id[$champ] : null;
}
// champs bruts en plus, ajouté pour obtenir le rang, mais retourne rang.code avec du kk dedans :-/
if (in_array($champ, $champs_forces)) {
$champ = $this->trouverChampBddCorrespondant($champ);
$this->table_retour[$champ] = (isset($reponse_id[$champ])) ? $reponse_id[$champ] : null;
}
}
}
}
}
 
public function afficherPointEtoile($champ, $reponse) {
preg_match('/^([^.]+\.)\*$/', $champ, $match);
if ($match[1] == 'nom_sci') {
$this->afficherNomSciPointEpithete($this->resultat_req);
} else {
foreach ($reponse as $chp => $valeur) {
if (strrpos($chp, $match[1]) !== false) {
if ($valeur != '') {
$this->table_retour[$chp] = $valeur;
} else {
$this->table_retour[$chp] = null;
}
}
}
}
}
 
public function decomposerNomChamp($champ) {
$decomposition = false;
if (preg_match('/^(?:([^.]+\.parent_0[12]|[^.]+))(?:\.(.+))?$/', $champ, $match)) {
$radical_champ = $match[1];
$suffixe = (isset($match[2])) ? $match[2] : "";
$decomposition = array($radical_champ, $suffixe);
}
return $decomposition;
}
 
public function verifierValiditeChamp($champ) {
$decomposition = $this->decomposerNomChamp($champ);
$validite_ressource = true;
if ($decomposition) {
list($radical, $suffixe) = $decomposition;
$champs_complementaire = array('nom_retenu_complet', 'basionyme_complet');
// on verifie si le nom du champ existe bien
if (!$this->estChampApi($radical) && !$this->estChampComplementaire($radical)) {
if (!in_array($radical, $champs_complementaire)) {
$validite_ressource = false;
$e = 'Le champ "'.$radical.'" n\'existe pas dans la base. <br/><br/>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} elseif ($this->estUnPoint($champ)) {
$validite_ressource = $this->verifierValiditeSuffixe($suffixe, $radical);
}
}
return $validite_ressource;
}
 
public function estChampApi($radical_champ) {
$champ_api_ok = false;
if (in_array($radical_champ, $this->champs_api) || in_array($radical_champ, $this->correspondance_champs)) {
$champ_api_ok = true;
}
return $champ_api_ok;
}
 
public function estChampComplementaire($radical_champ) {
$champ_complementaire_ok = in_array($radical_champ, $this->champs_comp) ? true : false;
return $champ_complementaire_ok;
}
 
public function verifierValiditeSuffixe($suffixe, $radical_champ) {
$validite_ressource = true;
if ($this->correspondAUnId($radical_champ) || $radical_champ == 'id') {
$this->verificationSuffixesIdentifiant($suffixe, $radical_champ, $validite_ressource);
} elseif ($this->correspondAUnCode($radical_champ)) {
$this->verificationSuffixesCodes($suffixe, $radical_champ, $validite_ressource);
} elseif ($radical_champ == 'nom_sci') {
if ($suffixe != '*') {
$validite_ressource = false;
$m = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/>
Les suffixes possibles sont les suivants : <li> * </li>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
} else {
$validite_ressource = false;
$m = 'Erreur : Le paramètre "'.$radical_champ.'" ne peut pas présenter de suffixe. <br/><br/>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
return $validite_ressource;
}
 
public function verificationSuffixesCodes(&$suffixe, &$radical_champ, &$validite_ressource ) {
if (!in_array($suffixe, array('*', 'code', 'href', 'details'))) {
$validite_ressource = false;
$e = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'.<br/> Les suffixes '
.'possibles sont les suivants : <li> .* </li><li> .code </li><li> .href </li><li> .details </li>';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
public function verificationSuffixesIdentifiant(&$suffixe, &$radical_champ, &$validite_ressource) {
if ((strrpos($radical_champ, 'parent') !== false && !in_array($suffixe, array('*', 'id', 'href', 'details', 'notes')))
|| !in_array($suffixe, array('*', 'id', 'href', 'details')) && strrpos($radical_champ, 'parent') === false) {
$validite_ressource = false;
$e = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/> Les suffixes '
.'possibles sont les suivants : <li> .* </li><li> .id </li><li> .href </li><li> .details </li>'
.'<li> .notes (seulement pour les hybride.parent)';
$this->renvoyerErreur( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
 
//------------------------------fonction de formatage pour les services /stats/-----------------------------------------
 
public function formaterStatsAnnee($resultat) {
foreach ($resultat as $cle_annee) {
$annee = ($cle_annee['annee'] != '') ? $cle_annee['annee'] : 'ND';
$nb = $cle_annee['nombre'];
$retour_stats_annee[$annee] = $nb;
}
return $retour_stats_annee;
}
 
public function formaterStatsRang($resultat) {
foreach ($resultat as $rangs) {
if ($rangs['rang'] != 0) {
$rang = $rangs['rang'];
if ($this->parametres['retour.format'] == 'max') {
$retour_rang[$rang]['rang'] = $this->ajouterSignificationCode('rang',$rang);
}
$nombre = $rangs['nombre'];
$retour_rang[$rang]['nombre'] = $nombre;
}
}
return $retour_rang;
}
 
public function formaterStatsInitiales($resultat) {
$rang = null;
$table_rang = array();
foreach ($resultat as $tuple) {
if ($tuple['rang'] != 0) {
$this->memoriserRang($table_rang, $tuple, $rang);
if ($tuple['lettre'] == 'x ') {
$this->ajouterHybrideChimere('hybride', $rang, $tuple);
} elseif ($tuple['lettre'] == '+ ') {
$this->ajouterHybrideChimere('chimere', $rang, $tuple);
} else {
$l = substr($tuple['lettre'], 0, 1);
if (isset($this->table_retour[$rang][$l])) {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] += floatval($tuple['nb']);
} else {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] = floatval($tuple['nb']);
}
}
}
}
return $this->table_retour;
}
 
public function memoriserRang(&$table_rang, $tuple, &$rang) {
if (is_array($table_rang)) {
if (!in_array($tuple['rang'], $table_rang)) {
$rang = $tuple['rang'];
$table_rang[] = $rang;
if ($this->parametres['retour.format'] == 'max') {
$rang = $this->ajouterSignificationCode('rang', $rang);
}
}
}
}
 
public function ajouterHybrideChimere($groupe, &$rang, &$tuple) {
if (isset($this->table_retour[$rang][str_replace('hybride', 'hyb', $groupe)])) {
$this->table_retour[$rang][$groupe] += floatval($tuple['nb']);
} else {
$this->table_retour[$rang][$groupe] = floatval($tuple['nb']);
}
}
 
//-----------------------------Fonctions d'affichage utiliser dans les fonctions de formatage---------------------------
 
public function afficherDonnees($champApi, $valeur) {
$champBdd = $this->trouverChampBddCorrespondant($champApi);
 
if ($this->parametres['retour.format'] == 'min') {
if ($champApi == 'nom_sci') {
$valeur = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req);
}
if ($champApi == 'nom_sci_html') {
$valeur = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req, 'htm');
}
$this->table_retour[$champBdd] = $valeur;
// on essaye de permettre l'obtention du nom_sci_complet, y compris en retour.format == 'min',
// tout en évitant les appels aux ontologies
/*if ($this->correspondAUnId($champBdd) || $champBdd == 'id' && $valeur != '0') {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $champBdd, $match);
if(strpos($this->parametres['retour.format'], $match[1]) !== false) $this->afficherSignification($match[1], $valeur);
}*/
} else {
$this->afficherToutesLesInfos($champBdd, $valeur);
}
}
 
public function trouverChampBddCorrespondant($champApi) {
if (array_key_exists($champApi, $this->champs_api)) {
$champBdd = $this->correspondance_champs[$champApi];
} else {
$champBdd = $champApi;
}
return $champBdd;
}
 
public function afficherToutesLesInfos($nom_champ_api, $valeur) {
if ($this->presentePlusieursId($nom_champ_api, $valeur)) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'details', $valeur);
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif (strrpos($nom_champ_api, 'parent') !== false && strrpos($nom_champ_api, 'notes') !== false) {
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif (($this->correspondAUnId($nom_champ_api) || $nom_champ_api == 'id' && $valeur != '0')) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'id,signification,href', $valeur);
 
} elseif ($this->correspondAUnCode($nom_champ_api)) {
preg_match('/^([^.]+)(?:\.code)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'code,signification,href', $valeur);
 
} elseif ($nom_champ_api == 'nom_sci_html') {
$this->table_retour['nom_sci_html'] = $valeur;
$this->table_retour['nom_sci_html_complet'] = $valeur.' '.$this->ajouterCompositionNom($this->resultat_req, 'htm');
}elseif ($nom_champ_api != 'nom_sci') {
$this->table_retour[$nom_champ_api] = $valeur;
}
}
 
public function presentePlusieursId($ressource, $valeur = null) {
if ($valeur) {
$presente = strrpos($ressource, 'proparte') !== false && strrpos($valeur, ',') !== false;
} else { //pour la vérification du champ, on ignore alors la valeur de la ressource
$presente = strrpos($ressource, 'proparte') !== false;
}
return $presente;
}
 
public function afficherInfosPrecises($champ, $suffixe, $valeur) {
$suffixes = explode(',', $suffixe);
//on initialise au service appelé. Sera potentiellement modifié dans la fonction afficherSignification()
$this->service_href = $this->service;
foreach ($suffixes as $suffixe) {
switch ($suffixe) {
case 'id' :
$this->table_retour[str_replace('id.id', 'id', $champ.'.id')] = $valeur;
break;
case 'details' :
$this->afficherTableDetails($champ, $valeur);
break;
case 'signification' :
$this->afficherSignification($champ, $valeur);
break;
case 'href' :
$url = $this->creerUrl($champ, $valeur);
$this->table_retour[str_replace('id.href', 'href', $champ.'.href')] = $url;
break;
case 'code' :
$this->table_retour[$champ.'.code'] = $this->obtenirCode($champ, $valeur);
break;
case 'notes' :
$this->table_retour[$champ.'.notes'] = $this->resultat_req[str_replace('.', '_', $champ).'_notes'];
break;
default : break;
}
}
}
 
public function afficherTableDetails($nom_champ_api, $valeur) {
$tab_id = explode(',', $valeur);
$tab_res = $this->table_retour;
$this->table_retour = array();
foreach ($tab_id as $id) {
$this->afficherInfosPrecises($nom_champ_api, 'id,signification,href', $id);
$tab_res[$nom_champ_api.'.details'][] = $this->table_retour;
$this->table_retour = array();
}
$this->table_retour = $tab_res;
}
 
private function obtenirCode($champ, $valeur) {
$code = $this->transformerChampEnCode($champ);
return "bdnt.$code:$valeur";
}
 
private function transformerChampEnCode($champ) {
if (is_null($this->relationsChampsCodesOntologie)) {
$this->relationsChampsCodesOntologie = Outils::recupererTableauConfig('ChampsCodesOntologie');
}
 
$code = $champ;
if (array_key_exists($champ, $this->relationsChampsCodesOntologie)) {
$code = $this->relationsChampsCodesOntologie[$champ];
}
return $code;
}
 
public function creerUrl($champ, $valeur) {
if ($this->correspondAUnId($champ) || $champ == 'id') {
$service = $this->service_href;
$url = $this->ajouterHref($service, $valeur);
} else {
$code = $this->transformerChampEnCode($champ);
$url = $this->ajouterHrefAutreProjet('ontologies', "$code:", $valeur, 'bdnt');
}
return $url;
}
 
public function afficherSignification($champ, $valeur) {
if ($champ == 'id' && isset($this->resultat_req['nom_sci']) && $this->resultat_req['num_nom'] == $valeur) {
//si le nom_sci du num_nom que l'on veut afficher est déjà dans la table de résultat :
$this->table_retour['nom_sci'] = $this->resultat_req['nom_sci'];
$this->table_retour['nom_sci_complet'] = $this->resultat_req['nom_sci'] . (($suff = $this->ajouterCompositionNom($this->resultat_req)) ? ' ' . $suff : '');
} elseif ($this->correspondAUnId($champ) || $champ == 'id') {
$nom = $this->recupererNomSci($valeur);
if ($nom != array()) {
$this->table_retour[$champ.'.libelle'] = $nom['nom_sci'];
$this->table_retour[$champ.'_html'] = $nom['nom_sci_html'];
$this->table_retour[$champ.'_complet'] = $nom['nom_sci_complet'];
$this->table_retour[$champ.'_html_complet'] = $nom['nom_sci_complet_html'];
$this->service_href = $nom['service'];
}
} elseif ($this->correspondAUnCode($champ)) {
$this->table_retour[$champ.'.libelle'] = $this->ajouterSignificationCode($champ, $valeur);
}
}
 
/** Permet d'afficher les élements nomenclatural du nom_sci lors de l'appel dans le service noms/id/champ du champ^nom_sci.*/
public function afficherNomSciPointEpithete($resultat) {
$tab_nom_sci = array('nom_supra_generique', 'genre', 'epithete_infra_generique', 'epithete_sp',
'type_epithete', 'epithete_infra_sp', 'cultivar_groupe', 'cultivar', 'nom_commercial');
foreach ($tab_nom_sci as $compo_nom) {
if (isset($resultat[$compo_nom]) && !empty($resultat[$compo_nom])) {
$this->table_retour['nom_sci.'.$compo_nom] = $resultat[$compo_nom];
}
}
}
 
public function ajouterSignificationCode($champ, $valeur) {
if($this->termeOntologieEstEnCache($champ, $valeur)) {
$nom_code = $this->obtenirTermeOntologieParCache($champ, $valeur);
} else {
$code = $this->transformerChampEnCode($champ);
if (preg_match('/^([^_-]+)(?:_|-)([^_-]+)$/', $code, $match)) {
$code = $match[1].ucfirst($match[2]);
}
$requete = sprintf('SELECT * FROM %s WHERE id IN (SELECT id FROM %s WHERE code = "%s" AND classe_id = (SELECT id FROM %s WHERE code = "%s")) LIMIT 0, 100 -- %s:%s', Config::get('bdd_table_ontologies'), Config::get('bdd_table_ontologies'), $valeur, Config::get('bdd_table_ontologies'), $code, __FILE__, __LINE__);
$res = $this->getBdd()->recuperer($requete);
$nom_code = $valeur;
if (is_array($res)) {
$nom_code = $res['nom'];
}
$this->mettreEnCacheOntologie($champ, $valeur, $nom_code);
}
return $nom_code;
}
 
public function recupererNomSci($id) {
$nom = array();
if ($id != 0) {
if ($this->compo_nom == null) {
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html FROM '.$this->table.' WHERE num_nom = '.$id;
} else { //on ajoute à la requete sql, les champs de ns.structure
//print_r($this->compo_nom);
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html, '.implode(', ', $this->compo_nom)
.' FROM '.$this->table
.' WHERE num_nom = '.$id;
}
if ($this->parametres['ns.format'] == 'htm') {
$req = str_replace('nom_sci', 'nom_sci_html as nom_sci', $req);
}
$res = $this->getBdd()->recuperer($req . ' -- ' . __FILE__ . ':' . __LINE__);
if ($res) {
$nom['nom_sci'] = $res['nom_sci'];
$nom['nom_sci_html'] = $res['nom_sci_html'];
$nom['nom_sci_complet'] = $res['nom_sci'].' '.$this->ajouterCompositionNom($res);
$nom['nom_sci_complet_html'] = $res['nom_sci_html'].' '.$this->ajouterCompositionNom($res, 'htm');
$nom['service'] = ($res['num_nom_retenu'] == $id && $this->service == 'taxons') ? 'taxons' : 'noms';
}
}
return $nom;
}
 
/** Permet de retourner une chaine de caractère composée des parametres du nom (ns.structure : annnée, auteur,
* bibilio et addendum). A ajouter au nom scientifique */
public function ajouterCompositionNom($tab_res, $format = '') {
$format = ($format == '') ? $this->parametres['ns.format'] : $format;
 
$nom = '';
if (isset($this->compo_nom)) {
if ($format == 'htm') {
$format = array(
'au' => '<span class="auteur">%s</span>',
'an' => '[<span class="annee">%s</span>]',
'an_bib' => '[<span class="annee">%s</span>, <span class="biblio">%s</span>]',
'bib' => '[<span class="biblio">%s</span>]',
'ad' => '[<span class="adendum">%s</span>]',
'bib_excl' => '<span class="bib_excl">, %s</span>');
} else {
$format = array(
'au' => '%s',
'an' => '[%s]',
'an_bib' => '[%s, %s]',
'bib' => '[%s]',
'ad' => '[%s]',
'gen' => '%s',
'sp' => '%s',
'ssp' => '%s',
'fam' => '%s',
'au_ss' => '%s',
'bib_ss' => '%s',
'bib_excl' => ', %s'
);
}
$compo_nom = array();
 
foreach ($this->compo_nom as $key => $champ) {
if (isset($tab_res[$champ]) && !empty($tab_res[$champ])) {
$compo_nom[$key] = $tab_res[$champ];
}
}
$nom_complet = $this->formerNomComplet($compo_nom, $format);
$nom = implode(' ', $nom_complet);
}
return rtrim($nom, ' ');
}
 
 
public function formerNomComplet($compo_nom, $format) {
$nom_complet = array();
extract($compo_nom);
if (isset($au)) $nom_complet[] = sprintf($format['au'], $au);
if (isset($an)) {
if (isset($bib)) {
$nom_complet[] = sprintf($format['an_bib'], $an, $bib);
} else {
$nom_complet[] = sprintf($format['an'], $an);
}
} elseif (isset($bib)) {
$nom_complet[] = sprintf($format['bib'], $bib);
}
if (isset($bib_excl)) {
$nom_complet[] = sprintf($format['bib_excl'], $bib_excl);
}
if (isset($ad)) $nom_complet[] = sprintf($format['ad'], $ad);
if (isset($gen)) $nom_complet[] = sprintf($format['gen'], $gen);
if (isset($ssp)) $nom_complet[] = sprintf($format['ssp'], $ssp);
if (isset($sp)) $nom_complet[] = sprintf($format['sp'], $sp);
if (isset($fam)) $nom_complet[] = sprintf($format['fam'], $fam);
if (isset($au_ss)) $nom_complet[] = sprintf($format['au_ss'], $au_ss);
if (isset($bib_ss)) {
$bibl = $this->tronquerBiblio($bib_ss);
//simule un 'select distinct' sur les biblio tronquées
if (!isset($this->bib_traitees[$bibl])) {
$nom_complet[] = sprintf($format['bib_ss'],$bibl );
$this->bib_traitees[$bibl] = 1;
}
}
return $nom_complet;
}
 
public function tronquerBiblio($valeur){
$bib = '';
if(strpos($valeur,',') !== false) {
$bib = explode(',',$valeur);
}
if(strpos($bib[0],';') !== false) {
 
$bib[0] = strstr($bib[0],';');
$bib[0] = str_replace('; ','',$bib[0]);
}
return $bib[0];
}
 
 
 
public function correspondAUnCode($key) {
return (strrpos($key, '.code') !== false) || (in_array($key.'.code', $this->correspondance_champs));
}
 
public function correspondAUnId($key) {
return (strrpos($key, '.id') !== false) || (in_array($key.'.id', $this->correspondance_champs));
}
 
public function estUnPoint($key) {
if (strrpos($key, 'hybride.parent') !== false) {
$key = str_replace('hybride.parent', 'hybride_parent', $key);
}
return (strrpos($key, '.') !== false);
}
 
public function recupererMasquePrincipal() {
$masque = null;
$tab_masque = array(
'masque' => 'nom_sci',
'masque_sg' => 'nom_supra_generique',
'masque_gen' => 'genre',
'masque_sp' => 'epithete_sp',
'masque_ssp' => 'epithete_infra_sp',
'masque_au' => 'auteur',
'masque_an' => 'annee',
'masque_bib' => 'biblio_origine',
'masque_ad' => 'addendum',
'masque_rg' => 'rang');
$liste_masque = array();
 
if (isset($this->masque['num_nom'])) {
$liste_masque[] = $this->masque['num_nom'];
}
 
foreach ($tab_masque as $key => $filtre) {
if (isset($this->masque[$filtre])) {
if (!isset($masque) && !in_array($filtre, array('rang', 'annee'))) {
$masque = array($key, $filtre);
}
$liste_masque[] = $this->masque[$filtre];
}
}
$this->masque = $liste_masque;
return $masque;
}
 
private function mettreEnCacheOntologie($categorie, $valeur, $correspondance) {
if(!isset($this->ontologie[$categorie])) {
$this->ontologie[$categorie] = array();
}
if(!isset($this->ontologie[$categorie][$valeur])) {
$this->ontologie[$categorie][$valeur] = array();
}
$this->ontologie[$categorie][$valeur] = $correspondance;
}
 
private function termeOntologieEstEnCache($categorie, $valeur) {
return array_key_exists($categorie, $this->ontologie) && array_key_exists($valeur, $this->ontologie[$categorie]);
}
 
private function obtenirTermeOntologieParCache($categorie, $valeur) {
return $this->ontologie[$categorie][$valeur];
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtfx/CommunNomsTaxons2.php
New file
0,0 → 1,821
<?php
/*
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
* @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
*/
 
abstract class CommunNomsTaxons extends Commun {
 
/** Tableau de correspondance entre les noms des champs et les codes de l'ontologie.*/
private $relationsChampsCodesOntologie = null;
protected $table_retour; //Permet de stocker le tableau de résultat (non encodé en json)
protected $resultat_req; // Permet de stocker le résultat de la requete principale.
protected $table;// Nom de la table dans laquelle on récupèrera les données dans les requetes SQL
protected $total_resultat = null;
/** Stocke le service appelé correspondant. Est utilisé principalement lors de l'affichage du href d'un synonyme
(ex id=12, basionyme num 25 est un synonyme) dans le service taxon */
protected $service_href = null;
protected $erreursParametres = null;
protected $sans_nom_sci = array('gen','sp','ssp','fam','au_ss','bib_ss');
private $bib_traitees = array();
 
static $correspondance_champs = array();
static $champs_api = array();
static $compo_nom = null; //Stocke sous forme de tableau les composant du nom à ajouter au nom scientifique
static $cache_ontologies = array(); // cache des ontologies
//+------------------------------- PARAMÈTRES ---------------------------------------------------------------+
 
public function traiterParametres() {
$this->definirParametresParDefaut();
$this->verifierParametres();
if (isset($this->parametres) && count($this->parametres) > 0) {
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'ns.structure' :
self::remplirTableCompositionNom($val);
if (in_array($val,$this->sans_nom_sci)){
$this->requete_champ = implode(', ',self::$compo_nom);
}else {
$this->requete_champ .= ' ,'.implode(', ',self::$compo_nom);
}
break;
case 'navigation.depart' :
$this->limite_requete['depart'] = $val;
break;
case 'navigation.limite' :
$this->limite_requete['limite'] = $val;
break;
}
}
$this->traiterParametresSpecifiques();
}
}
 
protected function definirParametresParDefaut() {
if (empty($this->parametres['recherche'])) {
$this->parametres['recherche'] = 'stricte';
}
if (empty($this->parametres['ns.format'])) {
$this->parametres['ns.format'] = 'txt';
}
if (empty($this->parametres['retour.format'])) {
$this->parametres['retour.format'] = 'max';
}
if (empty($this->parametres['ns.structure']) &&
$this->parametres['retour.format'] != 'oss') {
$this->parametres['ns.structure'] = 'au,an,bib';
}
}
 
 
public function verifierParametres() {
//$this->verifierParametresAPI();
 
$this->verifierParametre('recherche', 'stricte|floue|etendue|complete');
$this->verifierParametre('ns.format', 'htm|txt');
$this->verifierParametre('retour.format', 'min|max|oss|perso');
$this->verifierParametreAvecValeurMultipe('ns.structure', 'an|au|bib|ad|gen|sp|ssp|fam|au_ss|bib_ss');
 
/*if (count($this->erreursParametres) > 0) {
$m = 'Erreur dans votre requête : '.implode('<br/>', $this->erreursParametres);
throw new Exception(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}*/
}
 
public function verifierParametresAPI() {
$parametresApi = Commun::recupererTableauConfig('parametresAPI');
while (!is_null($parametre = key($this->parametres))) {
if (!in_array($parametre, $parametresApi)) {
$this->erreursParametres[] = "Le paramètre '$parametre' n'est pas pris en compte par cette version de l'API.";
}
next($this->parametres);
}
}
 
public function verifierParametre($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeur = $this->parametres[$parametre];
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
 
public function verifierParametreAvecValeurMultipe($parametre, $valeursPermises) {
if (isset($this->parametres[$parametre]) && !empty($this->parametres[$parametre])) {
$valeursConcatenees = $this->parametres[$parametre];
$valeurs = explode(',', $valeursConcatenees);
foreach ($valeurs as $valeur) {
$this->verifierValeursPermises($parametre, $valeur, $valeursPermises);
}
}
}
 
private function verifierValeursPermises($parametre, $valeur, $valeursPermises) {
if (!in_array($valeur, explode('|', $valeursPermises))) {
$this->erreursParametres[] = "Le paramètre '$parametre' ne peut pas prendre la valeur '$valeur'. Valeurs permises : $valeursPermises";
}
}
 
public function ajouterFiltreMasque($nom_champ, $valeur) {
$orig_val = $valeur;
$valeur = explode(',',$valeur);
$conditions = array();
if ($nom_champ == 'annee' || $nom_champ == 'rang') {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ = ".$this->getBdd()->proteger($val);
}
} else {
if ($this->parametres['recherche'] == 'etendue') {
foreach ($valeur as $val) {
$val = self::preparerChainePourRechercheEtendue(self::remplacerCaractereHybrideEtChimere($val));
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
 
} elseif ($this->parametres['recherche'] == 'floue') {
foreach ($valeur as $val) {
$val = $this->getBdd()->proteger($val);
$conditions[] = "( SOUNDEX($nom_champ) = SOUNDEX($val))".
" OR ( SOUNDEX(REVERSE($nom_champ)) = SOUNDEX(REVERSE($val)))";
}
// utile pour la détermination à partir d'un nom retenu (concat(nom_sci,auteur)) lors
// d'un import depuis le CEL
} elseif ($this->parametres['recherche'] == 'concat' && $nom_champ == 'nom_sci') {
$conditions[] = "CONCAT(nom_sci, ' ', auteur) = " . $this->getBdd()->proteger($orig_val);
 
} else {
foreach ($valeur as $val) {
$conditions[] = "$nom_champ LIKE ".$this->getBdd()->proteger($val);
}
}
}
$this->requete_condition[]= '('.implode(' OR ', $conditions ).')';
$this->masque[$nom_champ] = $nom_champ.'='.implode(',',$valeur);
}
 
static function remplacerCaractereHybrideEtChimere($valeur) {
return str_replace(array('×', '%D7', '+', '%2B'),
array('x ','x ', '+', '+'),
$valeur);
}
 
static function preparerChainePourRechercheEtendue($valeur) {
return str_replace(' ', '% ', trim($valeur)) . '%';
}
 
//+-------------------------------Fonctions d'analyse des ressources-------------------------------------+
public function traiterRessources() {
if (isset($this->ressources) && count($this->ressources) > 0) {
if ($this->ressources[0] == 'relations') {
$this->traiterRessourceRelations();
} elseif ($this->estUnIdentifiant($this->ressources[0])) { //l'identifiant peut etre de type /#id ou /nt:#id
$this->traiterRessourcesIdentifiant(); // dans le service noms ou taxons
} elseif ($this->ressources[0] == 'stats') { //ressource = noms/stats
$this->traiterRessourcesStats();
} else {
$e = 'Erreur dans votre requete </br> Ressources disponibles : <br/>
<li> /'.$this->service.'/#id (id : L\'identifiant du nom rechercher)</li>
<li> /'.$this->service.'/nt:#id (id : Numero du taxon recherche)</li>
<li> /'.$this->service.'/stats </li>';
throw new Exception(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
}
 
public function traiterRessourcesStats() {
$this->format_reponse = $this->service.'/stats';
 
$e = "Erreur dans votre requête </br> Ressources disponibles : $this->service/stats/[annees|rangs|initiales]";
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
switch ($this->ressources[1]) {
case 'annees' :
$this->traiterRessourceStatsAnnees();
break;
case 'rangs' :
$this->traiterRessourceStatsRangs();
break;
case 'initiales' :
$this->traiterRessourceStatsInitiales();
break;
default :
throw new Exception(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
} else {
throw new Exception(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
/** Vérifie si la première valeur de la table de ressource est un identifiant :
* un numerique ou un numéro taxonomique sous la forme nt:xx */
static function estUnIdentifiant($uripart) {
return (is_numeric($uripart) || (strrpos($uripart,'nt:') !== false
&& is_numeric(str_replace('nt:','',$uripart))));
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonction d'analyse des parametres
 
/** Permet de remplir le tableau compo_nom. Il comprendra en fct du paramètre ns.structure les éléments à rajouter
* au nom_sci (annee, auteur, biblio ou addendum). */
static function remplirTableCompositionNom($valeur) {
$structure_nom = explode(',', $valeur);
 
foreach ($structure_nom as $structure) {
$structure = trim($structure);
$patterns = array('/^an$/', '/^au$/', '/^bib$/', '/^ad$/', '/^sp$/', '/^gen$/', '/^ssp$/','/^fam$/',
'/^au_ss$/','/^bib_ss$/');
$champs = array('annee', 'auteur', 'biblio_origine', 'nom_addendum', 'epithete_sp', 'genre',
'epithete_infra_sp','famille','auteur', 'biblio_origine');
 
// avec str_replace() 'sp' est inclu dans 'ssp', et la conversion pour 'ssp' est mauvaise
self::$compo_nom[$structure] = preg_replace($patterns, $champs, $structure);
}
}
 
public function mettreAuFormat() {
if ($this->parametres['ns.format'] == 'htm') {
if (strrpos($this->requete_champ, 'nom_sci_html as nom_sci') === false) {
$this->requete_champ = str_replace('nom_sci', 'nom_sci_html as nom_sci', $this->requete_champ);
}
}
}
 
//+------------------------------------------------------------------------------------------------------+
// Fonctions de formatage
public function formaterEnOss($resultat) {
$table_nom = array();
$oss = '';
foreach ($resultat as $tab) {
if (isset($tab['nom_sci']) ) {
if (!in_array($tab['nom_sci'], $table_nom)) {
$table_nom[] = $tab['nom_sci'];
$oss[] = $tab['nom_sci'].' '.self::ajouterCompositionNom($tab, $this->parametres['ns.format'], $this->bib_traitees);
}
}else {
$res = self::ajouterCompositionNom($tab, $this->parametres['ns.format'], $this->bib_traitees);
if($res) {
$oss[] = $res;
}
}
 
}
 
if (isset($this->masque)) $masque = implode('&', $this->masque);
else $masque = 'Pas de masque';
$table_retour_oss = array($masque, $oss);
return $table_retour_oss;
}
 
public function afficherEnteteResultat($url_service) {
$this->table_retour['depart'] = $this->limite_requete['depart'];
$this->table_retour['limite'] = $this->limite_requete['limite'];
$this->table_retour['total'] = $this->total_resultat;
$url = $this->formulerUrl($this->total_resultat, $url_service);
if (isset($url['precedent']) && $url['precedent'] != '') {
$this->table_retour['href.precedent'] = $url['precedent'];
}
if (isset($url['suivant']) && $url['suivant'] != '') {
$this->table_retour['href.suivant'] = $url['suivant'];
}
}
 
public function afficherNomHrefRetenu($tab, $num) {
$this->resultat_req = $tab;
$this->afficherDonnees('num_nom', $num);
if ($this->parametres['retour.format'] == 'min') { // sinon est affiché ds afficherDonnees(num_nom, $val) ci-dessus
$this->table_retour['nom_sci'] = $tab['nom_sci'];
$this->table_retour['nom_sci_complet'] = $tab['nom_sci'].' '.self::ajouterCompositionNom($tab, $this->parametres['ns.format'], $this->bib_traitees);
}
if ($tab['num_nom_retenu'] != '') {
$retenu = ($tab['num_nom_retenu'] == $num) ? 'true' : 'false';
} else {
$retenu = 'absent';
}
$this->table_retour['retenu'] = $retenu;
// Pourquoi ce unset ? JPM - 28-03-2013
unset($this->table_retour['id']);
}
 
 
//+------------------------------------------------------------------------------------------------------+
// Fonction de formatage pour les services /#id/
 
public function formaterId($resultat) {
self::$correspondance_champs = Commun::recupererTableauConfig('correspondance_champs');
foreach (self::$correspondance_champs as $key => $val) {
preg_match('/(hybride[.]parent_0[12](?:[.]notes)?|nom_sci[.][^.]+|[^.]+)(?:[.](id|code))?/', $val, $match);
self::$champs_api[$key] = $match[1];
}
 
$this->resultat_req = $resultat;
 
foreach ($resultat as $cle => $valeur) {
if ($valeur != '') {
$this->afficherDonnees($cle, $valeur);
}
}
if (isset($this->parametres['retour.champs']) && $this->format_reponse == 'noms/id') {
$retour = $this->table_retour;
$this->table_retour = array();
$champs = explode(',', $this->parametres['retour.champs']);
self::ajouterChampsPersonnalises($champs, $retour, $this->champs_table, $this->table_retour, $this->resultat_req);
}
unset($this->table_retour['href']);
return $this->table_retour;
}
 
public function formaterIdChamp($resultat) {
self::$correspondance_champs = Commun::recupererTableauConfig('correspondance_champs');
foreach (self::$correspondance_champs as $key => $val) {
preg_match('/(hybride[.]parent_0[12](?:[.]notes)?|nom_sci[.][^.]+|[^.]+)(?:[.](id|code))?/', $val, $match);
self::$champs_api[$key] = $match[1];
}
 
$reponse_id = $this->formaterId($resultat);
$this->table_retour = array();
$champs = explode(' ', $this->ressources[1]);
self::ajouterChampsPersonnalises($champs, $reponse_id, $this->champs_table, $this->table_retour, $this->resultat_req);
return $this->table_retour;
}
 
static function ajouterChampsPersonnalises($champs, $reponse_id, $champs_table, &$retour, $resultat_req) {
$champs_a_libeller = array('nom_retenu', 'rang', 'basionyme', 'hybride', 'hybride.parent_01',
'hybride.parent_02', 'presence', 'tax_sup', 'statut_origine', 'statut_culture', 'statut_introduction');
if (! is_null($champs) && is_array($champs) && count($champs) > 0) {
foreach ($champs as $champ) {
if (! self::verifierValiditeChamp($champ, $champs_table)) continue;
 
if (strrpos($champ, '.*') !== false) {
self::afficherPointEtoile($champ, $reponse_id, $retour, $resultat_req);
} elseif (in_array($champ, $champs_a_libeller)) {
$retour[$champ.'.libelle'] =
(isset($reponse_id[$champ.'.libelle'])) ? $reponse_id[$champ.'.libelle'] : null;
} else {
$champ_bdd = self::trouverChampBddCorrespondant($champ);
$retour[$champ_bdd] = isset($reponse_id[$champ_bdd]) ? $reponse_id[$champ_bdd] : null;
}
}
}
}
 
static function afficherPointEtoile($champ, $reponse, &$retour, $resultat_req) {
preg_match('/^([^.]+\.)\*$/', $champ, $match);
if ($match[1] == 'nom_sci') {
self::afficherNomSciPointEpithete($resultat_req, $retour);
} else {
foreach ($reponse as $chp => $valeur) {
if (strrpos($chp, $match[1]) !== false) {
if ($valeur != '') {
$retour[$chp] = $valeur;
} else {
$retour[$chp] = null;
}
}
}
}
}
 
static function verifierValiditeChamp($champ, $champs_table) {
if (! preg_match('/^(?:([^.]+\.parent_0[12]|[^.]+))(?:\.(.+))?$/', $champ, $match)) {
return true;
}
// decomposerNomChamp()
$radical = $match[1];
$suffixe = isset($match[2]) ? $match[2] : "";
 
$champs_complementaire = array('nom_retenu_complet', 'basionyme_complet');
// on verifie si le nom du champ existe bien
$champs_complementaire2 = array_diff($champs_table, array_keys(self::$champs_api)); // XXX
if (! self::estChampApi($radical) && ! in_array($radical_champ, $champs_complementaire2)) {
if (!in_array($radical, $champs_complementaire)) {
throw new Exception(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, 'Le champ "'.$radical.'" n\'existe pas dans la base. <br/><br/>');
return FALSE;
}
} elseif (self::estUnPoint($champ)) {
return self::verifierValiditeSuffixe($suffixe, $radical);
}
 
return TRUE;
}
 
static function estChampApi($radical_champ) {
$champ_api_ok = false;
if (in_array($radical_champ, self::$champs_api) || in_array($radical_champ, self::$correspondance_champs)) {
$champ_api_ok = true;
}
return $champ_api_ok;
}
 
static function verifierValiditeSuffixe($suffixe, $radical_champ) {
$validite_ressource = true;
if (self::correspondAUnId($radical_champ) || $radical_champ == 'id') {
self::verificationSuffixesIdentifiant($suffixe, $radical_champ, $validite_ressource);
} elseif (self::correspondAUnCode($radical_champ)) {
if (!in_array($suffixe, array('*', 'code', 'href', 'details'))) {
throw new Exception(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'.<br/> Les suffixes possibles sont les suivants : <li> .* </li><li> .code </li><li> .href </li><li> .details </li>');
}
} elseif ($radical_champ == 'nom_sci') {
if ($suffixe != '*') {
$validite_ressource = false;
$m = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/>
Les suffixes possibles sont les suivants : <li> * </li>';
throw new Exception( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
} else {
$validite_ressource = false;
$m = 'Erreur : Le paramètre "'.$radical_champ.'" ne peut pas présenter de suffixe. <br/><br/>';
throw new Exception( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $m);
}
return $validite_ressource;
}
 
 
static function verificationSuffixesIdentifiant(&$suffixe, &$radical_champ, &$validite_ressource) {
if ((strrpos($radical_champ, 'parent') !== false && !in_array($suffixe, array('*', 'id', 'href', 'details', 'notes')))
|| !in_array($suffixe, array('*', 'id', 'href', 'details')) && strrpos($radical_champ, 'parent') === false) {
$validite_ressource = false;
$e = 'Erreur : Le suffixe demandé n\'existe pas pour le champ "'.$radical_champ.'".<br/> Les suffixes '
.'possibles sont les suivants : <li> .* </li><li> .id </li><li> .href </li><li> .details </li>'
.'<li> .notes (seulement pour les hybride.parent)';
throw new Exception( RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
 
 
//------------------------------fonction de formatage pour les services /stats/-----------------------------------------
public function formaterStatsInitiales($resultat) {
$rang = null;
$table_rang = array();
foreach ($resultat as $tuple) {
if ($tuple['rang'] != 0) {
$this->memoriserRang($table_rang, $tuple, $rang);
if ($tuple['lettre'] == 'x ') {
self::ajouterHybrideChimere('hybride', $this->retour[$rang], $tuple);
} elseif ($tuple['lettre'] == '+ ') {
self::ajouterHybrideChimere('chimere', $this->retour[$rang], $tuple);
} else {
$l = substr($tuple['lettre'], 0, 1);
if (isset($this->table_retour[$rang][$l])) {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] += floatval($tuple['nb']);
} else {
$this->table_retour[$rang][substr($tuple['lettre'], 0, 1)] = floatval($tuple['nb']);
}
}
}
}
return $this->table_retour;
}
 
public function memoriserRang(&$table_rang, $tuple, &$rang) {
if (is_array($table_rang)) {
if (!in_array($tuple['rang'], $table_rang)) {
$rang = $tuple['rang'];
$table_rang[] = $rang;
if ($this->parametres['retour.format'] == 'max') {
$rang = self::ajouterSignificationCode('rang', $rang, $this->getBdd());
}
}
}
}
 
static function ajouterHybrideChimere($groupe, &$tab, &$tuple) {
if (isset($tab[str_replace('hybride', 'hyb', $groupe)])) {
$tab[$groupe] += floatval($tuple['nb']);
} else {
$tab[$groupe] = floatval($tuple['nb']);
}
}
 
//-----------------------------Fonctions d'affichage utiliser dans les fonctions de formatage---------------------------
 
public function afficherDonnees($champApi, $valeur) {
$champBdd = self::trouverChampBddCorrespondant($champApi);
 
if ($this->parametres['retour.format'] == 'min') {
if ($champApi == 'nom_sci') {
$valeur = $valeur.' '.self::ajouterCompositionNom($this->resultat_req, $this->parametres['ns.format'], $this->bib_traitees);
}
if ($champApi == 'nom_sci_html') {
$valeur = $valeur.' '.self::ajouterCompositionNom($this->resultat_req, 'htm', $this->bib_traitees);
}
$this->table_retour[$champBdd] = $valeur;
// on essaye de permettre l'obtention du nom_sci_complet, y compris en retour.format == 'min',
// tout en évitant les appels aux ontologies
/*if ($this->correspondAUnId($champBdd) || $champBdd == 'id' && $valeur != '0') {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $champBdd, $match);
if(strpos($this->parametres['retour.format'], $match[1]) !== false) $this->afficherSignification($match[1], $valeur);
}*/
} else {
$this->afficherToutesLesInfos($champBdd, $valeur);
}
}
 
static function trouverChampBddCorrespondant($champApi) {
if (array_key_exists($champApi, self::$champs_api)) {
$champBdd = self::$correspondance_champs[$champApi];
} else {
$champBdd = $champApi;
}
return $champBdd;
}
 
public function afficherToutesLesInfos($nom_champ_api, $valeur) {
if ($this->presentePlusieursId($nom_champ_api, $valeur)) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'details', $valeur, $this->table_retour);
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif (strrpos($nom_champ_api, 'parent') !== false && strrpos($nom_champ_api, 'notes') !== false) {
$this->table_retour[$nom_champ_api] = $valeur;
 
} elseif ((self::correspondAUnId($nom_champ_api) || $nom_champ_api == 'id' && $valeur != '0')) {
preg_match('/^([^.]+\.parent_0[12]|[^.]+)(?:\.id)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'id,href', $valeur, $this->table_retour);
self::afficherSignification($match[1], $valeur, $obj->resultat_req, $this->table_retour, $this->getBdd(), $this);
 
} elseif (self::correspondAUnCode($nom_champ_api)) {
preg_match('/^([^.]+)(?:\.code)?$/', $nom_champ_api, $match);
$this->afficherInfosPrecises($match[1], 'code,href', $valeur, $this->table_retour);
self::afficherSignification($match[1], $valeur, $obj->resultat_req, $this->table_retour, $this->getBdd(), $this);
 
} elseif ($nom_champ_api == 'nom_sci_html') {
$this->table_retour['nom_sci_html'] = $valeur;
$this->table_retour['nom_sci_html_complet'] = $valeur.' '.self::ajouterCompositionNom($this->resultat_req, 'htm', $this->bib_traitees);
} elseif ($nom_champ_api != 'nom_sci') {
$this->table_retour[$nom_champ_api] = $valeur;
}
}
 
public function presentePlusieursId($ressource, $valeur = null) {
if ($valeur) {
$presente = strrpos($ressource, 'proparte') !== false && strrpos($valeur, ',') !== false;
} else { //pour la vérification du champ, on ignore alors la valeur de la ressource
$presente = strrpos($ressource, 'proparte') !== false;
}
return $presente;
}
 
public function afficherInfosPrecises($champ, $suffixe, $valeur, &$retour) {
$suffixes = explode(',', $suffixe);
//on initialise au service appelé. Sera potentiellement modifié dans la fonction afficherSignification()
$this->service_href = $this->service;
foreach ($suffixes as $suffixe) {
switch ($suffixe) {
case 'id' :
$retour[str_replace('id.id', 'id', $champ.'.id')] = $valeur;
break;
case 'details' :
$tab_id = explode(',', $valeur);
$tab_res = $retour;
$retour = array();
foreach ($tab_id as $id) {
$this->afficherInfosPrecises($champ, 'id,signification,href', $id, $retour);
$tab_res[$champ.'.details'][] = $retour;
$retour = array();
}
$retour = $tab_res;
break;
case 'href' :
$retour[str_replace('id.href', 'href', $champ.'.href')] = self::creerUrl($champ, $valeur, $this->version_projet);
break;
case 'code' :
$retour[$champ.'.code'] = "bdnt." . self::transformerChampEnCode($champ) . ":$valeur";
break;
case 'notes' :
$retour[$champ.'.notes'] = $this->resultat_req[str_replace('.', '_', $champ).'_notes'];
break;
default : break;
}
}
}
 
static function transformerChampEnCode($champ) {
static $tab;
$tab = Outils::recupererTableauConfig('ChampsCodesOntologie');
if (!array_key_exists($champ, $tab)) return $champ;
return $tab[$champ];
}
 
static function creerUrl($champ, $valeur, $version_projet) {
if (self::correspondAUnId($champ) || $champ == 'id') {
$service = $this->service_href;
$url = self::s_ajouterHref($service, $valeur, $version_projet);
} else {
$code = self::transformerChampEnCode($champ);
$url = self::ajouterHrefAutreProjet('ontologies', "$code:", $valeur, 'bdnt');
}
return $url;
}
 
static function afficherSignification($champ, $valeur, $resreq, &$retour, $db, $obj) {
$fmt = $obj->parametres['ns.format'];
 
if ($champ == 'id' && isset($resreq['nom_sci']) && $resreq['num_nom'] == $valeur) {
//si le nom_sci du num_nom que l'on veut afficher est déjà dans la table de résultat :
$retour['nom_sci'] = $resreq['nom_sci'];
$retour['nom_sci_complet'] = $resreq['nom_sci'] . (($suff = self::ajouterCompositionNom($resreq, $fmt, $obj->bib_traitees)) ? ' ' . $suff : '');
return ;
}
 
if (self::correspondAUnCode($champ)) {
$retour[$champ.'.libelle'] = self::ajouterSignificationCode($champ, $valeur, $db);
return ;
}
 
if (self::correspondAUnId($champ) || $champ == 'id') {
// $nom = $obj->recupererNomSci($valeur);
$id = $valeur;
 
$nom = array();
if ($id != 0) {
if (self::$compo_nom == null) {
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html FROM '.$obj->table.' WHERE num_nom = '.$id;
} else { //on ajoute à la requete sql, les champs de ns.structure
//print_r(self::$compo_nom);
$req = 'SELECT nom_sci, num_nom_retenu, nom_sci_html, '.implode(', ', self::$compo_nom)
.' FROM '.$obj->table
.' WHERE num_nom = '.$id;
}
if ($fmt == 'htm') {
$req = str_replace('nom_sci', 'nom_sci_html as nom_sci', $req);
}
$res = $db->recuperer($req . ' -- ' . __FILE__ . ':' . __LINE__);
if ($res) {
$nom['nom_sci'] = $res['nom_sci'];
$nom['nom_sci_html'] = $res['nom_sci_html'];
$nom['nom_sci_complet'] = $res['nom_sci'].' '.self::ajouterCompositionNom($res, $fmt, $obj->bib_traitees);
$nom['nom_sci_complet_html'] = $res['nom_sci_html'].' '.self::ajouterCompositionNom($res, 'htm', $obj->bib_traitees);
$nom['service'] = ($res['num_nom_retenu'] == $id && $obj->service == 'taxons') ? 'taxons' : 'noms';
}
}
 
 
if ($nom != array()) {
$retour[$champ.'.libelle'] = $nom['nom_sci'];
$retour[$champ.'_html'] = $nom['nom_sci_html'];
$retour[$champ.'_complet'] = $nom['nom_sci_complet'];
$retour[$champ.'_html_complet'] = $nom['nom_sci_complet_html'];
$obj->service_href = $nom['service'];
}
}
}
 
/** Permet d'afficher les élements nomenclatural du nom_sci lors de l'appel dans le service noms/id/champ du champ^nom_sci.*/
static function afficherNomSciPointEpithete($resultat, &$retour) {
$tab_nom_sci = array('nom_supra_generique', 'genre', 'epithete_infra_generique', 'epithete_sp',
'type_epithete', 'epithete_infra_sp', 'cultivar_groupe', 'cultivar', 'nom_commercial');
foreach ($tab_nom_sci as $compo_nom) {
if (isset($resultat[$compo_nom]) && !empty($resultat[$compo_nom])) {
$table_retour['nom_sci.'.$compo_nom] = $resultat[$compo_nom];
}
}
}
 
static function ajouterSignificationCode($champ, $valeur, $db) {
// ontologie/cache
if(array_key_exists($champ, self::$cache_ontologies) && array_key_exists($valeur, self::$cache_ontologies[$champ])) {
$nom_code = self::$cache_ontologies[$champ][$valeur];
} else {
$code = self::transformerChampEnCode($champ);
if (preg_match('/^([^_-]+)(?:_|-)([^_-]+)$/', $code, $match)) {
$code = $match[1].ucfirst($match[2]);
}
$requete = sprintf('SELECT * FROM %1$s WHERE id IN (SELECT id FROM %1$s WHERE code = "%2$s" AND classe_id = (SELECT id FROM %1$s WHERE code = "%3$s")) LIMIT 0, 100 -- %4$s:%5$s',
Config::get('bdd_table_ontologies'), $valeur, $code, __FILE__, __LINE__);
$res = $db->recuperer($requete);
$nom_code = $valeur;
if (is_array($res)) {
$nom_code = $res['nom'];
}
// cache
self::$cache_ontologies[$champ][$valeur] = $correspondance;
}
return $nom_code;
}
 
/** Permet de retourner une chaine de caractère composée des parametres du nom (ns.structure : annnée, auteur,
* bibilio et addendum). A ajouter au nom scientifique */
static function ajouterCompositionNom($tab_res, $format, &$bib_traitees) {
if(!self::$compo_nom) return '';
 
if ($format == 'htm') {
$format = array(
'au' => '<span class="auteur">%s</span>',
'an' => '[<span class="annee">%s</span>]',
'an_bib' => '[<span class="annee">%s</span>, <span class="biblio">%s</span>]',
'bib' => '[<span class="biblio">%s</span>]',
'ad' => '[<span class="adendum">%s</span>]');
} else {
$format = array(
'au' => '%s',
'an' => '[%s]',
'an_bib' => '[%s, %s]',
'bib' => '[%s]',
'ad' => '[%s]',
'gen' => '%s',
'sp' => '%s',
'ssp' => '%s',
'fam' => '%s',
'au_ss' => '%s',
'bib_ss' => '%s');
}
$compo_nom_arr = array();
foreach (self::$compo_nom as $key => $champ) {
if (isset($tab_res[$champ]) && !empty($tab_res[$champ])) {
$compo_nom_arr[$key] = $tab_res[$champ];
}
}
return rtrim(implode(' ', self::formerNomComplet($compo_nom_arr, $format, $bib_traitees)), ' ');
}
 
 
static function formerNomComplet($compo_nom_arr, $format, &$bib_traitees) {
$nom_complet = array();
extract($compo_nom_arr);
if (isset($au)) $nom_complet[] = sprintf($format['au'], $au);
if (isset($an)) {
if (isset($bib)) {
$nom_complet[] = sprintf($format['an_bib'], $an, $bib);
} else {
$nom_complet[] = sprintf($format['an'], $an);
}
} elseif (isset($bib)) {
$nom_complet[] = sprintf($format['bib'], $bib);
}
if (isset($ad)) $nom_complet[] = sprintf($format['ad'], $ad);
if (isset($gen)) $nom_complet[] = sprintf($format['gen'], $gen);
if (isset($ssp)) $nom_complet[] = sprintf($format['ssp'], $ssp);
if (isset($sp)) $nom_complet[] = sprintf($format['sp'], $sp);
if (isset($fam)) $nom_complet[] = sprintf($format['fam'], $fam);
if (isset($au_ss)) $nom_complet[] = sprintf($format['au_ss'], $au_ss);
if (isset($bib_ss)) {
$bibl = self::tronquerBiblio($bib_ss);
//simule un 'select distinct' sur les biblio tronquées
if (!isset($bib_traitees[$bibl])) {
$nom_complet[] = sprintf($format['bib_ss'],$bibl );
$bib_traitees[$bibl] = 1;
}
}
return $nom_complet;
}
 
static function tronquerBiblio($valeur){
$bib = '';
if(strpos($valeur,',') !== false) {
$bib = explode(',',$valeur);
}
if(strpos($bib[0],';') !== false) {
$bib[0] = strstr($bib[0],';');
$bib[0] = str_replace('; ','',$bib[0]);
}
return $bib[0];
}
 
 
 
static function correspondAUnCode($key) {
return strrpos($key, '.code') !== false || in_array($key.'.code', self::$correspondance_champs);
}
static function correspondAUnId($key) {
return strrpos($key, '.id') !== false || in_array($key.'.id', self::$correspondance_champs);
}
 
static function estUnPoint($key) {
if (strrpos($key, 'hybride.parent') !== false) {
$key = str_replace('hybride.parent', 'hybride_parent', $key);
}
return (strrpos($key, '.') !== false);
}
 
public function recupererMasquePrincipal() {
$masque = null;
$tab_masque = array(
'masque' => 'nom_sci',
'masque_sg' => 'nom_supra_generique',
'masque_gen' => 'genre',
'masque_sp' => 'epithete_sp',
'masque_ssp' => 'epithete_infra_sp',
'masque_au' => 'auteur',
'masque_an' => 'annee',
'masque_bib' => 'biblio_origine',
'masque_ad' => 'addendum',
'masque_rg' => 'rang');
$liste_masque = array();
 
if (isset($this->masque['num_nom'])) {
$liste_masque[] = $this->masque['num_nom'];
}
 
foreach ($tab_masque as $key => $filtre) {
if (isset($this->masque[$filtre])) {
if (!isset($masque) && !in_array($filtre, array('rang', 'annee'))) {
$masque = array($key, $filtre);
}
$liste_masque[] = $this->masque[$filtre];
}
}
$this->masque = $liste_masque;
return $masque;
}
}
/tags/v5.12-baouque/services/modules/0.1/bdtfx/Noms.php
New file
0,0 → 1,733
<?php
// declare(encoding='UTF-8');
/**
* Classe permettant de fournir des informations sur les noms scientifiques.
* Si l'url finit par /noms on retourne une liste de noms latin et leurs identifiants (seulement les 100 premeiers noms par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /noms?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, masque.gen (nom de genre), masque.sp (épithète d'espèce), masque.ssp (épithète infra-spécifique),
* masque.au (auteur du nom), masque.an (année de publication du nom), masque.bib (réf biblio de la publi d'origine du nom), masque.ad (nomen addendum),
* masque.nn (identifiant du nom), recherche, rang, distinct, retour.format, nl.format, nl.structure, navigation.depart et navigation.limite.
* Les différentes requetes :
* - noms | noms/relations/#projet/#id_projet | noms/#id | noms/#id/#champ+#champ
* - noms/#id/relations | noms/#id/relations/synonymie | noms/#id/relations/homonymie | noms/#id/relations/flores
* - noms/stats/rangs | noms/stats/annees | noms/stats/initiales
*
* @package bdtfx
* @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 $Id$
* @copyright 1999-2011 Tela Botanica (accueil@tela-botanica.org)
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Noms
*/
 
class Noms extends CommunNomsTaxons {
 
protected $format_reponse = 'noms'; // Permet de stocker la requete formulée
protected $service = 'noms';
protected $serviceNom = 'noms';
protected $requete_champ = 'num_nom, nom_sci, num_nom_retenu';
protected $requete_condition = null;
protected $requete_group_by = '';
/** Permet de stocker les limite de la requete SQL (par défaut seul les 100 premiers résultats seront retournés).*/
protected $limite_requete = array('depart' => 0, 'limite' => 100);
protected $distinct = null; // Valeur du paramètre de requete distinct (=0|1)
 
public function consulter($ressources, $parametres) {
return parent::consulter($ressources, $parametres);
}
 
//+----------------FONCTION D'ANALYSE DES PARAMETRES---------------------------------------------------------+
 
public function traiterParametresSpecifiques() {
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'masque' :
$champ = isset($this->parametres['recherche']) && ($this->parametres['recherche'] == 'etendue') ?
'CONCAT(nom_sci," ",auteur)' : 'nom_sci';
$this->ajouterFiltreMasque($champ, $val);
break;
case 'masque.sg' :
$this->ajouterFiltreMasque('nom_supra_generique', $val);
break;
case 'masque.gen' :
$this->ajouterFiltreMasque('genre', $val);
break;
case 'masque.sp' :
$this->ajouterFiltreMasque('epithete_sp', $val);
break;
case 'masque.ssp' :
$this->ajouterFiltreMasque('epithete_infra_sp',$val);
break;
case 'masque.au' :
$this->ajouterFiltreMasque('auteur', $val);
break;
case 'masque.an' :
$this->ajouterFiltreMasque('annee', $val);
break;
case 'masque.bib' :
$this->ajouterFiltreMasque('biblio_origine',$val);
break;
case 'masque.ad' :
$this->ajouterFiltreMasque('nom_addendum', $val);
break;
case 'masque.nn' :
$this->requete_condition []= 'num_nom IN ('.$val.')';
$this->masque['num_nom'] = "num_nom=$val";
break;
case 'masque.nt' :
$this->requete_condition []= 'num_taxonomique IN ('.$val.')';
$this->masque['num_tax'] = "num_taxonomique=$val";
break;
case 'masque.rg' :
$this->ajouterFiltreMasque('rang', $val);
break;
case 'retour.champs' :
$this->verifierParamChamps($param, $val);
break;
case 'distinct' :
$this->ajouterNomDistinct($val);
break;
case 'masque.fam' :
$this->ajouterFiltreMasque('famille', $val);
break;
case 'masque.prga' :
$this->ajouterFiltreMasque('presence_ga', $val);
break;
case 'masque.prco' :
$this->ajouterFiltreMasque('presence_co', $val);
break;
case 'masque.sto' :
$this->ajouterFiltreMasque('statut_origine', $val);
break;
case 'masque.sti' :
$this->ajouterFiltreMasque('statut_introduction', $val);
break;
case 'masque.stc' :
$this->ajouterFiltreMasque('statut_culture', $val);
break;
case 'masque.and' :
$this->requete_condition []= " annee >= ".$this->getBdd()->proteger($val);
break;
case 'masque.anf' :
$this->requete_condition []= " annee <= ".$this->getBdd()->proteger($val);
break;
}
 
}
}
 
public function verifierParamChamps($param, $val) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$champs_demandes = explode(',', $val);
$champs_verifies = array();
$champs_api = array_flip($this->champs_api);
$champs_supp = array('nom_retenu_complet'=>'num_nom_retenu', 'num_basionyme_complet'=>'num_basionyme');
$champs_api = array_merge($champs_api, $champs_supp);
foreach ($champs_demandes as $champ) {
if (array_key_exists($champ, $champs_api)) {
$champs_verifies[] = $champs_api[$champ];
}
}
if (count($champs_verifies) > 0) {
$this->requete_champ .= ', '.implode(',', $champs_verifies);
}
}
 
/** Permet de rajouter à la requete sql le parametre distinct. N'est utilisé qu'avec le format oss */
public function ajouterNomDistinct($distinct) {
if (isset($distinct)) {
if ($distinct == 1 && $this->parametres['retour.format'] == 'oss') {
$this->distinct = ' distinct ';
} elseif ($distinct == 1 && $this->parametres['retour.format'] != 'oss') {
$e = 'Erreur dans votre requête </br> L\'utilisation du paramètre distinct ne se fait que sous
le format oss';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
}
 
//-----------------FONCTION D'ANALYSE DES RESSOURCES--------------------------------------------------------------------
 
public function traiterRessourcesIdentifiant() {
//on initialise la condition de la requete sql et le format de réponse
$this->requete_condition = array(); //on vide la table dans le cas de plusieurs version
$this->requete_condition[] = 'num_nom = '.$this->getBdd()->proteger($this->ressources[0]);
$this->format_reponse = $this->service.'/id';
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
if ($this->ressources[1] == 'relations') {
$this->traiterRessourceIdRelations();
} else {
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> noms/#id/relations </li> <li> noms/#id/#champ+#champ </li>
<li> noms/#id/relations/synonymie </li> <li> noms/#id/relations/flores </li>
<li> noms/#id/relations/homonymie </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else { // requete de type noms/#id : rajout du nom_sci pour récupérer le format html par la fct mettreAuFormat()
$this->requete_champ = ' *, nom_sci ';
}
}
 
public function traiterRessourceRelations() {
$this->format_reponse .= '/relations';
$projet = $this->ressources[1];
$num_nom = $this->ressources[2];
if (strrpos($num_nom, 'nn.coste') !== false) {
list($p, $nn) = explode('=', $num_nom);
$num_nom = $nn;
}
$champ = "flore_$projet"."_num";
if (isset($this->ressources[3])) {
$type = $this->ressources[3];
if (!in_array($type, array('homonymie', 'synonymie', 'flores'))) {
$e = "Les types disponibles pour les noms sont homonymie, synonymie et flores";
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
}
$this->requete_champ = ' num_nom ';
$this->requete_condition = array();
$this->requete_condition[] = "$champ = ".$this->getBdd()->proteger($num_nom);
}
 
public function traiterRessourceIdRelations() {
$this->format_reponse .= '/relations';
if (isset($this->ressources[2]) && !empty($this->ressources[2])) {
// requete de type noms/#id/relations/#relation
switch ($this->ressources[2]) {
case 'synonymie' :
$this->traiterRessourceIdSynonymie();
break;
case 'flores' :
$this->traiterRessourceIdFlores();
break;
case 'homonymie' :
$this->traiterRessourceIdHomonymie();
break;
default :
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> noms/#id/relations </li> <li> noms/#id/relations/synonymie </li>
<li> noms/#id/relations/flores </li> <li> noms/#id/relations/homonymie </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
}
}
 
public function traiterRessourceIdSynonymie() {
// SELECT num_nom, nom_sci, num_nom_retenu, num_basionyme FROM bdtfx_v2_00 WHERE num_nom = X LIMIT 0,100;
$this->format_reponse .= '/synonymie';
if (strrpos($this->requete_champ, ', num_basionyme') === false) {
$this->requete_champ .= ', num_basionyme ';
}
if (strrpos($this->requete_champ, ', num_type') === false) {
$this->requete_champ .= ', num_type ';
}
$this->requete_champ .= ', source_biblio ';
$this->requete_condition[0] = 'num_nom_retenu = '.
'(SELECT num_nom_retenu FROM '.$this->table.' WHERE '.$this->requete_condition[0].')';
}
 
public function traiterRessourceIdHomonymie() {
// SELECT num_nom, nom_sci, num_nom_retenu FROM bdtfx_v2_00 WHERE nom_sci = (SELECT nom_sci FROM bdtfx_v2_00 WHERE num_nom = X);
$this->format_reponse .= '/homonymie';
$this->requete_condition[0] = 'nom_sci = (SELECT nom_sci FROM '.$this->table
.' WHERE '.$this->requete_condition[0].')';
}
 
public function traiterRessourceIdFlores() {
$champ_flores = '';
foreach ($this->champs_table as $champ) {
if (preg_match('/^flore_.*$/', $champ)) {
$champ_flores .= ', '.$champ;
}
}
$this->format_reponse .= '/flores';
$this->requete_champ = 'num_nom,num_nom_retenu,nom_sci,flores'.$champ_flores;
$this->requete_condition = null;
$this->requete_condition[] = "num_nom_retenu = ".$this->ressources[0]." OR num_nom = ".$this->ressources[0];
}
 
public function traiterRessourceStatsRangs() {
// SELECT count(*) as nombre, rang FROM bdtfx_v2_00 [WHERE rang = 290] GROUP BY rang ORDER BY rang;
$this->format_reponse .= '/rangs';
$this->requete_champ = 'count(*) as nombre, rang ';
$this->requete_group_by = ' GROUP BY rang ORDER BY rang ';
}
 
public function traiterRessourceStatsAnnees() {
// SELECT count(*) as nombre, annee FROM bdtfx_v2_00 GROUP BY annee ORDER BY annee;
$this->format_reponse .= '/annees';
$this->requete_champ = 'count(*) as nombre, annee ';
$this->requete_condition = null;
$this->requete_group_by = ' GROUP BY annee ORDER BY annee ';
}
 
public function traiterRessourceStatsInitiales() {
// SELECT count(left( nom_sci, 2 )) as nb, rang, left(nom_sci, 2) as lettre GROUP BY rang, left(nom_sci, 2);
$this->format_reponse .= '/initiales';
$this->requete_champ = 'count(left( nom_sci, 2 )) as nb, rang, left(nom_sci, 2) as lettre ';
$this->requete_group_by = ' GROUP BY rang, left(nom_sci, 2)';
}
 
 
 
//-----------------------------FONCTIONS DASSEMBLAGE DE LA REQUETE-----------------------------------------------------
 
public function assemblerLaRequete() {
if ( strrpos($this->format_reponse, 'noms/stats/') === false ) {
$this->mettreAuFormat(); //Ds CommunNomsTaxons.php
}
$requete = 'SELECT '.$this->retournerChamps().' '.
"FROM {$this->table} ".
$this->retournerRequeteCondition().' '.
$this->requete_group_by.' '.
$this->retournerOrderBy().' '.
$this->formerRequeteLimite() .
' -- ' . __FILE__ . ':' . __LINE__ ;
return $requete;
}
 
public function retournerChamps() {
$sql = '';
if ($this->distinct) {
$sql .= $this->distinct.' ';
}
if ($this->requete_champ) {
$sql .= $this->requete_champ.' ';
}
 
// Champs "virtuels" pour tier sur l'ensemble des résultats
if (isset($this->parametres['retour.tri'])) {
list($champ, $ordre) = $this->decouperParametreRetourTri();
if ($champ == 'retenu') {
$sql .= ", IF(num_nom = num_nom_retenu, '0', '1') AS nom_retenu_tri ";
}
}
 
return $sql;
}
 
public function decouperParametreRetourTri() {
$tri = array('', '');
if (isset($this->parametres['retour.tri'])) {
if (preg_match('/^(retenu)(?:,(ASC|DESC)|)$/', $this->parametres['retour.tri'], $match))
$tri[0] = $match[1];
$tri[1] = isset($match[2]) ? $match[2] : '';
}
return $tri;
}
 
public function retournerRequeteCondition() {
$condition = '';
if ($this->requete_condition) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
 
public function retournerOrderBy() {
$orderBy = array();
 
// Tri sur l'ensemble des résultats
if (isset($this->parametres['retour.tri'])) {
list($champ, $ordre) = $this->decouperParametreRetourTri();
if ($champ == 'retenu') {
$orderBy[] = "nom_retenu_tri $ordre";
}
}
// Tri par défaut
if ($this->format_reponse == 'noms') {
$orderBy[] = 'nom_sci ASC';
}
 
$sql = '';
if (count($orderBy) > 0) {
$sql = 'ORDER BY '.implode(', ', $orderBy).' ';
}
return $sql;
}
 
public function formerRequeteLimite() {
if ($this->format_reponse != 'noms' && $this->format_reponse != 'noms/id/relations/synonymie'
&& $this->format_reponse != 'noms/id/relations/homonymie') {
$this->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
$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;
}
 
/** Recupere le nombre total de résultat d'une requete lancée. */
public function recupererTotalResultat() {
$total = null;
$requete = 'SELECT count(*) as nombre FROM '.$this->table.$this->retournerRequeteCondition().$this->requete_group_by;
$res = $this->getBdd()->recuperer($requete);
if ($res) {
$total = $res['nombre'];
} else {
$e = 'Fct recupererTotalResultat() : <br/>Données introuvables dans la base';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
}
return $total;
}
 
 
//-------------------FONCTIONS POUR LE FORMATAGE EN JSON----------------------------------------------------------------
 
public function retournerResultatFormate($resultat) {
 
switch ($this->format_reponse) {
case 'noms/relations' :
$reponse = $this->formaterRelations($resultat[0]);
break;
case 'noms/id' : //ds CommunNomsTaxons
$reponse = $this->formaterId($resultat[0]);
break;
case 'noms/id/relations' :
$reponse = $this->formaterIdRelations($resultat[0]);
break;
case 'noms/id/relations/synonymie' :
$reponse = $this->formaterIdSynonymie($resultat);
break;
case 'noms/id/relations/homonymie' :
$reponse = $this->formaterIdHomonymie($resultat);
break;
case 'noms/id/relations/flores' : //ds CommunsNomsTaxons
$reponse = $this->formaterIdFlores($resultat);
break;
case 'noms/stats/annees' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsAnnee($resultat);
break;
case 'noms/stats/rangs' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsRang($resultat);
break;
case 'noms/stats/initiales' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsInitiales($resultat);
break;
case 'noms' :
$reponse = $this->formaterNoms($resultat);
break;
}
return $reponse;
}
 
//+---------------------concerne les resultats pour des requetes de type noms/id-----------------------------+
 
public function formaterRelations($resultat) {
$num_nom = $resultat['num_nom'];
if (isset($this->ressources[3])) {
$url = Config::get('url_service').$this->service."/$num_nom/relations";
} else {
$type = $this->ressources[3];
$url = Config::get('url_service')."/$this->service/$num_nom/relations/$type";
}
$res = $this->consulterHref($url);
return $res;
}
 
public function formaterIdRelations($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
$retour_id_rel = array ('entete' => array()); //on initialise pr que l'entete apparaisse en premier lors de l'affichage
 
//on recupère le resultat de chaque relation (appel du WS correspondant)
$flores = $this->ajouterRelations('flores');
if (isset($flores)) $retour_id_rel['resultat']['flores'] = $flores;
$homonymes = $this->ajouterRelations('homonymie');
if (isset($homonymes)) $retour_id_rel['resultat']['homonymes'] = $homonymes;
$synonymes = $this->ajouterRelations('synonymie');
if (isset($synonymes)) $retour_id_rel['resultat']['synonymes'] = $synonymes;
 
//on renvoit null si il n'existe aucune relations (on efface l'entete en premier lieu)
if (!isset($retour_id_rel['resultat'])) {
$retour_id_rel = null;
} else { //on rajoute l'entete si des relations existent
$this->afficherDonnees('num_nom', $this->ressources[0]);
$retour_id_rel['entete'] = $this->table_retour;
$this->table_retour = array();
}
return $retour_id_rel;
}
 
/**
* Recupere les relations (type de la relation passée en paramètres :[type_relation] = synonymie, homonymie ou
* flores) par l'appel du web service [version]/noms/#id/relations/[type_relation]
*/
public function ajouterRelations($relation) {
$version = str_replace(Config::get('bdd_table').'_', '', $this->table);
$res = null;
$parametres_url = '';
if ($this->parametres != array()) $parametres_url = '?'.http_build_query($this->parametres, '', '&');
$url = Config::get('url_service').'/'.$this->service.'/'
.$this->ressources[0].'/relations/'
.$relation.$parametres_url; Debug::printr($url);
 
$relation = $this->consulterHref($url);
 
$res = $relation->resultat;
return $res;
}
 
 
public function formaterIdSynonymie($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$retour_id_syn = array();
if ($resultat[0]['num_nom_retenu'] == '') return array('nom_retenu N.D.');
 
// 1 ou + résultat(s)
$retour_id_syn['entete'] = $this->afficherEnteteResultat('/'.$this->service.'/'.$this->ressources[0].'/relations/synonymie');
$retour_id_syn['entete']['id'] = $this->ressources[0];
$retour_id_syn['resultat'] = array();
 
// résultat contient aussi l'original
if(count($resultat) > 1) {
//on remplit d'abord l'entete du resultat
$this->table_retour['id'] = $this->ressources[0];
$this->afficherEnteteResultat('/'.$this->service.'/'.$this->ressources[0].'/relations/synonymie');
$retour_id_syn['entete'] = $this->table_retour;
$this->table_retour = array();
foreach ($resultat as $tab) {
//pour chaque basionyme, on recupère le résultat : num_nom, nom_sci, num_basionyme et num_nom_retenu :
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('num_basionyme', $tab['num_basionyme']);
$this->afficherDonnees('num_type', $tab['num_type']);
$this->afficherDonnees('source_biblio', $tab['source_biblio']);
$retour_id_syn['resultat'][$num] = $this->table_retour;
$this->table_retour = array();
}
if (!isset($retour_id_syn['resultat']) && !in_array('nom_retenu N.D.', $retour_id_syn)) {
$retour_id_syn = null; //on initialise le resultat à null
}
}
return $retour_id_syn;
}
 
public function formaterIdHomonymie($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
if (count($resultat) != 1) {
$this->table_retour['id'] = $this->ressources[0];
$this->afficherEnteteResultat($resultat, '/'.$this->service.'/'.$this->ressources[0].'/relations/homonymie');
$retour_id_hom['entete'] = $this->table_retour;
$this->table_retour = array();
foreach ($resultat as $homonyme) {
$this->resultat_req = $homonyme;
$id = $homonyme['num_nom'];
$this->afficherDonnees('num_nom', $id);
if ($homonyme['num_nom_retenu'] != '') {
$retenu = ($id == $homonyme['num_nom_retenu']) ? 'true' : 'false';
} else {
$retenu = 'absent';
}
$this->table_retour['retenu'] = $retenu;
$retour_id_hom['resultat'][$id] = $this->table_retour;
unset($retour_id_hom['resultat'][$id]['id']);
$this->table_retour = array();
}
} else {
$retour_id_hom = null;
}
return $retour_id_hom;
}
 
 
public function formaterIdFlores($synonymes_flores) {//print_r($resultat);
$this->recupererTableSignification('noms_projets');
if (is_array($synonymes_flores)) {//print_r($synonymes_flores);
foreach ($synonymes_flores as $synonyme) {
if ($synonyme['num_nom'] === $synonyme['num_nom_retenu']) {
$reponse['entete']['id'] = $synonyme['num_nom'];
}
foreach ($this->noms_projets as $flore => $valeur) {
if (isset($synonyme[$flore.'_num']) && $synonyme[$flore.'_num'] != '') {
$presence[$valeur] = $flore;
$this->table_retour[$flore]['type'] = "code";
$this->afficherInfosFlore($synonyme, $flore, $valeur, '_num');
} else if (isset($synonyme[$flore.'_page']) && $synonyme[$flore.'_page'] != '') {
$this->table_retour[$flore]['type'] = "page";
$this->afficherInfosFlore($synonyme, $flore, $valeur, '_page');
} else if (isset($synonyme[$flore]) && $synonyme[$flore] != '') {
$this->table_retour[$flore]['type'] = "page";
$this->afficherInfosFlore($synonyme, $flore, $valeur, 'page');
}
}
if ($synonyme['flores'] != "") {
$this->recupererTableSignification('correspondance_flores');
$flores = explode(',', $synonyme['flores']);
$projet = array_flip($this->noms_projets);
foreach ($flores as $b =>$code) {
$code = trim($code);
if (isset($this->correspondance_flores[$code]) && !isset($presence[$this->correspondance_flores[$code]])) {
$this->table_retour[$projet[$this->correspondance_flores[$code]]]['nom_flore'] = $this->correspondance_flores[$code];
}
}
}
}
}
 
if ($this->table_retour != array()) {
$reponse['resultat'] = $this->table_retour;
$this->table_retour = array();
} else {
$reponse = null;
}
return $reponse;
}
 
 
public function afficherInfosFlore($synonyme, $flore, $nom_flore, $type) {
preg_match('/^([0-9]+)(.*)?$/', $synonyme[$flore.$type], $match);
$this->table_retour[$flore]['nom_flore'] = $nom_flore;
$this->table_retour[$flore]['num'][$synonyme[$flore.$type]]['id'] = $match['1'];
$this->table_retour[$flore]['num'][$synonyme[$flore.$type]]['num_nom'] = $synonyme['num_nom'];
$this->table_retour[$flore]['num'][$synonyme[$flore.$type]]['nom_sci'] = $synonyme['nom_sci'];
if (isset($synonyme[$flore.'_rem']) && $synonyme[$flore.'_rem'] != '') {
$this->table_retour[$flore]['num'][$synonyme[$flore.$type]]['remarques'] = $synonyme[$flore.'_rem'];
}
if ($flore == "flore_coste") {
$this->table_retour[$flore]['num'][$synonyme[$flore.$type]]['href'] = $this->ajouterHrefAutreProjet('textes', 'coste.nn:', $match[1], 'coste');
}
switch ($flore) {
case "flore_coste" : $statuts = array('syn' => 'synonyme', 'incl'=> 'taxons inclus dans', 'x' => 'correspond aux compléments en fin de tome 3',
'hyb' => 'hybride', 'sub' => 'nom apparaissant dans la clé sous');break ;
case "flore_bonnier" : break ; // champ vide
case "flore_cnrs" : $statuts = array('syn' => 'synonyme', 'incl'=> 'taxons inclus dans');break ;
case "flore_fe" : break ; // champ vide
case "flore_coste" : $statuts = array('syn' => 'synonyme', 'inc'=> 'taxons inclus dans', 'x' => 'compléments en fin de tome 3');break ;
case "flore_fh" : $statuts = array('syn' => 'synonyme', 'inc'=> 'taxons inclus dans'); break;
case "flore_fournier" : $statuts = array('syn' => 'synonyme', 'hyb'=> 'hybride', 'sub' => 'nom apparaissant dans la clé sous'); break;
case "flore_belge_ed5" : $statuts = array('R'=> 'nom retenu', 'S' => 'synonyme');break ;
case "flore_fg" : $statuts = array('r' => 'nom retenu', 'c' => 'cité hors clé',
's' => 'synonyme d’un nom retenu', 'cs' => 'synonyme d’un nom cité hors clé',
'i' => 'nom d’un taxon inclus dans un autre', 'is' => 'syn d’un nom d’un taxon inclus dans un autre');break ;
}
/*
* Pour CNRS :
a, b, c, d = le taxon est inclus dans un autre taxon, mentionné en note
 
 
Pour Coste :
a, b,… aux taxons inclus dans
*/
if (isset($statuts[trim($match[2])])) {
$this->table_retour[$flore]['num'][$synonyme[$flore.$type]]['statut'] = $statuts[trim($match[2])];
} else if(trim($match[2]) != "") {
$suf = preg_split('/[\.|-|\s]/', $match[2]);
$statut = "";
foreach ($suf as $s) {
if (isset($statuts[trim($s)])) {
$statut .= $statuts[trim($s)]." ";
} else if (preg_match('/^[a-z]$/', trim($s)) === 1) {
$statut .= "taxon '".trim($s)."' inclus dans un autre taxon ";
} else {
$statut .= trim($s)." ";
}
}
$this->table_retour[$flore]['num'][$synonyme[$flore.$type]]['statut'] = trim($statut);
}
}
 
//+---------------------concerne les resultats pour des requetes de type /noms avec ou sans paramètres-------+
 
public function formaterNoms($resultat) {
if ($this->parametres['retour.format'] == 'oss') {
$reponse = $this->formaterEnOss($resultat); //Ds CommunNomsTaxons.php
} else {
$reponse = $this->formaterEnJsonMax($resultat);
}
return $reponse;
}
 
public function formaterEnJsonMax($resultat) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
 
// TODO : améliorer le tri des résultats
// ATTENTION : ce comportement est étrange
$masque = $this->recupererMasquePrincipal();
if ($masque && isset($this->parametres[$masque[0]] /* à éclaircir */ ) && !isset($this->parametres['retour.tri'])) {
$resultat = $this->trierRechercheFloue($this->parametres[$masque[0]], $resultat, $masque[1]);
}
 
// Tri à la mode du CeL : lexicographique puis noms retenus (retour.tri = "alpharet")
if (isset($this->parametres['retour.tri']) && ($this->parametres['retour.tri'] == "alpharet")) {
usort($resultat, array($this, 'genrePuisNomsRetenusEnTete'));
}
 
$table_retour_json['entete'] = $this->afficherEnteteResultat('/'.$this->service);
$table_retour_json['resultat'] = $this->remplirJsonResultat($resultat);
return $table_retour_json;
}
 
// Trie les éléments du tableau de résultats : le genre en tête, puis les noms retenus, puis le reste
// mais à partir du jeu de données retourné par SQL (indépendents du statut "retenu")
private function genrePuisNomsRetenusEnTete($a, $b) {
// On pourrait utiliser l'indice ['retenu'] mais il contient parfois "absent", qui est dur à traiter
$aEstRetenu = ($a['num_nom'] == $a['num_nom_retenu']);
$bEstRetenu = ($b['num_nom'] == $b['num_nom_retenu']);
$retour = 0;
 
// les noms retenus en premier ("inférieurs")
if ($aEstRetenu) {
if (! $bEstRetenu) {
$retour = -1;
}
} else {
if ($bEstRetenu) {
$retour = 1;
}
}
 
// en cas d'égalité on conserve le tri lexicographique - devrait faire sortir le genre en première position
// car il ne contient pas le nom d'auteur
if ($retour == 0) {
$retour = strcasecmp($a['nom_sci'], $b['nom_sci']);
}
 
return $retour;
}
 
public function remplirJsonResultat($resultat) {
$champs = null;
if (array_key_exists('retour.champs', $this->parametres)) {
$champs = explode(',', $this->parametres['retour.champs']);
}
 
// Structure des données: objet ou liste ?
$modeListe = false;
if (array_key_exists('retour.structure', $this->parametres)) {
$modeListe = ($this->parametres['retour.structure'] === "liste");
}
 
$noms = array();
foreach ($resultat as $tab) {
$this->table_retour = array();
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num); // ajoute le nom_sci, href et si le nom est retenu dans $this->table_retour
$retour = $this->table_retour;
$this->table_retour = array();
if ($champs != null) {
$reponse_id = $this->formaterId($tab);
$this->table_retour = array();
$this->ajouterChampsPersonnalises($champs, $reponse_id);
$retour = array_merge($retour, $this->table_retour);
}
if ($modeListe) {
$retour['num_nom'] = intval($num);
$noms[] = $retour;
} else {
$noms[$num] = $retour;
}
}
 
return $noms;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/bdtfx/Taxons.php
New file
0,0 → 1,522
<?php
 
// declare(encoding='UTF-8');// ou ISO-8859-15
/**
* Description :
* Classe Taxons.php permettant de fournir des informations sur les noms scientifiques retenu.
* Si l'url finit par /taxons on retourne une liste de noms latin et leurs identifiants (seulement les 100 premeiers noms par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /taxons?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, recherche, rang, distinct, retour.format, nl.format,
* nl.structure, 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 Taxons extends CommunNomsTaxons {
/** Permet de stocker la requete formulée taxons | taxons/#id | taxons/#id/#champ+#champ ...*/
protected $format_reponse = 'taxons';
protected $service = 'taxons';
protected $requete_champ = 'num_nom, nom_sci, num_nom_retenu, num_taxonomique ';
protected $requete_condition = null;
protected $requete_group_by = ' ';
/** Permet de stocker les limite de la requete SQL (par défaut seul les 100 premiers résultats seront retournés).*/
protected $limite_requete = array('depart' => 0, 'limite' => 100);
protected $num_nom_taxon; //Stocke le num_nom du nom retenu du num_nom recherché
protected $presence_num_tax = true;
public function consulter($ressources, $parametres) {
return parent::consulter($ressources, $parametres);
}
public function traiterParametresSpecifiques() {
$this->requete_condition[] = 'num_nom = num_nom_retenu';
foreach ($this->parametres as $param => $val) {
switch ($param) {
case 'masque' :
$this->ajouterFiltreMasque('nom_sci', $val);
break;
case 'masque.nt' :
$this->requete_condition[] = "num_taxonomique IN ($val)";
$this->masque[] = "num_tax=$val";
break;
case 'masque.rg':
$this->requete_condition[] = 'rang = '.$this->getBdd()->proteger($val);
$this->masque[] = "rang=$val";
break;
}
}
}
//------------------------------------------Fonction ressources---------------------------------------------------------------------
public function gererNumTax() {
if (!in_array('num_taxonomique', $this->champs_table)) {
$this->presence_num_tax = false;
$this->requete_champ = str_replace(', num_taxonomique ', '', $this->requete_champ);
} else {
$this->presence_num_tax = true;
}
}
public function traiterRessourcesIdentifiant() {
$this->format_reponse = 'taxons/id';
$this->traiterRessourceNtId();
$this->num_nom_taxon = $this->recupererNumNomTaxon(); //on recupere le taxon correspondant au num_nom recherché
if ($this->entete_http == '') {
$this->requete_condition[0] = 'num_nom = '.$this->getBdd()->proteger($this->num_nom_taxon);
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
//---------------- requete de type taxons/#id/#champ+#champ--------------------------------------
if ($this->ressources[1] != 'relations') { // SELECT *, nom_sci FROM bftfx_v2_00 WHERE num_nom = X;
$this->requete_champ = ' *, nom_sci ';
$this->format_reponse .= '/champ';
//---------------- requete de type taxons/#id/relations/#relation--------------------------------
} elseif ($this->ressources[1] == 'relations') {
$this->traiterRessourceIdRelations();
} else {
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> #id/relations </li> <li> #id/#champ+#champ </li> <li> #id/relations </li>
<li> #id/relations/inferieurs </li> <li> #id/relations/superieurs </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else { //--------------- requete de type taxons/#id-----------------------------------------------------
$this->requete_champ = ' *, nom_sci ';
}
}
}
public function traiterRessourceNtId() {
if (strrpos($this->ressources[0], 'nt:') !== false) {
if ($this->presence_num_tax) {
// SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = num_nom_retenu AND num_taxonomique = X;
$this->requete_condition[0] = ' num_taxonomique = '
.str_replace('nt:', '', $this->ressources[0]).' ';
} else {
$e = 'Erreur dans votre requête : </br> Le numéro taxonomique n\'existe pas dans ce projet';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
}
} else {
// SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = (SELECT num_nom_retenu FROM bdtfx_v2_00 WHERE num_nom = X);
$this->requete_condition[0] = 'num_nom = '.$this->ressources[0];
}
}
/** Permet de récupérer le num_nom du taxon recherché. Soit le numéro taxonomique est demandé (avec nt: )
* soit un num_nom dont on recherche le num_nom_retenu */
public function recupererNumNomTaxon() {
$identifiant = '';
if ($this->entete_http == '') {
//on récupere l'identifiant du taxon correspondant au num_nom ou num_taxonomique demandé pour pouvoir l'afficher
$req_tax = 'SELECT num_nom_retenu FROM '.$this->table.' WHERE '.$this->requete_condition[0];
$res_tax = $this->getBdd()->recuperer($req_tax . ' -- ' . __FILE__ . ':' . __LINE__ );
//on recherche ensuite les identifiants des taxons supérieurs ou inférieurs
if ($res_tax && $res_tax != '') {
$identifiant = $res_tax['num_nom_retenu'];
} else {
$e = 'Le numéro de taxon ou l\'identifiant de nom correspondant au num_nom '
.$this->ressources[0].' n\'existe pas dans la base.';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
Debug::printr($req_tax);
}
}
return $identifiant;
}
public function traiterRessourceIdRelations() {
//----------------- requete de type taxons/#id/relations-------------------------------------------
// SELECT *, nom_sci FROM bftfx_v2_00 WHERE num_nom = X;
$this->format_reponse .= '/relations';
if (isset($this->ressources[2]) && !empty($this->ressources[2])) {
//------------- requete de type taxons/#id/relations/#relation--------------------------------
switch ($this->ressources[2]) {
case 'superieurs' :
$rel = 'recupererIdSup';
$this->format_reponse .= '/superieurs';
$this->traiterRessourceIdRelationInfSup($rel);
break;
case 'inferieurs' :
$rel = 'recupererIdInf';
$this->format_reponse .= '/inferieurs';
$this->traiterRessourceIdRelationInfSup($rel);
break;
case 'hierarchie' :
$rel = 'recupererIdHierarchie';
$this->format_reponse .= '/hierarchie';
$this->traiterRessourceIdRelationHierarchie($rel);
break;
default :
$e = 'Erreur dans votre requête </br> Ressources disponibles : <br/>
<li> taxons/#id/relations </li><li> #id/relations/inferieurs </li>
<li> #id/relations/superieurs </li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $e);
break;
}
}
}
public function traiterRessourceIdRelationInfSup($rel) {
//Appel de la fct récupérerIdSup ou recupererIdInf : retourne les num_nom des noms inferieurs ou superieurs
$res_relation = $this->$rel();
//analyse du résultat retourné par la requete de recherche des identifiants correspondant aux taxons inf|sup :
if ($res_relation == '') { //dans le cas ou la requete comporte des erreurs
$e = 'Fct traiterRessourceIdRelationInfSup : La requête forme comporte une erreur!';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
} elseif ($res_relation) {
//dans le cas ou une ou plusieurs relations est retournée, on récupère les identifiants ss la forme (id, id, id)
foreach ($res_relation as $ligne) $res[] = $ligne['num_nom'];
$res = implode(',',$res);
$this->requete_condition[0] = "num_nom IN ($res)";
$this->requete_champ .= ', rang, num_tax_sup ';
} else { //dans le cas ou aucune relation n'existe
$res = array($this->num_nom_taxon => null);
$this->corps_http = json_encode($res);
$this->entete_http = RestServeur::HTTP_CODE_OK;
}
}
public function traiterRessourceIdRelationHierarchie($rel) {
//Appel de la fct récupérerIdSup ou recupererIdInf : retourne les num_nom des noms inferieurs ou superieurs
$res_relation = $this->$rel();
//analyse du résultat retourné par la requete de recherche des identifiants correspondant aux taxons inf|sup :
if ($res_relation == '') {
//dans le cas ou la requete comporte des erreurs
$e = 'Fct traiterRessourceIdRelationInfSup : La requête forme comporte une erreur!';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $e);
} elseif ($res_relation) {
//dans le cas ou une ou plusieurs relations est retournée, on récupère les identifiants ss la forme (id, id, id)
foreach ($res_relation as $ligne) $res[] = $ligne['num_nom'];
$res = implode(',',$res);
$this->requete_condition[0] = "num_nom IN ($res)";
$this->requete_champ .= ', rang, num_tax_sup ';
} else { //dans le cas ou aucune relation n'existe
$res = array($this->num_nom_taxon => null);
$this->corps_http = json_encode($res);
$this->entete_http = RestServeur::HTTP_CODE_OK;
}
}
public function recupererIdHierarchie() {
$req_relation = 'SELECT num_nom FROM '.$this->table.' '.
' WHERE hierarchie LIKE CONCAT('.
'(SELECT hierarchie FROM '.
$this->table.' '.
'WHERE num_nom = '.$this->getBdd()->proteger($this->num_nom_taxon).')'.
', '.$this->getBdd()->proteger($this->num_nom_taxon.'-%').
')';
$res_relation = $this->getBdd()->recupererTous($req_relation . ' -- ' . __FILE__ . ':' . __LINE__ );
return $res_relation;
}
public function recupererIdInf() {
//SELECT num_nom FROM bfdtx_v2_00 WHERE num_tax_sup = (SELECT num_nom FROM bdtfx_v2_00 WHERE num_nom = X);
$req_relation = 'SELECT num_nom FROM '.$this->table
.' WHERE num_nom = num_nom_retenu AND num_tax_sup = (SELECT num_nom FROM '
.$this->table
.' WHERE '.implode(' AND ', $this->requete_condition).')';
$res_relation = $this->getBdd()->recupererTous($req_relation . ' -- ' . __FILE__ . ':' . __LINE__ );
return $res_relation;
}
public function recupererIdSup() {
//SELECT num_nom FROM bfdtx_v2_00 WHERE num_nom = (SELECT num_tax_sup FROM bdtfx_v2_00 WHERE num_nom = X);
$this->requete_condition[] = "num_nom = num_nom_retenu" ;
$req_relation = 'SELECT num_tax_sup as num_nom FROM '.$this->table
.' WHERE '.implode(' AND ', $this->requete_condition);
$res_relation = $this->getBdd()->recupererTous($req_relation . ' -- ' . __FILE__ . ':' . __LINE__ );
return $res_relation;
}
 
public function traiterRessourceStatsInitiales() {
// SELECT count(nom_sci) as nb, rang, left(nom_sci, 2) as lettre FROM bdtfx_v2_00 GROUP BY rang, left(nom_sci, 2);
$this->format_reponse = 'taxons/stats/initiales';
$this->requete_champ = 'count(nom_sci) as nb, rang, left(nom_sci, 2) as lettre ';
$this->requete_group_by = ' GROUP BY rang, left(nom_sci, 2) ';
}
public function traiterRessourceStatsRangs() {
// SELECT count(*) as nombre, rang FROM bdtfx_v2_00 [WHERE rang = 290] GROUP BY rang ORDER BY rang;
$this->format_reponse = 'taxons/stats/rangs';
$this->requete_champ = 'count(*) as nombre, rang ';
$this->requete_group_by = ' GROUP BY rang ORDER BY rang ';
}
public function traiterRessourceStatsAnnees() {
// SELECT count(*) as nombre, annee FROM bdtfx_v2_00 GROUP BY annee ORDER BY annee;
$this->format_reponse = 'taxons/stats/annees';
$this->requete_champ = 'count(*) as nombre, annee ';
$this->requete_group_by = ' GROUP BY annee ORDER BY annee ';
}
//-----------------------------FONCTIONS DASSEMBLAGE DE LA REQUETE-----------------------------------------------------
public function assemblerLaRequete() {
if ($this->format_reponse != 'taxons/stats/initiales') {
$this->mettreAuFormat(); //on remplace les nom_sci par les nom_sci_html
}
$requete = ' SELECT '.$this->requete_champ.
' FROM '.$this->table
.$this->retournerRequeteCondition()
.$this->requete_group_by
.$this->formerRequeteLimite() .
' -- ' . __FILE__ . ':' . __LINE__ ;
return $requete;
}
public function formerRequeteLimite() {
if ($this->format_reponse != 'taxons' && $this->format_reponse != 'taxons/id/relations/homonymie') {
$this->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
$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 retournerRequeteCondition() {
$condition = '';
if ($this->requete_condition) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
public function recupererTotalResultat() {
$requete = 'SELECT count(*) as nombre FROM '.$this->table.$this->retournerRequeteCondition().$this->requete_group_by;
$res = $this->getBdd()->recuperer($requete);
if ($res) {
$total = $res['nombre'];
}
return $total;
}
 
//-------------------------FONCTIONS DE FORMATION DU RESULTAT-----------------------------------------------------------
/** Permet de récupérer le résultat à retourner propre à chaque requete et de l'encoder en json*/
public function retournerResultatFormate($resultat, $version) {
$reponse = null;
switch ($this->format_reponse) {
case 'taxons/id' ://ds CommunNomsTaxons
$reponse = $this->formaterId($resultat[0]);
break;
case 'taxons/id/champ' ://ds CommunNomsTaxons
$reponse = $this->formaterIdChamp($resultat[0]);
break;
case 'taxons/id/relations' :
$reponse = $this->formaterIdRelations($resultat[0],$version);
break;
case 'taxons/id/relations/superieurs' :
$reponse = $this->formaterIdSuperieur($resultat, $version);
break;
case 'taxons/id/relations/inferieurs' :
$reponse = $this->formaterIdInferieur($resultat);
break;
case 'taxons/id/relations/hierarchie' :
// le formatage de la hiérarchie est identique aux relations inférieures
$reponse = $this->formaterIdInferieur($resultat);
break;
case 'taxons/stats/annees' : //ds CommunNomsTaxons
$reponse = $this->formaterStatsAnnee($resultat);
break;
case 'taxons/stats/rangs' ://ds CommunNomsTaxons
$reponse = $this->formaterStatsRang($resultat);
break;
case 'taxons/stats/initiales' ://ds CommunNomsTaxons
$reponse = $this->formaterStatsInitiales($resultat);
break;
case 'taxons' :
$reponse = $this->formatertaxons($resultat);
break;
}
return $reponse;
}
//----------------------concerne les resultats pour des requetes de type /noms avec ou sans paramètres--------------
public function formaterTaxons($resultat) {
if ($this->parametres['retour.format'] == 'oss') {
$reponse = $this->formaterEnOss($resultat);
} else {
$reponse = $this->formaterEnJsonMax($resultat);
}
return $reponse;
}
public function formaterEnJsonMax($resultat) {
//print_r($resultat);
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$masque = $this->recupererMasquePrincipal();
if (isset($masque)) $resultat = $this->trierRechercheFloue($this->parametres[$masque[0]], $resultat, $masque[1]);
$table_retour_json['entete'] = $this->afficherEnteteResultat('/'.$this->service);
//on remplit la table $table_retour_json['resultat']
$tab_tax_inf = $this->recupererListeTaxonInf($resultat);
foreach ($resultat as $tab) {
$num = $tab['num_nom'];
if (isset($this->parametres['masque.nt'])) $this->afficherDonnees('num_taxonomique', $tab['num_taxonomique']);
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherTaxonInfNb($num, $tab_tax_inf);
$resultat_json[$num] = $this->table_retour;
$this->table_retour = array(); //on vide le tableau table_retour
}
$table_retour_json['resultat'] = $resultat_json;
return $table_retour_json;
}
//--------------------concerne les resultats pour des requetes de type noms/id----------------------------------------
 
public function formaterIdRelations($resultat, $version) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$this->resultat_req = $resultat;
$retour_id_rel = array ('entete' => array()); //on initialise pr que l'entete apparaisse en premier
 
$superieurs = $this->ajouterRelations('superieurs'); //, $version);
if (isset($superieurs)) $retour_id_rel['resultat']['superieurs'] = $superieurs;
$inferieurs = $this->ajouterRelations('inferieurs', $version);
if (isset($inferieurs)) $retour_id_rel['resultat']['inferieurs'] = $inferieurs;
if (!isset($retour_id_rel['resultat'])) { //on renvoit un tableau null si il n'existe aucune relations
$retour_id_rel = 'null';
} else { //on rajoute l'entete si des relations existent
$this->afficherDonnees('num_nom', $this->num_nom_taxon); //$this->afficherEnteteResultat($resultat, '/'.$this->service.'/'.$this->ressources[0].'/relations/synonymie');
$retour_id_rel['entete'] = $this->table_retour;
$this->table_retour = array();
}
return $retour_id_rel;
}
public function ajouterRelations($relation, $version) {
$version = str_replace(Config::get('bdd_table').'_', '', $version);
$res = null;
$taxon = $this->num_nom_taxon;
$parametres_url = '';
if ($this->parametres != array()) $parametres_url = '?'.http_build_query($this->parametres, '', '&');
$url = Config::get('url_service').'/'
.$this->service.'/'.$version.'/'
.$this->ressources[0].'/relations/'
.$relation.$parametres_url;
$relation = $this->consulterHref($url);
if (isset($relation->resultat)) {
$res = $relation->resultat;
} elseif (isset($relation->$taxon)) { //pour les relations inf et sup
$res = $relation->$taxon;
}
return $res;
}
public function formaterIdSuperieur($resultat, $version) {
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$tab_relation = null; //si il n'existe aucune relation
$taxon_sup_traites = array();
if (($resultat) != '' ) {
//on recupere d'abord les rangs supérieurs
$sup = $resultat[0];
do {
$sup = $this->recupererIdSuperieur($sup['num_tax_sup'], $version);
if(!in_array($sup['num_nom'], $taxon_sup_traites)) {
$taxon_sup_traites[] = $sup['num_nom'];
} else {
$sup = null;
}
if ($sup['rang'] == '0') $sup['rang'] = '10'; //erreur dans la base
if (isset($sup)) $resultat[] = $sup;
} while ($sup != null);
krsort($resultat);
//on les affiche ensuite
foreach ($resultat as $tab) {
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
$this->afficherDonnees('rang', $tab['rang']);
$tab_inf[$num] = $this->table_retour;
$tab_inf[$num]['num_nom'] = $tab['num_nom'];
$this->table_retour = array();
}
$tab_relation[$this->num_nom_taxon] = $tab_inf;
}
return $tab_relation;
}
public function recupererIdSuperieur($id, $version) {
$req = 'SELECT num_nom, num_nom_retenu, num_tax_sup, rang, nom_sci FROM '
.$version.' WHERE num_nom = '.$this->getBdd()->proteger($id);
$res = $this->getBdd()->recupererTous($req . ' -- ' . __FILE__ . ':' . __LINE__ );
if ($res) {
$resultat = $res[0];
} else {
$resultat = null; //on return null si il n'y a pas de taxon superieur
}
return $resultat;
}
public function formaterIdInferieur($resultat) {
// Attention à l'ordre, on doit d'abord récupérer correpondance_champs avant champs_api
$this->recupererTableSignification('correspondance_champs,champs_api,champs_comp');
$tab_relation = null;
if (($resultat) != array()) {
foreach ($resultat as $tab) {
$this->resultat_req = $tab;
$num = $tab['num_nom'];
$this->afficherNomHrefRetenu($tab, $num);
if(!empty($tab['rang'])) {
$this->afficherDonnees('rang', $tab['rang']);
}
$tab_inf[$num] = $this->table_retour;
$tab_inf[$num]['nom_sci'] = $tab['nom_sci'];
$tab_inf[$num]['num_nom'] = $tab['num_nom'];
$this->table_retour = array();
}
$tab_relation[$this->num_nom_taxon] = $tab_inf;
}
return $tab_relation;
}
public function afficherTaxonInfNb($num, $tab_tax_inf) {
foreach ($tab_tax_inf as $taxNb) {
if ($taxNb['num_tax_sup'] == $num) {
$this->table_retour['taxon_inferieur_nbre'] = $taxNb['nb'];
}
}
if (!isset($this->table_retour['taxon_inferieur_nbre'])) {
$this->table_retour['taxon_inferieur_nbre'] = '0';
}
}
public function recupererListeTaxonInf($resultat) {
// SELECT num_tax_sup, count(*) as nb FROM bdtfx_v2_00 WHERE num_tax_sup IN (id, id, id) AND num_nom = num_nom_retenu GROUP BY num_tax_sup';
foreach ($resultat as $tab) {
$tab_num[] = $tab['num_nom']; //on regroupe ici les id des taxons dont on cherche le nb de taxon inf
}
$req = 'SELECT num_tax_sup, count(*) as nb FROM '.$this->table
.' WHERE num_tax_sup IN ('.implode(',',$tab_num)
.') AND num_nom = num_nom_retenu GROUP BY num_tax_sup';
$res = $this->getBdd()->recupererTous($req . ' -- ' . __FILE__ . ':' . __LINE__ );
if ($res) {
$resultat = $res;
} else {
$resultat = array(); //on retourne un tableau vide s'il n'y a pas de taxon inférieurs
}
return $resultat;
}
}
 
?>
/tags/v5.12-baouque/services/modules/0.1/sptba/Statuts.php
New file
0,0 → 1,155
<?php
// declare(encoding='UTF-8');
/**
* Classe implémentant l'API d'eFlore concernant les statuts de protection
*
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Status
*
* @package eFlore/services
* @author Aurélien PERONNET <aurelien@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)
*/
// TODO : Config et Outils sont des classes statiques qui doivent poser des pb pour les tests...
class Statuts extends Commun {
 
protected $parametres = array();
protected $ressources = array();
private $bdd;
private $retour_format = 'complet';
private $retours_formats_autorises = array('complet','zone_geo');
 
public function __construct($config = null) {
$this->config = $config;
$this->bdd = $this->getBdd();
}
public function consulter($ressources, $parametres) {
 
$this->parametres = $parametres;
$this->ressources = $ressources;
 
$this->affecterParametresParDefaut();
$this->verifierParametres();
 
$resultat = new ResultatService();
$resultat->corps = $this->obtenirStatuts();
 
return $resultat;
}
//+---------------------------FONCTION D'ANALYSE DES PARAMETRES---------------------------------------------------------+
 
private function affecterParametresParDefaut() {
$this->retour_format = isset($this->parametres['retour.format']) ? $this->parametres['retour.format'] : $this->retour_format;
}
private function verifierParametres() {
$erreurs = array();
if (empty($this->parametres['masque.nn'])) {
$erreurs[] = 'renseignez une valeur pour masque.nn';
}
if(!is_numeric($this->parametres['masque.nn'])) {
$erreurs[] = 'la valeur pour masque.nn doit être un entier';
}
if(!in_array($this->retour_format, $this->retours_formats_autorises)) {
$erreurs[] = 'la valeur '.$this->retour_format.' est inconnue';
}
if (count($erreurs) > 0) {
$message = implode('<br />', $erreurs);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
}
//+---------------------------FONCTIONS DE REQUETE---------------------------------------------------------+
 
private function obtenirLois(Array $id_lois) {
$id_lois = array_map(array($this->bdd, 'proteger'), $id_lois);
$requete = "SELECT * FROM ".Config::get('bdd_table_lois').' '.
"WHERE id IN (".implode(',',$id_lois).") ";
return $this->bdd->recupererTous($requete);
}
private function obtenirLoisZoneGeo(Array $id_lois) {
$id_lois = array_map(array($this->bdd, 'proteger'), $id_lois);
$requete = "SELECT DISTINCT zone_application, code_zone_application FROM ".Config::get('bdd_table_lois').' '.
"WHERE id IN (".implode(',',$id_lois).") ";
return $this->bdd->recupererTous($requete);
}
private function obtenirStatuts() {
$nn_demande = $this->parametres['masque.nn'];
$conditions_taxons = array();
$conditions_taxons = $this->obtenirNumNomTaxonsSuperieurs(Config::get('referentiel'), $nn_demande);
$conditions_taxons[] = $this->bdd->proteger($nn_demande);
$requete = "SELECT * FROM ".Config::get('bdd_table_especes').' '.
"WHERE num_nom_retenu IN (".implode(', ', $conditions_taxons).") OR ".
"num_nom IN (".implode(', ', $conditions_taxons).") ";
$statuts = $this->bdd->recuperer($requete);
$statuts = $this->formaterRetour($statuts);
return $statuts;
}
//+---------------------------FONCTIONS DE FORMATAGE---------------------------------------------------------+
 
private function formaterRetour($statuts_taxon) {
switch($this->retour_format) {
case 'zone_geo':
$retour = $this->formaterStatutsTaxonZoneGeo($statuts_taxon);
break;
case 'complet':
$retour = $this->formaterStatutsTaxon($statuts_taxon);
break;
default:
$retour = $this->formaterStatutsTaxon();
break;
}
return $retour;
}
private function formaterStatutsTaxonZoneGeo($statuts_taxon) {
$lois_statuts = array();
foreach ($statuts_taxon as $champ => $statut) {
if($statut == "1") {
$lois_statuts[] = $champ;
}
}
$zones_geo_lois = (!empty($lois_statuts)) ? $this->obtenirLoisZoneGeo($lois_statuts) : array();
return $zones_geo_lois;
}
private function formaterStatutsTaxon($statuts_taxon) {
$statuts_formates = array();
$lois_statuts = array();
if(is_array($statuts_taxon)) {
unset($statuts_taxon['num_nom']);
unset($statuts_taxon['num_nom_retenu']);
unset($statuts_taxon['nom_sci']);
foreach ($statuts_taxon as $champ => $statut) {
if($statut == "1") {
$lois_statuts[] = $champ;
}
}
}
$statuts_formates = (!empty($lois_statuts)) ? $this->obtenirLois($lois_statuts) : array();
return $statuts_formates;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/Projets.php
New file
0,0 → 1,332
<?php
/**
* Description :
* Classe principale de chargement des services d'eFlore.
*
* 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 Projets extends RestService {
 
/** Contients les paramètres.*/
private $parametres = array();
/** Contients les ressources.*/
private $ressources = array();
 
/** Nom du projet courrant. */
private $projetNom = array();
/** Nom du service demandé. */
private $serviceNom = array();
/** Chemin vers le dossier courrant. */
private $cheminCourrant = null;
private $classe = null;
 
private $cache;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres brutes. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourrant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$resultat = '';
$reponseHttp = new ReponseHttp();
try {
$this->initialiserRessourcesEtParametres($ressources, $parametres);
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
if(strpos($_SERVER['SCRIPT_NAME'], 'phpunit') === FALSE) $reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function traiterRessources() {
$retour = '';
if ($this->avoirRessources()) {
if ($this->avoirRessourceProjet()) {
$this->chargerNomDuService(); // défini $this->serviceNom
$this->initialiserProjet(); // autoload defined here
if ($this->avoirRessourceService()) {
$this->classe = self::debusquerClasse($this->projetNom, $this->serviceNom);
$retour = $this->initialiserService();
}
}
}
return $retour;
}
 
private function avoirRessources() {
$presenceDeRessources = false;
if (isset($this->ressources) && count($this->ressources) > 0) {
$presenceDeRessources = true;
} else {
$message = "Aucune ressource n'a été indiquée.\n".
"Veuillez indiquer au moins un code de projet et un type de service.";
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
return $presenceDeRessources;
}
 
private function avoirRessourceProjet() {
$presenceRessourceProjet = false;
$projet = $this->ressources[0];
$projetsDispo = Outils::recupererTableauConfig('projetsDispo');
if (in_array($projet, $projetsDispo)) {
$presenceRessourceProjet = true;
} else {
$message = "La ressource '$projet' n'indique pas un projet existant.\n".
"Les projets existant sont :\n".implode(', ', $projetsDispo);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
return $presenceRessourceProjet;
}
 
private function initialiserProjet() {
$this->chargerNomDuProjet();
$this->chargerConfigProjet();
 
// php5.3 : Enregistrement en première position des autoload de la méthode gérant les classes des services
if (phpversion() < 5.3) {
spl_autoload_register(array($this, 'chargerClasseProjet'));
} else {
spl_autoload_register(array($this, 'chargerClasseProjet'), true , true);
}
}
 
private function chargerNomDuProjet() {
$this->projetNom = $this->ressources[0];
}
 
private function chargerConfigProjet() {
$projet = $this->projetNom;
$chemin = Config::get('chemin_configurations')."config_$projet.ini";
Config::charger($chemin);
}
 
/*
1) jusqu'à présent:
* le principe pour URL = a/b est: de charger
* require_once($chemin/a/ucfirst(c).php)
* new ucfirst(c); ucfirst(c)->consulter()
* sachant que ucfirst(c).php et la classe ucfirst(c) apparaîssent à de multiples emplacements (selon a)
 
1") Beurk... (php-className conflicts en PHP 5.2)
 
Ici nous faisons des cas particuliers pour Ontologies, mais en suivant ce principe, sont affectés:
Images, Informations, InformationsTaxonsSup,
LegendeCartes, NomCommune, Noms, NomsVernaculaires, Projets, Statuts,
Taxons, TaxonsCartes, Textes, ZoneGeo
 
cf:
$ grep -r '^[cC]lass '|grep -F '.php:'|egrep -w " \($(grep -rh '^[cC]lass '|awk '{print $2}'|sort|uniq -d|tr "\n" '|')\) " \
|sort -k2
 
PS: "Using two class with the same name"
http://stackoverflow.com/questions/4555186/using-two-class-with-the-same-name
> Stop.
> Whatever you are doing is wrong. Backup. Re-evaluate what you are doing and why.
*/
private static function debusquerClasse($p, $s) {
if($s == 'ontologies') {
switch($p) {
case 'baseflor':
return 'BaseFloreOntologies';
case 'eflore':
return 'EfloreOntologies';
case 'chorodep':
return 'ChorodepOntologies';
case 'baseveg':
return 'BasevegOntologies';
case 'moissonnage':
return 'MoissonnageOntologies';
case 'commun':
return 'Ontologies';
}
}
 
if($s == 'cartes') {
switch($p) {
case 'bdtxa':
return 'BdtxaCartes';
case 'eflore':
return 'EfloreCartes';
case 'chorodep':
return 'ChorodepCartes';
case 'moissonnage':
return 'MoissonnageCartes';
case 'sophy':
return 'SophyCartes';
}
}
 
return NULL;
}
 
private function chargerClasseProjet($classe) {
if (class_exists($classe)) {
return null;
}
 
if($this->serviceNom == 'ontologies') {
$c = NULL;
switch($this->projetNom) {
case 'baseflor':
$c = 'BaseFloreOntologies';
break;
case 'eflore':
$c = 'EfloreOntologies';
break;
case 'chorodep':
$c = 'ChorodepOntologies';
break;
case 'baseveg':
$c = 'BasevegOntologies';
break;
case 'moissonnage':
$c = 'MoissonnageOntologies';
break;
case 'commun':
$c = 'Ontologies';
break;
}
if($c) {
require_once($this->cheminCourrant . 'commun' . DS . 'Commun.php');
require_once($this->cheminCourrant . $this->projetNom . DS . $this->obtenirNomClasseService($this->serviceNom) . '.php');
return;
}
}
 
// problème de class-name conflict. Exemple:
// phpunit --verbose --debug --filter 'ChorodepCartesTest::testCarteGenerique|EfloreCartesTest::testCarteGenerale'
if($this->serviceNom == 'cartes') {
$c = NULL;
switch($this->projetNom) {
case 'bdtxa':
$c = 'BdtxaCartes';
break;
case 'eflore':
$c = 'EfloreCartes';
break;
case 'chorodep':
$c = 'ChorodepCartes';
break;
case 'moissonnage':
$c = 'MoissonnageCartes';
break;
case 'sophy':
$c = 'SophyCartes';
break;
}
if($c) {
require_once($this->cheminCourrant . 'commun' . DS . 'Commun.php');
require_once($this->cheminCourrant . $this->projetNom . DS . $this->obtenirNomClasseService($this->serviceNom) . '.php');
return;
}
}
 
$cheminBiblio = Config::get('chemin_bibliotheque');
$chemins = array();
$chemins[] = $this->cheminCourrant.$this->projetNom.DS;
$chemins[] = $this->cheminCourrant.'commun'.DS;
$chemins[] = $cheminBiblio;
$chemins[] = $cheminBiblio.'robots'.DS;
 
foreach ($chemins as $chemin) {
$chemin = $chemin.$classe.'.php';
if (file_exists($chemin)) {
require_once $chemin;
break;
}
}
}
 
private function avoirRessourceService() {
$presenceRessourceService = false;
$servicesDispo = Outils::recupererTableauConfig('servicesDispo');
if (isset($this->ressources[1])) {
$service = $this->ressources[1];
if (in_array($service, $servicesDispo)) {
$presenceRessourceService = true;
} else {
$message = "Le service demandé '$service' n'est pas disponible pour le projet {$this->projetNom} !\n".
"Les services disponibles sont : ".implode(', ', $servicesDispo);
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
} else {
$message = "Vous n'avez pas indiqué de service pour le projet {$this->projetNom} !\n".
"Les services disponibles sont : ".implode(', ', $servicesDispo);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
return $presenceRessourceService;
}
 
private function initialiserService() {
if($this->classe) {
$classe = $this->classe;
$service = new $classe($this->getBdd());
return $service->consulter($this->filtrerRessourcesPourService(), $this->parametres, $this->getBdd());
}
$classe = $this->obtenirNomClasseService($this->serviceNom);
$chemins = array();
$chemins[] = $this->cheminCourrant.$this->projetNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourrant.'commun'.DS.$classe.'.php';
 
$service = null;
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
$service = new $classe($this->getBdd());
// Affichage utile lors de PHPUnit pour détecter les conflits d'autoload de classes de même nom
// $reflector = new ReflectionClass($classe);
// printf("===> Projets init classe '%s' depuis '%s', mais provenant de '%s'\n", $classe, $chemin, $reflector->getFileName());
$ressourcesPourService = $this->filtrerRessourcesPourService();
return $service->consulter($ressourcesPourService, $this->parametres, $this->getBdd());
}
}
if (is_null($service)) {
$message = "Le service demandé '{$this->serviceNom}' n'existe pas dans le projet {$this->projetNom} !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return NULL;
}
 
private function chargerNomDuService() {
$this->serviceNom = $this->ressources[1];
}
 
private function obtenirNomClasseService($mot) {
return str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
}
 
private function filtrerRessourcesPourService() {
$ressourcesPourService = array();
$nbreDeRessources = count($this->ressources);
for ($i = 2; $i < $nbreDeRessources; $i++) {
$ressourcesPourService[] = $this->ressources[$i];
}
return $ressourcesPourService;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/photoflora/ALIRE.txt
New file
0,0 → 1,8
; l'utilisation d'une redirection transparente des appels à l'api photoflora peut se faire
; en incluant dans le .htaccess du site, la ligne suivante :
RewriteRule ^service:eflore:([0-9]\.[0-9])/photoflora/images$ http://photoflora.free.fr/eflore-photoflora/services/index.php/$1/projets/photoflora/images
; Attention ! Il faut l'inclure avant la ligne de redirection des services web eflore
 
; Free ne supporte pas la redirection .htacess, il faut donc donc la désactiver dans le .htaccess de la racine des services
; Photoflora étant hébergé chez free, il faut changer ce paramètre dans le fichier de config général en ce qui suit
serveur.baseURL = "/eflore-photoflora/services/index.php/"
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/tags/v5.12-baouque/services/modules/0.1/photoflora/Images.php
New file
0,0 → 1,421
<?php
/**
* Web service particulier pour photoflora, qui ne doitpas être installé sur tela botanica
* mais sur photoflora.free.fr
* Une redirection htaccess est à faire, redirigeant /service:eflore:0.1/photoflora/image
* vers le site photoflora à l'adresse ou seront installé les services web et le minimum
* nécessaire pour les faire fonctionner (framework + base de code eflore-projet ou peut-être moins)
*
* La table des metadonnées est, elle, stockée sur Tela Botanica
* Le service est dans le même dépot que les autres par souci de commodité
*
*/
class Images {
 
const MIME_JPEG = 'image/jpeg';
const MIME_PNG = 'image/png';
const MIME_JSON = 'application/json';
const MIME_XML = 'text/xml';
 
//TODO déplacer ceci dans des parametres de config
const BDD_PF = 'photoflora';
private $efph_url_photo = 'http://photoflora.free.fr/photos/%s/max/%s';
private $efph_url_photo_bb = 'http://photoflorabb.free.fr/max/%s';
private $efph_url_photo_jlt = 'http://photoflorajlt.free.fr/max/%s';
 
private $efph_url_photo_min = 'http://photoflora.free.fr/photos/%s/min/%s';
private $efph_url_photo_bb_min = 'http://photoflora.free.fr/photos/bb/min/%s';
private $efph_url_photo_jlt_min = 'http://photoflora.free.fr/photos/jlt/min/%s';
 
private $parametres = array();
private $ressources = array();
private $Bdd;
 
private $format = 'min';
private $retour_mime = 'application/json';
private $nbreImages = '0';
 
public function __construct(Bdd $bdd = null, Array $config = null) {
$this->config = is_null($config) ? Config::get('Images') : $config;
$this->Bdd = is_null($bdd) ? new Bdd() : $bdd;
}
 
public function consulter($ressources, $parametres) {
 
$this->parametres = $parametres;
$this->ressources = $ressources;
 
$this->definirValeurParDefautDesParametres();
 
$this->format = (isset($this->parametres['retour.format']) && $this->parametres['retour.format'] != '') ? $this->parametres['retour.format'] : $this->format;
$this->retour_mime = (isset($this->parametres['retour']) && $this->parametres['retour'] != '') ? $this->parametres['retour'] : $this->retour_mime;
$photographies = $this->getResultatTest();
if($this->retour_mime == self::MIME_JPEG) {
$photo = $this->obtenirPremiereImage();
$retour = $this->formaterRetourImageBinaire($photo);
echo $retour;
} elseif($this->retour_mime == self::MIME_JSON) {
$photographies = $this->obtenirImages();
$this->nbreImages = count($photographies);
$photographies_formatees = $this->formaterRetourJson($photographies);
$resultat = $photographies_formatees;
$entete = $this->construireEntete();
return array('entete' => $entete, 'resultats' => $resultat);
} elseif ($this->retour_mime == self::MIME_XML) {
$photographies = $this->obtenirImages();
$this->nbreImages = count($photographies);
$photographies_formatees = $this->formaterRetourXml($photographies);
header('Content-Type: '.self::MIME_XML);
echo $photographies_formatees;
exit;
}
}
 
private function construireEntete() {
$entete = array('masque' => '', 'depart' => 0, 'limite' => 100, 'total' => 0);
 
$entete['masque'] = $this->recupererMasque();
$entete['depart'] = (int) $this->parametres['navigation.depart'];
$entete['limite'] = (int) $this->parametres['navigation.limite'];
$entete['total'] = $this->nbreImages;
 
return $entete;
}
 
private function recupererMasque() {
$masqueEntete = '';
foreach ($this->parametres as $param => $cle) {
if ($param == 'masque') {
$masqueEntete = 'masque='.$cle.',';
} elseif (substr($param, 0, 7) == 'masque.') {
$masqueEntete .= substr($param, 7).'='.$cle.',';
}
}
$masqueEntete = rtrim($masqueEntete,',');
return $masqueEntete;
}
 
private function definirValeurParDefautDesParametres() {
if (isset($this->parametres['retour']) == false) {
$this->parametres['retour'] = self::MIME_JSON;
}
if (isset($this->parametres['retour.format']) == false) {
$this->parametres['retour.format'] = 'min';
}
if (isset($this->parametres['navigation.depart']) == false) {
$this->parametres['navigation.depart'] = 0;
}
if (isset($this->parametres['navigation.limite']) == false) {
$this->parametres['navigation.limite'] = 100;
}
}
 
public function obtenirPremiereImage() {
$this->parametres['navigation.depart'] = 0;
$this->parametres['navigation.limite'] = 1;
$images = $this->obtenirImages();
if (!is_array($images) || count($images) <= 0) {
$message = "Aucune image ne correspond au numéro numenclatural $refTax:$numNom";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
} else {
return $images[0];
}
}
 
public function obtenirImages() {
//TODO: tri par date, mais les dates dans la bdd photoflora sont des chaines en entités HTML
// donc un tri dessus n'a pas de sens
$requete = 'SELECT photos.*, taxons.NumTaxon, taxons.NumNomen, taxons.Combinaison, photographes.Nom, '.
' photographes.Prenom, photographes.Initiales, photographes.Mail '.
'FROM '.self::BDD_PF.'.photos, '.self::BDD_PF.'.photographes, '.self::BDD_PF.'.taxons '.
'WHERE '.
'photos.Auteur = photographes.ID '.
'AND photos.NumTaxon = taxons.NumTaxon '.
$this->construireWhereNumNom().' '.
$this->construireWhereNumTax().' '.
$this->construireWhereNomSci().' '.
$this->construireWhereAuteur().' '.
'ORDER BY photos.support LIMIT '.$this->parametres['navigation.depart'].','.$this->parametres['navigation.limite'];
$resultat = $this->Bdd->recupererTous($requete);
return $resultat;
}
 
private function construireWhereNumNom() {
return (isset($this->parametres['masque.nn'])) ? 'AND taxons.NumNomen = '.$this->Bdd->proteger($this->parametres['masque.nn']).' ' : '';
}
 
private function construireWhereNumTax() {
return (isset($this->parametres['masque.nt'])) ? 'AND taxons.NumTaxon = '.$this->Bdd->proteger($this->parametres['masque.nt']).' ' : '';
}
 
private function construireWhereNomSci() {
return (isset($this->parametres['masque.ns'])) ? 'AND taxons.Combinaison LIKE '.$this->Bdd->proteger($this->parametres['masque.ns'].'%').' ' : '';
}
 
private function construireWhereAuteur() {
$requete_auteur = '';
if (isset($this->parametres['masque.auteur'])) {
$auteur_like = $this->Bdd->proteger($this->parametres['masque.auteur'].'%');
$requete_auteur = 'AND photos.auteur = '.
'(SELECT id FROM '.self::BDD_PF.'.photographes '.
'WHERE '.
'Nom LIKE '.$auteur_like.' OR '.
'Prenom LIKE '.$auteur_like.' OR '.
'Initiales LIKE '.$auteur_like.' OR '.
'Mail LIKE '.$auteur_like.') ';
}
return $requete_auteur;
}
 
private function formaterRetourImageBinaire($photo) {
$image = '';
$chemin = $url = $this->getUrlPhotoPourInitiales($photo['Initiales'], $photo['NumPhoto'], $this->format);
$image = file_get_contents($chemin);
if ($image === false) {
$message = "L'image demandée est introuvable sur le serveur : $chemin";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $image;
}
 
private function formaterRetourJson($photographies) {
$resultat = array();
if (is_array($photographies)) {
foreach ($photographies as $photo) {
$image = array();
$url = $this->getUrlPhotoPourInitiales($photo['Initiales'], $photo['NumPhoto'], $this->format);
$urlmax = $this->getUrlPhotoPourInitiales($photo['Initiales'], $photo['NumPhoto'], 'max');
$id = str_replace(array('.jpg','.jpeg', '.png'), '', $photo['NumPhoto']);
 
// Post-traitement des valeurs
$image['date'] = $this->donnerDate($this->formaterChaineEncodeeBddPhotoflora($photo['Date']));
$image['mime'] = $this->extraireMime($photo['NumPhoto']);
$image['auteur.libelle'] = $this->formaterChaineEncodeeBddPhotoflora($photo['Prenom'].' '.$photo['Nom']);
$image['binaire.href'] = $url;
$image['binaire.hrefmax'] = $urlmax;
$image['determination.libelle'] = $photo['Combinaison'].' ['.$photo['Prenom'].' '.$photo['Nom'].']';
$image['determination.nom_sci.libelle'] = $photo['Combinaison'];
$image['determination.nom_sci.code'] = "bdtfx.".$photo['NumNomen'];
$image['station.libelle'] = $this->formaterStation($photo['lieu']);
 
$resultat[$id] = $image;
}
}
return $resultat;
}
 
private function extraireMime($fichierImg) {
$mime = '';
if (strpos($fichierImg, '.jpg') || strpos($fichierImg, '.jpeg')) {
$mime = self::MIME_JPEG;
} else if (strpos($fichierImg, '.png')) {
$mime = self::MIME_PNG;
}
return $mime;
}
 
private function formaterStation($station) {
$station = $this->formaterChaineEncodeeBddPhotoflora($station);
$station = preg_replace('/^ : /', '', $station);
return $station;
}
 
private function callBackReplace($m) {
return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES");
}
 
private function formaterChaineEncodeeBddPhotoflora($chaine) {
return $chaine = preg_replace_callback("/(&#[0-9]+;)/", array($this, 'callBackReplace'), $chaine);
}
 
// TODO: garder ancien web service pour retour xml ou bien fusionner les deux ?
private function formaterRetourXml($photographies) {
// Formatage du xml
$xml = '<?xml version="1.0" encoding="utf-8"?>'."\n";
$xml .= '<rdf:RDF'."\n";
$xml .= ' xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"'."\n";
$xml .= ' xmlns:dc="http://purl.org/dc/elements/1.1/"'."\n";
$xml .= ' xmlns:dcterms="http://purl.org/dc/terms">'."\n";
foreach ($photographies as $photo) {
 
$url = $this->getUrlPhotoPourInitiales($photo['Initiales'], $photo['NumPhoto'], $this->format);
 
// Post-traitement des valeurs
$photo['lieu'] = preg_replace('/^[ ]*:[ ]*/', '', $photo['lieu']);
 
// Gestion du XML
$xml .= ' <rdf:Description about="'.$url.'"'."\n";
$xml .= ' dc:identifier="'.preg_replace('/\.\w+$/', '', $photo['NumPhoto']).'"'."\n";
$xml .= ' dc:title="'.$photo['Combinaison'].'"'."\n";
$xml .= ' dc:description="'.$photo['Objet'].'"'."\n";
$xml .= ' dc:creator="'.$photo['Prenom'].' '.$photo['Nom'].'"'."\n";
// $xml .= ' dc:contributor="Daniel MATHIEU (Détermination)"'."\n";
$xml .= ' dc:publisher="Photoflora"'."\n";
$xml .= ' dc:type="'.$this->donnerTxtSupport($photo['Support']).'"'."\n";
$xml .= ' dc:format="'.$this->donnerTypeMime($photo['NumPhoto']).'"'."\n";
$xml .= ' dcterms:spatial="'.$photo['lieu'].'"'."\n";
$xml .= ' dcterms:created="'.$photo['Date'].'"'."\n";
// $xml .= ' dcterms:dateSubmitted="2006-10-18 08:32:00"'."\n";
$xml .= ' dcterms:licence="Utilisation des photos non autorisée sans accord avec le gestionnaire du site et sous certaines conditions - Tous droits réservés - All rights reserved"/>'."\n";
}
$xml .= '</rdf:RDF>'."\n";
 
return $xml;
}
 
private function getUrlPhotoPourInitiales($initiales, $num_photo, $format) {
// Gestion des urls des photos
$url = '';
if ($initiales == 'bb') {
$base_url = ($format == 'max') ? $this->efph_url_photo_bb : $this->efph_url_photo_bb_min;
$url = sprintf($base_url, $num_photo);
} else if ($initiales == 'jlt') {
$base_url = ($format == 'max') ? $this->efph_url_photo_jlt : $this->efph_url_photo_jlt_min;
$url = sprintf($base_url, $num_photo);
} else {
$base_url = ($format == 'max') ? $this->efph_url_photo : $this->efph_url_photo_min;
$url = sprintf($base_url, $initiales, $num_photo);
}
 
return $url;
}
 
private function getResultatTest() {
$photographies = array();
$photographies[] = array('Initiales' => 'bb',
'NumPhoto' => 'bb047230.jpg',
'NumNomen' => '182',
'lieu' => 'Ristolas - Hautes Alpes (05) [France]',
'Combinaison' => '',
'Objet' => 'Vue générale, en fleur cv Musik - Canon EOS 350D DIGITAL - Expo : 1/160 sec. - Ouv. : f8 - ISO : 100 - flash : non - foc. : 60 - pix. : 8 Mp.',
'Prenom' => 'Benoit',
'Nom' => 'BOCK',
'Support' => 'Photographie numérique',
'Date' => 'Mai 2006');
 
return $photographies;
}
 
/**
* Fonction remplaçant les caractères posant problème dans le xml
*
* @param string le texte à nettoyer
* @return string le texte nettoyé
*/
function nettoyerXml($xml) {
// Remplacement des esperluettes
$xml = str_replace(' & ', ' &#38; ', $xml);
// Remplacement du caractère spécial de fin de ligne : VT
$xml = preg_replace('/ /', "\n", $xml);
return $xml;
}
 
/**
* Fonction fournissant les intitulés des types de support des images
*
* @param integer identifiant du support
* @return string le texte correspondant au type de support
*/
function donnerTxtSupport($support) {
switch ($support) {
case '0':
$support = 'Photographie num&#233;rique (6 mégapixels)';
break;
case '1':
$support = 'Diapositive';
break;
case '10':
$support = 'Scan de la flore de Coste';
break;
case '11':
$support = 'Scan de plante fraiche';
break;
default:
$support = 'Erreur code support : pr&#233;venir eflore_remarques@tela-botanica.org';
}
return $support;
}
 
/**
* Fonction fournissant les types MIME des fichiers images
*
* @param string le nom du fichier
* @return string le texte du type MIME du fichier
*/
function donnerTypeMime($fichier) {
if (preg_match('/\.(\w+)$/', $fichier, $match)) {
switch (strtolower($match[1])) {
case 'jpeg':
case 'jpg':
$type = 'image/jpeg';
break;
case 'png':
$type = 'image/png';
break;
default:
$type = 'Erreur Mime : prévenir eflore_remarques@tela-botanica.org';
}
} else {
$type = 'Erreur Mime : prévenir eflore_remarques@tela-botanica.org';
}
return $type;
}
 
/**
* Fonction fournissant une date au format Mysql
*
* @param string la date composé du nom du mois en français et de l'année sous 4 chiffres
* @return string la date dans le format Mysql
*/
function donnerDate($chaine) {
if (preg_match('/^(\w+) (\d{4})$/',$chaine, $match)) {
$mois = $match[1];
$annee = $match[2];
switch (strtolower($mois)) {
case 'janvier' :
$mois_sortie = '01';
break;
case 'février' :
$mois_sortie = '02';
break;
case 'mars' :
$mois_sortie = '03';
break;
case 'avril' :
$mois_sortie = '04';
break;
case 'mai' :
$mois_sortie = '05';
break;
case 'juin' :
$mois_sortie = '06';
break;
case 'juillet' :
$mois_sortie = '07';
break;
case 'aout' :
case 'août' :
$mois_sortie = '08';
break;
case 'septembre' :
$mois_sortie = '09';
break;
case 'octobre' :
$mois_sortie = '10';
break;
case 'novembre' :
$mois_sortie = '11';
break;
case 'decembre' :
$mois_sortie = '12';
break;
}
return $annee.'-'.$mois_sortie.'-01 01:01:01';
} else {
return '1970-01-01 01:01:01';
}
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/nvjfl/NomsVernaculaires.php
New file
0,0 → 1,922
<?php
/**
* Description :
* Classe NomsVernaculaires.php fournit une liste de noms vernaculaires et leur liaison à la bdtfx
* 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 langue et
* une relation avec un taxon de la bdtfx.
* Si l'url finit par /noms-vernaculaires on retourne une liste de noms (seulement les 100 premières par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /observations?param1=val1&param2=val2&...
*
* ATTENTION : /attributions groupe par taxon, le nombre de résultats est donc
* inférieur ou égal au nombre demandé par navigation.limite
*
* Les paramètres de requête disponibles sont : masque, masque.code, masque.nom, masque.region , recherche,
* distinct, retour.format, navigation.depart et navigation.limite.
*
* Encodage en entrée : utf8
* Encodage en sortie : utf8
* @package framework-v3
* @author Delphine Cauquil <delphine@tela-botanica.org>
* @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)
*/
 
// Un caractère de concaténation entre le projet et le service.
// Ce caractère ne doit pas faire partie d'aucun des noms de service ou projet
define('RES_VAL_SEP', '@');
define('SPE_INDEX_NVJFL', '_result_ontologies' . RES_VAL_SEP . 'nvjfl');
 
class NomsVernaculaires extends Commun {
 
static $onto_multi_support = array('conseil_emploi', 'genre');
static $champ_infos = array(
'taxon' => array('service' => 'taxons', 'ressource' => 'nt:', 'projet' => 'bdtfx', 'nom' => 'nom_sci',
// utilisés par ajouterChampsOntologieLigneResultat()
'intitule' => 'taxon.code', // intitulé du champ tel qu'il sera renvoyé en JSON
'bdd_champ' => 'num_taxon'), // intitulé du champ tel qu'il est présent dans l'enregistrement MySQL
'conseil_emploi' => array('service' => 'ontologies', 'ressource' => 'numStatut:', 'projet' => 'nvjfl', 'nom' => 'nom',
'intitule' => 'conseil_emploi', 'bdd_champ' => 'num_statut'),
'genre' => array('service' => 'ontologies', 'ressource' => 'genreNombre:', 'projet' => 'nvjfl', 'nom' => 'nom',
'intitule' => 'genre', 'bdd_champ' => 'num_genre'));
 
protected $service = 'noms-vernaculaires';
 
/**
* Permet de stocker la requete formulée : /noms-vernaculaires | /noms-vernaculaires/#id |
* /noms-vernaculaires/#id/champ | /noms-vernaculaires/#id/relations
* Est remplit au cours de l'analyse des ressources (traiterRessources()), par défaut, a la valeur du service.
* Est utilisée principalement pr déterminer le format du tableau à retourner. */
protected $format_reponse = 'noms-vernaculaires';
 
/** Variables constituant les parametres de la requete SQL (champ, condition, limit) remplie
* selon ressources et paramètres */
protected $requete_champ = array('*');
protected $requete_condition = '';
protected $limite_requete = array(
'depart' => 0,
'limite' => 100
);
 
/**
* Vrai tri SQL
*/
protected $tri;
protected $tri_ordre = 'asc';
 
// wtf ? on trie après avoir exécuté la requête ?
protected $champ_tri = 'code_langue';
protected $direction_tri = 'asc';
 
/**
* Indique les champs supplémentaires à retourner
* - conseil_emploi = conseil d'emploi du nom vernaculaire
* - genre = genre et nombre du nom
* - taxon = nom retenu associé à ce nom
*/
protected $champs_supp = array();
 
/**
* Precise la contenance plus ou moins précise du tableau à retourner :
* - min = les données présentes dans la table
* - max = les données de la table + les informations complémentaires (pour les identifiants et les codes)
* - oss = la liste des nom_sci (uniquement pour noms et taxons) */
protected $retour_format = 'max';
/** Valeur du paramètre de requete recherche :
* - stricte : le masque est passé tel quel à l'opérateur LIKE.
* - etendue : ajout automatique du signe % à la place des espaces et en fin de masque avec utilisation de LIKE.
* - floue : recherche tolérante vis-à-vis d'approximations ou d'erreurs (fautes d'orthographe par exemple) */
protected $recherche;
 
/** Permet de stocker le tableau de résultat (non encodé en json) */
protected $table_retour = array();
/** 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 $config;
 
public function __construct($config) {
$this->config = is_null($config) ? Config::get('NomsVernaculaires') : $config;
}
 
//+------------------------------------------------------------------------------------------------------+
// créer une condition en fonction du paramétre
public function traiterParametres() {
if (isset($this->parametres) && !empty($this->parametres)) {
 
if (isset($this->parametres['recherche']) && $this->parametres['recherche'] != '') {
$this->recherche = $this->parametres['recherche'];
}
foreach ($this->parametres as $param => $valeur) {
switch ($param) {
case 'masque' :
$this->ajouterFiltreMasque('nom_vernaculaire', $valeur);
break;
case 'masque.nt' :
$this->ajouterFiltreMasque('num_taxon', $valeur);
break;
case 'masque.nv' :
$this->ajouterFiltreMasque('nom_vernaculaire', $valeur);
break;
case 'masque.lg' :
$this->ajouterFiltreMasque('code_langue', $valeur);
break;
case 'masque.cce' :
$this->ajouterFiltreMasque('num_statut', $valeur);
break;
case 'retour.format' :
$this->retour_format = $valeur;
break;
case 'retour.tri' :
$this->tri = $valeur;
break;
case 'retour.ordre' :
if (in_array(strtolower($valeur), aray('asc', 'desc'))) {
$this->tri_ordre = $valeur;
}
break;
case 'navigation.depart' :
$this->limite_requete['depart'] = $valeur;
break;
case 'navigation.limite' :
$this->limite_requete['limite'] = $valeur;
break;
case 'retour.champs' :
$this->champs_supp = explode(',',$valeur);
break;
case 'recherche' :
break;
case 'version.projet' :
break;
default :
$p = '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, $p);
}
}
}
}
 
public function ajouterFiltreMasque($nom_champ, $valeur) {
if ($nom_champ == 'num_taxon') { // si il s'agit d'un chiffre
$this->requete_condition[] = $nom_champ.' = '.$this->getBdd()->proteger($valeur);
} else {
if ($this->recherche == 'floue') {
$this->requete_condition[] = '(SOUNDEX('.$nom_champ.') = SOUNDEX(\''.$valeur.'\')'
.' OR SOUNDEX(REVERSE('.$nom_champ.')) = SOUNDEX(REVERSE(\''.$valeur.'\'))) ';
} else {
if ($this->recherche == 'etendue') {
$valeur = '%'.str_replace(' ','% ', $valeur);
$valeur .= '%';
}
$this->requete_condition[] = $nom_champ.' LIKE '.$this->getBdd()->proteger($valeur);
}
}
}
 
//+------------------------------------------------------------------------------------------------------+
// en fonction de la présence des ressources modifie requete_champ et requete_condition
public function traiterRessources() {
if (isset($this->ressources) && !empty($this->ressources)) {
if (isset($this->ressources[0]) && !empty($this->ressources[0])) {
$this->traiterRessourceId(); // ajoute condition id=#valeur
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
$this->traiterRessourceChamp(); //modifie requete_champ ou requete_condition
}
}
} else { //rajoute distinct pour ne pas avoir plusieurs fois le même nom
$this->requete_champ = array('distinct(id)', 'nom_vernaculaire ');
$this->requete_champ = array_merge($this->requete_champ, $this->champs_supp);
}
}
 
//requete : /noms-vernaculaires/#id (ex : /noms-vernaculaires/7)
public function traiterRessourceId() {
if (is_numeric($this->ressources[0])) {
$this->requete_condition[] = ' id = '.$this->getBdd()->proteger($this->ressources[0]);
$this->format_reponse .= '/id';
} elseif ($this->ressources[0] == 'attributions') {
$this->format_reponse .= '/attributions';
} else {
$r = 'Erreur dans les ressources de votre requête : </br> La ressource " '.$this->ressources[0].
' " n\'existe pas.';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r);
}
}
 
 
public function traiterRessourceChamp() {
$this->format_reponse .= '/champ';
$this->analyserChamp();
}
 
public function analyserChamp() {
$this->recupererTableConfig('champs_possibles');// s'il y a plusieurs champs correspondant au champ demandé ils sont séparé par des |
$champs = explode(' ', $this->ressources[1]);
//$this->requete_champ = array(); // * car absence de mappings
foreach ($champs as $champ) {
preg_match('/^([^.]+)(\.([^.]+))?$/', $champ, $match);
if (isset($this->champs_possibles[$match[1]])) {
// wtf?
//$this->requete_champ[] = str_replace('|', ', ', $this->champs_possibles[$match[1]]);
// marche pas, pour chaque champ il faut en retourner un qui a un
// autre nom etc. , pas le temps de faire des mappings
$this->requete_champ[] = $match[1];
} elseif (isset($this->champs_possibles[$match[0]])) {
// wtf ?
$this->requete_champ[] = str_replace('|', ', ', $this->champs_possibles[$match[0]]);
} else {
$champs_possibles = implode('</li><li>', array_keys($this->champs_possibles));
$c = 'Erreur dans votre requête : </br> Le champ "'.$champ_possibles.'" n\'existe pas. '.
'Les champs disponibles sont : <li>'.$champs_possibles.'</li> et leurs déclinaisons (ex. ".code").';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $c);
}
}
}
 
// fait du neuf avec du vieux
public function assemblerLaRequete() {
$requete = false;
if ($this->format_reponse == 'noms-vernaculaires') {
// mode liste
$requete = $this->assemblerRequeteListe();
} else {
$requete = $this->assemblerRequeteAutre();
}
return $requete;
}
 
/**
* Exécute un astucieux GROUP BY afin que le service retourne ce qu'il
* annonce qu'il retourne (truc de ouf!) - pour le mode "liste"
*/
protected function assemblerRequeteListe() {
$count = $this->recupererTotalResultat();
$limiteClause = self::formerRequeteLimite( // LIMIT
$this->limite_requete['depart'],
$count,
$this->limite_requete['limite']
);
$req = sprintf(
'SELECT %s, group_concat(num_taxon) as num_taxon, IF(num_statut="",1,0) AS is_null' .
' FROM %s WHERE %s GROUP BY id ORDER BY %s is_null ASC, num_statut ASC %s -- %s:%d',
 
in_array('*', $this->requete_champ) ? ' * ' : implode(', ', $this->requete_champ),
$this->table,
$this->requete_condition ? implode(' AND ', $this->requete_condition) : 'TRUE',
$this->tri ? ($this->tri . ' ' . $this->tri_ordre . ', ') : '',
$limiteClause,
__FILE__, __LINE__);
return $req;
}
 
/**
* Ancien système d'assemblage de requête
*/
protected function assemblerRequeteAutre() {
$nolimit = in_array(
$this->format_reponse,
array($this->service.'/id', $this->service.'/id/champs'));
if(!$nolimit) {
$count = $this->recupererTotalResultat();
$limiteClause = self::formerRequeteLimite( // LIMIT
$this->limite_requete['depart'],
$count,
$this->limite_requete['limite']);
}
$req = sprintf(
'SELECT %s, IF(num_statut="",1,0) AS is_null' .
' FROM %s WHERE %s ORDER BY %s is_null ASC, num_statut ASC %s -- %s:%d',
 
in_array('*', $this->requete_champ) ? ' * ' : implode(', ', $this->requete_champ),
$this->table,
$this->requete_condition ? implode(' AND ', $this->requete_condition) : 'TRUE',
$this->tri ? ($this->tri . ' ' . $this->tri_ordre . ', ') : '',
$nolimit ? '' : $limiteClause,
__FILE__, __LINE__);
return $req;
}
 
//ajout d'une limite seulement pour les listes (pas plus de 100 resultats retournés pr les requetes
// suivantes : /noms-vernaculaires et /noms-vernaculaires/#id/relations)
static function formerRequeteLimite(&$depart, $total, $limite) {
if ($depart > $total) {
$depart = $total - $limite < 0 ? 0 : ($total - $limite);
return ' LIMIT ' . $depart . ', ' . $limite;
}
return ' LIMIT ' . $depart . ', ' . $limite;
}
 
//on récupère le nombre total de résultats de la requete (ex : le nombre d'id contenu dans la liste /noms-vernaculaires)
public function recupererTotalResultat() {
$res = $this->getBdd()->recuperer(sprintf(
'SELECT COUNT(%s) AS nombre FROM %s WHERE %s -- %s:%d',
$this->format_reponse == 'noms-vernaculaires/attributions' ? 'id' : 'distinct(id)',
$this->table,
$this->requete_condition ? implode(' AND ', $this->requete_condition) : 'TRUE',
__FILE__, __LINE__));
 
if (! $res)
throw new Exception('Données introuvables', RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
if($res['nombre'] == 0) {
print json_encode(
array(
"entete" => array(
"depart" => $this->limite_requete['depart'],
"limite" => $this->limite_requete['limite'],
"masque" => $this->recupererMasque(),
"total" => 0
),
"resultat" => array()
));
die; // die() très dommage (pour phpunit), mais la stack d'imbrication ne nous permet pas de retourner proprement
}
 
$this->total_resultat = $res['nombre'];
return $res['nombre'];
}
 
//+------------------------------------------------------------------------------------------------------+
// determine en fct du service appelé (/noms-vernaculaires | /noms-vernaculaires/#id | /noms-vernaculaires/#id/champ |
// /noms-vernaculaires/#id/relations) le format du tableau à retourner.
public function retournerResultatFormate($resultat) {
$this->recupererTableConfig('correspondance_champs');
switch ($this->format_reponse) {
case 'noms-vernaculaires' :
$reponse = ($this->retour_format == 'oss') ? $this->formaterEnOss($resultat) : $this->formaterNomsVernaculaires($resultat); break;
case 'noms-vernaculaires/attributions' : $reponse = $this->formaterNomsVernaculairesAttributions($resultat); break;
case 'noms-vernaculaires/id' : $reponse = $this->formaterNomsVernaculairesId($resultat); break;
case 'noms-vernaculaires/id/champ' : $reponse = $this->formaterNomsVernaculairesIdChamp($resultat); break;
default : break;
}
return $reponse;
}
public function ajouterJsonEnTeteNV() {
$table_retour_json['masque'] = $this->recupererMasque();
$table_retour_json['depart'] = $this->limite_requete['depart'];
$table_retour_json['limite'] = $this->limite_requete['limite'];
$table_retour_json['total'] = $this->total_resultat;
$url = $this->formulerUrl($this->total_resultat, '/noms-vernaculaires');
if (isset($url['precedent']) && $url['precedent'] != '') {
$table_retour_json['href.precedent'] = $url['precedent'];
}
if (isset($url['suivant']) && $url['suivant'] != '') {
$table_retour_json['href.suivant'] = $url['suivant'];
}
return $table_retour_json;
}
 
/**
* @TODO Ne devrait pas retourner un oblet mais un Array (conserve l'ordre,
* évite d'écraser des clefs etc.)
*/
public function ajouterJsonResultatNV($resultat) {
$resultat_json = array();
foreach ($resultat as $tab) {
$this->table_retour = array();
foreach ($tab as $key => $valeur) {
if ($valeur != '') {
switch ($key) {
case 'id' : $num = $valeur; break;
case 'nom_vernaculaire' : $this->table_retour['nom'] = $valeur; break;
default : break;
}
// champs supplémentaires
if (in_array($key, $this->champs_supp)) {
$this->table_retour[$key] = $valeur;
}
}
}
if ($this->retour_format == 'max') $this->table_retour['href'] = $this->ajouterHref('noms-vernaculaires', $num);
$resultat_json[$num] = $this->table_retour;
}
return $resultat_json;
}
 
public function formaterNomsVernaculaires($resultat) {
$table_retour_json['entete'] = $this->ajouterJsonEnTeteNV();
$resultat = $this->hierarchiserResultat($resultat);
$table_retour_json['resultat'] = $this->ajouterJsonResultatNV($resultat);
return $table_retour_json;
}
public function hierarchiserResultat($resultat) {
//tri recherche floue
if (isset($this->parametres['masque.nv'])) {
return $this->trierRechercheFloue($this->parametres['masque.nv'], $resultat, 'nom_vernaculaire');
}
if (isset($this->parametres['masque'])) {
return $this->trierRechercheFloue($this->parametres['masque'], $resultat, 'nom_vernaculaire');
}
return $resultat;
}
public function recupererMasque() {
$tab_masque = array();
foreach ($this->parametres as $param=>$valeur) {
if (strstr($param, 'masque') != false) {
$tab_masque[] = $param.'='.$valeur;
}
}
return implode('&', $tab_masque);
}
public function formaterEnOss($resultat) {
$table_nom = array();
$oss = '';
foreach ($resultat as $tab) {
if (isset($tab['nom_vernaculaire']) ) {
if (!in_array($tab['nom_vernaculaire'], $table_nom)) {
$table_nom[] = $tab['nom_vernaculaire'];
$oss [] = $tab['nom_vernaculaire'];
}
}
}
if (isset($this->masque)) $masque = implode('&', $this->masque);
else $masque = 'Pas de masque';
return array($masque, $oss);
}
public function formaterNomsVernaculairesAttributions($resultat) {
//on remplie la table $table_retour_json['entete']
$table_retour_json['entete']['masque'] = $this->recupererMasque();
$table_retour_json['entete']['depart'] = $this->limite_requete['depart'];
$table_retour_json['entete']['limite'] = $this->limite_requete['limite'];
$table_retour_json['entete']['total'] = $this->total_resultat;
$url = $this->formulerUrl($this->total_resultat, '/noms-vernaculaires/attributions');
if (!empty($url['precedent'])) {
$table_retour_json['entete']['href.precedent'] = $url['precedent'];
}
if (!empty($url['suivant'])) {
$table_retour_json['entete']['href.suivant'] = $url['suivant'];
}
$resultat_json = array();
foreach ($resultat as &$tab) {
$nnv = $tab['num_nom_vernaculaire'];
$resultat_json[$nnv]['id'] = $tab['id'];
$resultat_json[$nnv]['nom_vernaculaire'] = $tab['nom_vernaculaire'];
$resultat_json[$nnv]['langue.code'] = $resultat_json[$nnv]['code_langue'] = $tab['code_langue'];
$resultat_json[$nnv]['taxon.code'] = 'bdtfx.nt:'.$tab['num_taxon'];
if ($this->retour_format == 'max') {
$this->taxons[] = $tab['num_taxon']; // utilisé pour chercher les noms latins plus bas
if($this->champs_supp) {
//$resultat_json[$nnv] = $this->ajouterChampsOntologieLigneResultat($tab);
// simple initialisation par copie de la référence de l'original
$resultat_json[$nnv] = &$tab;
} else {
$resultat_json[$nnv]['num_taxon'] = $tab['num_taxon'];
$resultat_json[$nnv]['nom_retenu.code'] = $tab['num_taxon'];
$resultat_json[$nnv]['taxon'] = $tab['num_taxon'];
$resultat_json[$nnv]['href'] = $this->ajouterHref('noms-vernaculaires', $tab['id']);
}
}
}
 
// dans ce cas (particulier?) nous n'avons pour l'heure initialisé qu'une référence
// vers le tableau de valeurs original
if ($this->retour_format == 'max' && $this->champs_supp) {
// récupérons désormais les ontologies
$this->ajouterChampsOntologieLigneTousResultats($resultat_json);
}
 
if ($this->retour_format == 'max') {
// Deuxième boucle pour demander tous lestaxons présents en une
// fois et les attribuer aux noms car c'est beaucoup plus rapide
$noms_sci = $this->recupererNomTaxons();
foreach ($resultat_json as $num_nom => &$tab) {
$tab = $this->ajouterTaxonsAttributionsLigneResultat($tab, $noms_sci);
if($tab == null) {
unset($resultat_json[$num_nom]);
}
}
}
$table_retour_json['resultat'] = $resultat_json;
return $table_retour_json;
}
/**
* Ajoute les champs d'ontologie supplémentaires si necéssaire
* en faisant appels aux web services associés.
* Les appels peuvent être fait individuellement (pour un couple <ontologie:valeur>) ou bien
* regroupés, **si le webservice correspondant le supporte**.
*
* Nous disposons à ce jour de 3 (trois) webservices d'ontologies correspondant aux noms vernaculaires (cf $champ_infos)
* Mais 2 d'entre eux sont identiques, il s'agit de /nvjfl/ontologies/. Or ce webservice supporte le multi-critère.
* Nous pouvons donc factorisé l'appel pour "conseil_emploi" et "genre", mais pas pour "taxon".
*
* @param array in/out $resultats: tous les résultats
*/
public function ajouterChampsOntologieLigneTousResultats(&$resultats) {
$champs_sup = array_intersect($this->champs_supp, array_keys(self::$champ_infos));
 
// La regroupement des toutes les valeurs recherchées (pour tous les
// résultats), pour "les" onotologies supportant le multi-critère est effectué ci-dessous.
// Dans les faits ce n'est le cas que pour nvjfl.
$ontologieParamPending = self::NvjflOntologieIndex($resultats, $champs_sup);
$this->NvjflOntologieExpand($ontologieParamPending);
self::NvjflOntologieCombine($resultats);
 
// pour les ontologies multi-critères, on vient de le régler ci-dessus
$champs_sup = array_diff($champs_sup, self::$onto_multi_support);
 
 
// ici, $champs_sup ne peut contenir, au plus, que "taxon".
// code historique:
foreach($champs_sup as $cle) {
$champs_supplementaires = self::$champ_infos[$cle];
// extrait, depuis un élément de $champ_infos:
// $service, $ressource, $projet, $nom, $intitule, $bdd_champ
extract($champs_supplementaires);
 
foreach ($resultats as &$tab) {
$valeur_recherche = $tab[$bdd_champ];
if(!trim($valeur_recherche)) continue;
 
$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur_recherche, $projet);
$tab[$intitule] = $this->chercherSignificationCode($url, $nom);
}
}
}
 
/* Récupère les valeurs recherchées pour une liste de résultats, (plus ou moins)
spécifiquement au service d'Ontologies de NVJFL.
Aggrège les valeurs dans le tableau retourné.
Une référence vers l'index du tableau (NULL pour l'instant) est laissée dans
un élément du résultat. */
static function NvjflOntologieIndex(&$resultats, $champs_sup) {
// nous ne supportons le multi-critère que sur les ontologies nvjfl, et nous
// avons précisé celles qui sont concernées dans self::$onto_multi_support
$champs_sup = array_intersect($champs_sup, self::$onto_multi_support);
$ontologieParamPending = Array();
foreach($resultats as &$resultat) {
foreach($champs_sup as $v) {
// de cet extract() nous n'utilisons que $bdd_champ et $ressource
extract(self::$champ_infos[$v]);
if(!isset($resultat[$bdd_champ])) continue;
 
$valeur_recherche = $resultat[$bdd_champ];
if(!trim($valeur_recherche)) continue;
 
// XXX: $ressource contient déjà ':' comme suffixe
$critere = $ressource . $valeur_recherche;
$ontologieParamPending[$critere] = NULL;
// placeholder pour le résultat
$resultat[SPE_INDEX_NVJFL][$v][$critere] =
&$ontologieParamPending[$critere];
}
}
return $ontologieParamPending;
}
 
// TODO: switch to static si il peut en être de même pour ajouterHrefAutreProjet()
/* À partir d'un aggrégat des critère de requêtes d'ontologies, spécifiques à NVJFL,
créé une URL multi-critère.
Celle-ci, dans ce cas précis, n'est que la concaténation, par des virgules,
des couples <ressource:ValeurRecherchée>.
L'URL est appelée et la valeur correspondante est remplacée dans $criteres_requete.
 
Note: dans le cadre du tryptique index/expand/combine pour lequel cette fonction existe,
la valeur est référencée par un élément d'une ou plusieurs lignes de $resultat correspondantes.
Celle(s)-ci sera[ont] donc changée(s) dans la foulée. */
public function NvjflOntologieExpand(&$criteres_requete) {
// équivalent spécifique de ajouterHrefAutreProjet()
$valeurs_requises = implode(',', array_keys($criteres_requete));
// en vérité, nous ne supportons ceci ici que pour nvjfl et non n'importe quel url_service
$url = Config::get('url_service').'/ontologies/'.$valeurs_requises;
$val = $this->consulterHref($url);
 
// TODO, le webservice d'ontologies devrait être modifié pour retourner un tableau
// indexé par critère requesté à *CHAQUE* fois, y compris lorsque 1 seul critère est
// demandé.
if(array_key_exists('id', $val) && count($criteres_requete) == 1) {
$k = key($criteres_requete);
$criteres_requete[$k] = $val;
return;
}
 
// subtilité, cette affectation modifie par conséquent les valeurs dans
// $resultats[X][SPE_INDEX_NVJFL]
// dont la référence pointe toujours sur $v
foreach($val as $k => $v) $criteres_requete[$k] = $val->$k;
}
 
/* Fonction finale du tryptique: réordonne les valeurs obtenues auprès du web-service
NVJFL en adéquation avec les champs attendus en sortie.
Dès l'indexation des critères, nous avons associé une (ou plusieurs) référence(s) du
tableau de résultats vers le tableau de retour des ontologies à l'aide d'un index
particulier l'index SPE_INDEX_NVJFL qui contient comme élément(s)
un ou plusieurs ontologies (les indexes de self::$champ_infos) qui elles-mêmes contiennent
une ou plusieurs valeurs représentant les valeurs recherchées appartement à cette ontologies.
Celui-ci est supprimé après avoir été correctement copié. */
/**
* @param array in/out $resultats: tous les résultats
* @param array in $critere: tableau des ontologies:valeur demandées, de la forme [ numStatut:1, genreNombre:11, ... ]
*/
static function NvjflOntologieCombine(&$resultats) {
foreach($resultats as &$resultat) {
if(!array_key_exists(SPE_INDEX_NVJFL, $resultat)) continue;
 
/* Note: la complétude d'un résultat peut dépendre de plusieurs ontologies différentes,
d'où cette boucle. Cependant une seule valeur sera demandé pour cette ontologie, c'est pourquoi
$resultat[SPE_INDEX_NVJFL][$onto_name], s'il existe, ne contiendra toujours qu'un seul élément.
Puisque par définition un résultat contenant des valeurs d'ontologie n'aura jamais qu'un seul et unique
attribut num_genre (ou num_statut, ou autre) */
foreach(self::$onto_multi_support as $onto_name) {
if(!array_key_exists($onto_name, $resultat[SPE_INDEX_NVJFL])) continue;
 
/* $onto_name est un nom d'ontologie (l'une des clefs, parmi conseil_emploi et genre,
cf la boucle sur $champs_sup dans NvjflOntologieIndex()
de cet extract() nous n'utilisons que $intitule et $nom */
extract(self::$champ_infos[$onto_name]);
 
// equivalent de l'affectation finale de chercherSignificationCode()
// (utilisé lors de recherches d'ontologies en mono-critère)
// XXX: PHP-5.3 pas de récupération d'attribut sur fonction
$r = current($resultat[SPE_INDEX_NVJFL][$onto_name]);
$resultat[$intitule] = $r->$nom;
 
// XXX: certes nous pourrions nous contenter du unset() final
unset($resultat[SPE_INDEX_NVJFL][$onto_name]);
}
unset($resultat[SPE_INDEX_NVJFL]);
}
}
 
/**
* Ajoute les champs d'ontologie supplémentaires si necéssaire
* en faisant appels aux web services associés
* @param array $ligne_resultat
*
* @return array la ligne modifiée
*/
public function ajouterChampsOntologieLigneResultat($ligne_resultat) {
foreach(self::$champ_infos as $cle => $champs_supplementaires) {
if(!in_array($cle, $this->champs_supp)) continue;
// extrait, depuis un élément de $champ_infos:
// $service, $ressource, $projet, $nom, $intitule, $bdd_champ
extract($champs_supplementaires);
$valeur_recherche = $ligne_resultat[$bdd_champ];
if(!trim($valeur_recherche)) continue;
$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur_recherche, $projet);
$ligne_resultat[$intitule] = $this->chercherSignificationCode($url, $nom);
}
return $ligne_resultat;
}
/**
* Fonction qui ajoute les attributions à une ligne de résultats
*
* @param array $ligne_tableau_resultat
* @param array $nom_sci
*/
public function ajouterTaxonsAttributionsLigneResultat(&$ligne_tableau_resultat, &$noms_sci) {
if (isset($noms_sci[$ligne_tableau_resultat['num_taxon']])) {
$ligne_tableau_resultat['nom_retenu.code'] = $noms_sci[$ligne_tableau_resultat['num_taxon']]['id'];
$ligne_tableau_resultat['taxon'] = $noms_sci[$ligne_tableau_resultat['num_taxon']]['nom_sci'];
} else {
$ligne_tableau_resultat = null;
}
return $ligne_tableau_resultat;
}
private function trierLigneTableau($a, $b) {
$retour = 0;
if ($a[$this->champ_tri] == $b[$this->champ_tri]) {
$retour = 0;
}
if($this->champ_tri == 'code_langue') {
if ($a[$this->champ_tri] == 'fra' && $b[$this->champ_tri] != 'fra') {
$retour = ($this->direction_tri == 'asc') ? -1 : 1;
} else if ($a[$this->champ_tri] != 'fra' && $b[$this->champ_tri] == 'fra') {
$retour = ($this->direction_tri == 'asc') ? 1 : -1;
} else {
$retour = $this->comparerChaineSelonDirectionTri($a[$this->champ_tri], $b[$this->champ_tri]);
}
} else {
$retour = $this->comparerChaineSelonDirectionTri($a[$this->champ_tri], $b[$this->champ_tri]);
}
return $retour;
}
private function comparerChaineSelonDirectionTri($a, $b) {
if($this->direction_tri == 'asc') {
return ($a < $b) ? -1 : 1;
} else {
return ($a > $b) ? -1 : 1;
}
}
// formatage de la reponse /id ss la forme
// id, nom_vernaculaire, attributions
// langue
// num_nom (correspond à un taxon bdtfx)
public function formaterNomsVernaculairesId($resultat) {
foreach ($resultat as $taxon) { // pour chaque attribution à un taxon bdtfx
// on crée les variables qui serviront de clés et on les enléves du tableau
$num_nom = $taxon['num_nom_vernaculaire']; // unique pour un trinôme id, langue, taxon
unset($taxon['num_nom_vernaculaire']);
$langue = $taxon['code_langue'];
unset($taxon['code_langue']);
 
foreach ($this->correspondance_champs as $key => $correspondance) { // ordonne les infos pour affichage
if (isset($taxon[$key]) && $taxon[$key] != "") {
$this->afficherDonnees($correspondance, $taxon[$key], $langue, $num_nom);
}
}
foreach ($taxon as $key => $valeur) { // rajoute les champs non prévus dans l'api
if (!isset($this->correspondance_champs[$key]) && $valeur != "") {
$this->afficherDonnees($key, $valeur, $langue, $num_nom);
}
}
if ($this->retour_format == 'max') $this->chargerBiblio($num_nom, $langue);
}
if ($this->retour_format == 'max') $this->afficherTaxons(); // va chercher les noms de tous les taxons
unset($this->table_retour['href']);
return $this->table_retour;
}
 
public function afficherDonnees($champ, $valeur, $langue = '', $num_nom = '') {
if ($champ == 'id' || $champ == 'nom_vernaculaire') {
$this->table_retour[$champ] = $valeur;
} elseif (preg_match('/^(.*)\.code$/', $champ, $match)) {
switch ($match[1]) {
case 'taxon' : if ($this->retour_format == 'max') {$this->taxons[$num_nom] = $valeur;}
$this->afficherPointCode($match[1], $langue, $num_nom, $valeur); break;
case 'langue' : //$this->afficherPointCode($match[1], 'iso-639-3', 'langues', $valeur);
break;
case 'genre' : $this->afficherPointCode($match[1], $langue, $num_nom, $valeur); break;
case 'conseil_emploi' : $this->afficherPointCode($match[1], $langue, $num_nom, $valeur); break;
default : break;
}
 
} elseif ($langue != '') {
$this->table_retour['attributions'][$langue][$num_nom][$champ] = $valeur;
} else {
$this->table_retour[$champ] = $valeur;
}
}
 
public function afficherPointCode($nomChamp, $langue, $num_nom, $valeur) {
if (isset(self::$champ_infos[$nomChamp])) {
extract(self::$champ_infos[$nomChamp]);
}
 
if ($this->retour_format == 'max') {
$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur, $projet);
if ($service == 'taxons') {
$code_valeur = '';
$this->table_retour['attributions'][$langue][$num_nom]['nom_retenu.code'] = $code_valeur;
} else {
$code_valeur = $this->chercherSignificationCode($url, $nom);
}
if ($projet != '') $projet .= '.';
$this->table_retour['attributions'][$langue][$num_nom][$nomChamp] = $code_valeur;
$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.code'] = $projet.$ressource.$valeur;
$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.href'] = $url;
} else {
if ($projet != '') $projet .= '.';
$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.code'] = $projet.$ressource.$valeur;
}
}
 
public function chercherSignificationCode($url, $nom) {
if (isset($this->signification_code[$url])) {
$valeur = $this->signification_code[$url];
} else {
$res = $this->consulterHref($url);
$valeur = $res->$nom;
$this->signification_code[$url] = $valeur;
}
return $valeur;
}
 
/**
* Apparemment, regroupe les noms vernaculaires par taxons (élimine donc
* certains noms) - j'ai bon ?
*/
public function afficherTaxons() {
$resultat = $this->recupererNomTaxons();
foreach ($this->table_retour['attributions'] as $code_langue=>$langue) {
foreach ($langue as $num_nom=>$taxon) {
$num_tax = ltrim($taxon['taxon.code'], 'bdtfx.nt:');
if (isset($resultat[$num_tax])) {
$this->table_retour['attributions'][$code_langue][$num_nom]['nom_retenu.code'] = $resultat[$num_tax]['id'];
$this->table_retour['attributions'][$code_langue][$num_nom]['taxon'] = $resultat[$num_tax]['nom_sci'];
}
}
}
}
public function recupererNomTaxons() {
$taxons = array_unique($this->taxons);
// @TODO attention à la limite de taille de l'URL - faire un POST plutôt
$url = Config::get('url_service_base').'bdtfx/taxons?navigation.limite=500&ns.structure=au&masque.nt='.implode(',', $taxons);
$res = $this->consulterHref($url);
foreach ($res->resultat as $id => $taxon) {
$resultat[$taxon->num_taxonomique]['id'] = 'bdtfx.nn:'.$id;
$resultat[$taxon->num_taxonomique]['nom_sci'] = $taxon->nom_sci_complet;
}
return $resultat;
}
 
public function formaterNomsVernaculairesIdChamp($resultat) {
$this->table_retour['id'] = $this->ressources[0];
$champs = explode(' ', $this->ressources[1]);
if (in_array('attributions', $champs) != false) {
$this->formaterNomsVernaculairesId($resultat);
unset($this->table_retour['nom_vernaculaire']);
} else {
$champ_attributions = array('num_taxon', 'zone_usage', 'num_statut', 'num_genre', 'notes');
foreach ($resultat as $taxon) {
foreach ($taxon as $key=>$valeur) {
if ($key == 'code_langue' && in_array('langue', $champs) != false) {
$this->table_retour['attributions']['langue'][] = $valeur;
} elseif (in_array($key, $champ_attributions) != false) {
$this->afficherPoint($this->correspondance_champs[$key] , $valeur, $taxon['code_langue'], $taxon['num_nom_vernaculaire']);
} elseif (in_array($key, $champs) != false) {
$this->table_retour[$key] = $valeur;
}
}
if (in_array('biblio', $champs) != false) $this->chargerBiblio($taxon['num_nom_vernaculaire'], $taxon['code_langue']);
}
if (in_array('biblio', $champs) != false && array_search('biblio.num_ref', $this->table_retour) != false) $this->table_retour['biblio'] = null;
}
return $this->table_retour;
}
 
/**
* Quelqu'un sait-il ce que fait cette foutue fonction ? :-/
*/
public function afficherPoint($champ, $valeur, $langue, $num_nom) {
$aMatche = preg_match('/^(.*)\.code$/', $champ, $match);
if ($aMatche !== false && $aMatche !== 0) {
$champ = $match[1];
if (isset(self::$champ_infos[$champ])) {
extract(self::$champ_infos[$champ]);
$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur, $projet);
$projet .= '.';
}
 
$champs = explode(' ', $this->ressources[1]);
if (in_array($champ.'.*', $champs) !== false && isset($projet)) {
$this->table_retour['attributions'][$langue][$num_nom][$champ.'.code'] = $projet.$ressource.$valeur;
$this->table_retour['attributions'][$langue][$num_nom][$champ.'.href'] = $url;
}
if (in_array($champ.'.code', $champs) !== false && isset($projet)) {
$this->table_retour['attributions'][$langue][$num_nom][$champ.'.code'] = $projet.$ressource.$valeur;
}
if (in_array($champ.'.href', $champs) !== false && isset($projet)) {
$this->table_retour['attributions'][$langue][$num_nom][$champ.'.href'] = $url;
}
if (in_array($champ, $champs) !== false) {
if (isset($url)) {
$this->table_retour['attributions'][$langue][$num_nom][$champ] = $this->chercherSignificationCode($url, $nom);
} else {
$this->table_retour['attributions'][$langue][$champ] = $valeur;
}
}
}
}
 
public function afficherLangue($nomChamp, $projet, $service, $valeur, $ressource = '', $nom = 'nom') {
if ($this->retour_format == 'max') {
$this->table_retour['attributions'][$nomChamp] = $nom;
$this->table_retour['attributions'][$nomChamp.'.code'] = $projet.$ressource.$valeur;
$this->table_retour['attributions'][$nomChamp.'.href'] = $url;
} else {
$this->table_retour['attributions'][$nomChamp.'.code'] = $projet.$ressource.$valeur;
}
}
 
public function chargerBiblio($num_nom, $langue) {
list($table, $version) = explode('_v',$this->table);
$requete = "SELECT b.*, lb.notes FROM nvjfl_lien_biblio_v$version lb, nvjfl_biblio_v$version b ".
"WHERE b.num_ref = lb.num_ref AND lb.num_nom = '$num_nom' ;";
$resultat = $this->getBdd()->recupererTous($requete);
 
if ($resultat == '') { //cas ou la requete comporte des erreurs
$r = 'La requête SQL formée comporte une erreur !!';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $r);
Debug::printr($requete);
} elseif ($resultat) {
foreach ($resultat as $res) {
foreach ($res as $cle => $valeur) {
if ($valeur !== "") {
$this->table_retour['attributions'][$langue][$num_nom]['biblio.'.$cle] = $valeur;
}
}
}
}
}
 
}
?>
/tags/v5.12-baouque/services/modules/0.1/lion1906/NomCommune.php
New file
0,0 → 1,143
<?php
// declare(encoding='UTF-8');
/**
* Classe permettant d'obtenir le nom et le code INSEE des communes les plus proches d'un point (latitude et longitude).
* La latitude et longitude doivent être exprimée par un nombre décimal.
* Ce service fonctionne uniquement sur les communes de France métropolitaine (Corse comprise) présentent
* dans les données Lion1906 téléchargeable à cette adrese : http://www.lion1906.com/Pages/francais/utile/telechargements.html.
* Source des données : Lion1906.com http://www.lion1906.com
* Paramètres du service :
* - lat : latitude
* - lon : longitude
* Exemple :
* http://localhost/lion1906/services/0.1/nom-commune?lat=44.71546&lon=3.84216
*
* @category php 5.2
* @package lion1906
* @author Mohcen BENMOUNAH <mohcen@tela-botanica.org>
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @copyright Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
* @version $Id$
*/
class NomCommune {
 
const PATTERN_LAT = '/^[0-9]+(?:[.][0-9]+|)$/';
const PATTERN_LON = '/^[-]?[0-9]+(?:[.][0-9]+|)$/';
const LAT_MAX = 51.071667;
const LAT_MIN = 41.316667;
const LON_MAX = 9.513333;
const LON_MIN = -5.140278;
const NBRE_COMMUNE_PAR_DEFAUT = 10;
const NBRE_COMMUNE_MAX = 100;
const MIME_JSON = 'application/json';
 
private $parametres = array();
private $ressources = array();
private $bdd = null;
 
public function __construct(Bdd $bdd) {
$this->bdd = $bdd;
}
 
public function consulter($ressources, $parametres) {
$this->parametres = $parametres;
$this->ressources = $ressources;
 
$this->definirParametresParDefaut();
$this->verifierParametres();
 
$nomINSEEs = $this->trouverCommunesProches();
$corps = $this->formaterResultats($nomINSEEs);
 
$resultat = new ResultatService();
$resultat->mime = self::MIME_JSON;
$resultat->corps = $corps;
return $resultat;
}
 
private function definirParametresParDefaut() {
if (array_key_exists('nbre', $this->parametres) === false) {
$this->parametres['nbre'] = self::NBRE_COMMUNE_PAR_DEFAUT;
}
}
 
private function verifierParametres() {
extract($this->parametres);
$messages = array();
if (! array_key_exists('lat', $this->parametres)) {
$messages[] = "Vous devez indiquer une latitude en degré décimal à l'aide du paramètres d'url : lat";
} else if (!preg_match(self::PATTERN_LAT, $lat)) {
$messages[] = "La valeur de latitude doit être un nombre décimal positif dont le séparateur décimal est un point. Ex. : 44 ou 43.03";
} else if ($lat > self::LAT_MAX) {
$messages[] = "La valeur de latitude indiquée est supérieure à {self::LAT_MAX} qui est le point le plus au Nord de la France métropolitaine.";
} else if ($lat < self::LAT_MIN) {
$messages[] = "La valeur de latitude indiquée est infèrieure à {self::LAT_MIN} qui est le point le plus au Sud de la France métropolitaine.";
}
if (! array_key_exists('lon', $this->parametres)) {
$messages[] = "Vous devez indiquer une longitude en degré décimal à l'aide du paramètres d'url : lon";
} else if (!preg_match(self::PATTERN_LON, $lon)) {
$messages[] = "La valeur de longitude doit être un nombre décimal dont le séparateur décimal est un point. Ex. : -4.03 ou 3.256";
} else if ($lon > self::LON_MAX) {
$messages[] = "La valeur de longitude indiquée est supérieure à {self::LON_MAX} qui est le point le plus à l'Est de la France métropolitaine.";
} else if ($lon < self::LON_MIN) {
$messages[] = "La valeur de longitude indiquée est infèrieure à {self::LON_MIN} qui est le point le plus à l'Ouest de la France métropolitaine.";
}
if (array_key_exists('nbre', $this->parametres)) {
if (!preg_match('/^[0-9]+$/', $nbre)) {
$messages[] = "Le nombre de commune le plus proche à retourner doit être un entier positif. Ex. : 10";
} else if ($nbre > self::NBRE_COMMUNE_MAX) {
$messages[] = "Le nombre de commune le plus proche à retourner doit être un entier positif inférieur à 100. Ex. : 10";
}
}
 
if (count($messages) != 0) {
$message = implode('<br />', $messages);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
}
 
private function formaterResultats($nomINSEEs) {
$communes_trouvees = null;
if (isset($nomINSEEs) && !empty($nomINSEEs)) {
foreach ($nomINSEEs as $nomINSEE) {
$communes_trouvees[] = array('nom' => $nomINSEE['nom'], 'codeINSEE' => $nomINSEE['insee']);
}
if (!is_null($communes_trouvees)) {
if ($this->parametres['nbre'] == 1 && count($communes_trouvees) == 1) {
$communes_trouvees = $communes_trouvees[0];
}
} else {
$message = "Le service '".get_class($this)."' n'a trouvé aucune commune correspondant aux coordonnées : {$parametres['lat']}, {$parametres['lon']}.";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
} else {
$message = "Le service '".get_class($this)."' n'a trouvé aucune commune dont le centroïde correspond aux coordonnées : {$parametres['lat']}, {$parametres['lon']}.";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $communes_trouvees;
}
 
/**
* requête qui récupère les 20 communes les plus proches du point recherché
* La distance(AB = \sqrt{(x_B-x_A)^2 + (y_B-y_A)^2}) est calculée sans la racine
* (calcul en plus qui change pas le résultat).
*/
private function trouverCommunesProches() {
$lat = $this->parametres['lat'];
$lon = $this->parametres['lon'];
$requete = 'SELECT '.
" (({$lat} - X(centroide)) * ({$lat} - X(centroide)) + ({$lon} - Y(centroide)) * ({$lon} - Y(centroide))) AS distance, ".
"insee, nom ".
'FROM lion1906_communes_v2008 '.
'ORDER BY distance '.
"LIMIT {$this->parametres['nbre']} ";
$resultat = $this->bdd->recupererTous($requete);
return $resultat;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/moissonnage/cartes/SourceDonnees.php
New file
0,0 → 1,187
<?php
 
class SourceDonnees {
private $bdd = null;
private $limitesCarte = '';
private $taxon = array();
private $nomRang = '';
private $taxons = array();
private $genres = array();
private $utilisateurs = null;
public function __construct($limitesCarte, $taxon) {
$this->limitesCarte = $limitesCarte;
foreach ($this->limitesCarte as $bord => $valeur) {
$this->limitesCarte[$bord] = str_replace(",", ".", round($valeur, 6));
}
$this->bdd = new Bdd();
$this->taxon = $taxon;
$this->nomRang = $this->obtenirNomRang();
if ($this->nomRang == 'espece' || $this->nomRang == 'sous_espece') {
$this->taxons = $this->recupererSynonymesEtSousEspeces();
} elseif ($this->nomRang == 'famille') {
$this->genres = $this->recupererGenres();
}
$this->utilisateurs = new Utilisateurs();
}
private function obtenirNomRang() {
$nomsRangs = array('famille', 'genre', 'espece', 'sous_espece');
$rangs = explode(',', Config::get('rangs'));
for ($index = 0; $index < count($nomsRangs) && $rangs[$index] != $this->taxon['rang']; $index ++);
$position = $index == count($nomsRangs) ? count($nomsRangs)-1 : $index;
return $nomsRangs[$position];
}
protected function recupererSynonymesEtSousEspeces() {
$requete =
"SELECT num_nom, nom_sci, nom_complet, num_taxonomique FROM ".Config::get('bdd_table_referentiel').
" WHERE hierarchie LIKE '%-{$this->taxon['num_nom']}-%' ".
"OR num_nom_retenu = {$this->taxon['num_nom_retenu']}";
return $this->bdd->recupererTous($requete);
}
protected function recupererGenres() {
$this->bdd->requeter("USE ".Config::get('bdd_nom'));
$requete =
"SELECT num_nom, nom_sci, num_taxonomique FROM ".Config::get('bdd_table_referentiel').
" WHERE rang=220 AND num_tax_sup={$this->taxon['num_nom']}";
return $this->bdd->recupererTous($requete);
}
public function recupererStationsFloradata() {
$this->bdd->requeter("USE ".Config::get('bdd_nom_floradata'));
$requete =
"SELECT DISTINCTROW zone_geo AS commune, Date(date_observation) AS date, Floor(wgs84_latitude*10)/10 AS lat, ".
"Floor(wgs84_longitude*10)/10 AS lng, courriel_utilisateur AS auteur ".
"FROM cel_obs LEFT JOIN cel_zones_geo cz ON ce_zone_geo=id_zone_geo ".
"WHERE ".$this->construireWhereTaxonFloradata()." AND transmission=1 AND nom_referentiel = '".Config::get('referentielsDispo')."' AND ".
"wgs84_longitude BETWEEN ".$this->limitesCarte['ouest']." AND ".$this->limitesCarte['est']." ".
"AND wgs84_latitude BETWEEN ".$this->limitesCarte['sud']." AND ".$this->limitesCarte['nord']." ".
"AND date_observation<>'0000-00-00 00-00-00' ORDER BY lat DESC, lng ASC, commune, date";
$stations = $this->bdd->recupererTous($requete);
$this->extraireIdentitesAuteurs($stations);
foreach($stations as &$station) {
$station['auteur'] = $this->utilisateurs->getIntitule($station['auteur']);
}
return $stations;
}
private function extraireIdentitesAuteurs($stations) {
$courriels = array();
foreach ($stations as &$station) {
$courriels[] = $station['auteur'];
}
$this->utilisateurs->setCourriels($courriels);
$this->utilisateurs->chargerIdentites();
}
private function construireWhereTaxonFloradata() {
$criteres = array();
$nomRang = $this->obtenirNomRang($this->taxon);
if ($this->nomRang == 'famille') {
$criteres[] = "famille=".$this->bdd->proteger($this->taxon['nom_sci']);
} elseif ($this->nomRang == 'genre') {
$criteres[] = "nom_sel LIKE ".$this->bdd->proteger($this->taxon['nom_sci'].'%');
} else {
$taxons = array($this->taxon['num_nom']);
foreach ($this->taxons as $sousTaxon) {
$taxons[] = $sousTaxon['num_nom'];
}
$criteres[] = "nom_sel_nn IN (".implode(',', array_unique($taxons)) .")";
}
return "(".implode(' OR ',array_unique($criteres)).")";
}
public function recupererStationsMoissonnage($source) {
$this->bdd->requeter("USE ".Config::get('bdd_nom'));
$requete =
"SELECT DISTINCTROW lieu_commune_code_insee, observation_date AS date, observateur_nom_complet AS auteur ".
"FROM {$source}_tapir WHERE ".$this->construireWhereTaxonMoissonnage($source)." ".
"AND lieu_station_longitude BETWEEN ".$this->limitesCarte['ouest']." AND ".$this->limitesCarte['est']." ".
"AND lieu_station_latitude BETWEEN ".$this->limitesCarte['sud']." AND ".$this->limitesCarte['nord']." ".
"AND Length(lieu_commune_code_insee)=5 ORDER BY lieu_commune_code_insee, date"." -- " . __FILE__ . ":" . __LINE__." ". @$_SERVER['REQUEST_URI'];
$stations = $this->bdd->recupererTous($requete);
$this->rechercherInfosCommune($stations);
return $stations;
}
private function construireWhereTaxonMoissonnage($source) {
$nomRang = $this->obtenirNomRang();
$criteres = array();
$criteres[] = ($source == "baznat" || $source == "ifn") ?
"num_nom = ".$this->taxon['num_nom'] :
"nom_scientifique_complet LIKE ".$this->bdd->proteger($this->taxon['nom_sci']) ;
if ($this->nomRang == 'espece' || $this->nomRang == 'sous_espece') {
foreach ($this->taxons as $sousTaxon) {
$criteres[] = ($source == "baznat" || $source == "ifn") ?
"num_nom = ".$sousTaxon['num_nom'] :
"nom_scientifique_complet LIKE ".$this->bdd->proteger($sousTaxon['nom_sci']) ;
}
} elseif ($this->nomRang == 'famille') {
foreach ($this->genres as $genre) {
$criteres[] = "nom_scientifique_complet LIKE ".$this->bdd->proteger($genre['nom_sci']."%");
}
}
return "(".implode(' OR ',array_unique($criteres)).")";
}
private function rechercherInfosCommune(& $stations) {
$codesInsee = array();
foreach ($stations as $station) {
$codeInsee = $station['lieu_commune_code_insee'];
if (substr($codeInsee, 0, 2) == '20') {
$codeInsee = '2A'.substr($codeInsee, 2);
$codeInsee2 = '2B'.substr($codeInsee, 2);
}
if (!in_array($codeInsee, $codesInsee)) {
if (substr($codeInsee, 0, 2) == '20') {
$codesInsee[] = "'$codeInsee2'";
}
$codesInsee[] = "'$codeInsee'";
}
}
$nomTableCommunes = Config::get('bdd_table_communes');
$communes = array();
if(count($codesInsee) > 0) {
$requete =
"SELECT insee, nom AS commune, Floor(latitude_degre*10)/10 AS lat, Floor(longitude_degre*10)/10 AS lng ".
"FROM $nomTableCommunes WHERE insee IN (".implode(',', array_unique($codesInsee)).") ORDER BY insee";
$communes = $this->bdd->recupererTous($requete);
}
$indexStation = 0;
foreach ($communes as $commune) {
$codeInsee = $commune['insee'];
if (substr($codeInsee, 0, 2) == '2A' || substr($codeInsee, 0, 2) == '2B') {
$codeInsee = '20'.substr($codeInsee, 2);
}
while ($stations[$indexStation]['lieu_commune_code_insee'] < $codeInsee) {
$indexStation ++;
}
if ($stations[$indexStation]['lieu_commune_code_insee'] == $codeInsee) {
$stations[$indexStation]['lat'] = $commune['lat'];
$stations[$indexStation]['lng'] = $commune['lng'];
$stations[$indexStation]['commune'] = $commune['commune'];
}
}
$lat = array();
$lng = array();
foreach ($stations as $index => $station) {
if (!isset($station['lat'])) {
$station['lat'] = -100;
$station['lng'] = -100;
}
$lat[$index] = $station['lat'];
$lng[$index] = $station['lng'];
}
array_multisort($lat, SORT_DESC, $lng, SORT_ASC, $stations);
}
}
 
?>
/tags/v5.12-baouque/services/modules/0.1/moissonnage/cartes/FormateurSVG.php
New file
0,0 → 1,322
<?php
 
/**
* Classe qui genere la carte SVG pour les parametres de la requete qui a ete utilisee pour appeler
* le web service
*
* @package framework-0.4
* @author Alexandre GALIBERT <alexandre.galibert@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 $Id$
* @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
*
*/
 
 
class FormateurSVG {
private $documentXML;
private $coordonnees = array();
private $grille = null;
private $largeur = 0;
private $hauteur = 0;
private $typeMime = '';
private $format = 0;
private $sources = array();
private $image = null;
const ORIGINE = 20037508.342789244;
const MIME_MAP = 'text/html';
public function __construct($nomFichierSVG, $sources, $typeMime, $format) {
$this->chargerSVG($nomFichierSVG);
$this->chargerCoordonnees();
$this->construireParametresRetour($typeMime, $format);
$this->creerStyleSources();
$this->sources = $sources;
}
private function chargerSVG($nomFichierSVG) {
$this->documentXML = new DOMDocument("1.0", "UTF-8");
$this->documentXML->load($nomFichierSVG);
}
private function chargerCoordonnees() {
$viewbox = $this->recupererNoeuds('qgisviewbox');
$this->coordonnees = array(
'xMin' => $viewbox->attributes->getNamedItem('xMin')->value,
'xMax' => $viewbox->attributes->getNamedItem('xMax')->value,
'yMin' => $viewbox->attributes->getNamedItem('yMin')->value,
'yMax' => $viewbox->attributes->getNamedItem('yMax')->value
);
}
private function recupererNoeuds($nomCouche) {
$contenuSVG = $this->documentXML->documentElement->childNodes;
$noeudCouche = null;
$index = 0;
while ($index < $contenuSVG->length && is_null($noeudCouche)) {
$id = $contenuSVG->item($index)->attributes->getNamedItem('id');
if ($id->value == $nomCouche) {
$noeudCouche = $contenuSVG->item($index);
}
$index ++;
}
$noeuds = null;
if (!is_null($noeudCouche)) {
$noeuds = $noeudCouche->firstChild;
}
return $noeuds;
}
private function construireParametresRetour($typeMime, $format) {
$viewBox = $this->documentXML->documentElement->attributes->getNamedItem('viewBox');
$limitesPixels = explode(' ',$viewBox->value);
$this->largeur = intval($limitesPixels[2]);
$this->hauteur = intval($limitesPixels[3]);
$this->typeMime = $typeMime;
$this->format = intval($format);
}
private function creerStyleSources() {
$couleurs = $this->recupererCouleursSources();
$reglesCss = array();
foreach ($couleurs as $codeSource => $codeCouleur) {
$reglesCss[] = ".{$codeSource} {\nfill:{$codeCouleur}\n}\n";
}
$texteCss = $this->documentXML->createCDATASection(implode(' ', $reglesCss));
$noeudStyle = new DomElement('style', '');
$this->documentXML->documentElement->appendChild($noeudStyle);
$noeudStyle->appendChild($texteCss);
}
private function recupererCouleursSources() {
$sourcesDonnees = Config::get('sourcesDonnees');
$codesSources = str_replace('floradata', 'cel', $sourcesDonnees).',tout';
$codes = explode(',', $codesSources);
for ($index = 0; $index < count($codes); $index ++) {
$codes[$index] = "'".$codes[$index]."'";
}
$codesSources = implode(',', $codes);
$bdd = new Bdd();
$requete = "SELECT code, SUBSTR(complements,9) AS couleur FROM ".Config::get('bdd_table_ontologies')." WHERE code IN ({$codesSources})";
$couleurs = $bdd->recupererTous($requete);
$listeCouleurs = array();
foreach ($couleurs as $couleur) {
$couleur['code'] = $couleur['code'] == 'cel' ? 'floradata' : $couleur['code'];
$listeCouleurs[$couleur['code']] = $couleur['couleur'];
}
return $listeCouleurs;
}
 
public function formaterCarte($taxon) {
$limitesCarte = $this->renvoyerLimitesCarte();
$sourceDonnees = new SourceDonnees($limitesCarte, $taxon);
// modification temporaire pour lors de la selection d'un rang au dessus de famille on ne prenne que floradata
// (probleme de performance, qui sera réglé en reremplissant la table de moissonnage)
if($taxon['rang'] >= 180) {
foreach ($this->sources as $source) {
$nomMethode = "recupererStations".($source == 'floradata' ? 'Floradata' : 'Moissonnage');
$stations = $sourceDonnees->$nomMethode($source);
$this->ajouterStations($stations, $source);
}
} else {
$stations = $sourceDonnees->recupererStationsFloradata($source);
$this->ajouterStations($stations, $source);
}
$this->supprimerMaillesVides();
}
public function renvoyerLimitesCarte() {
$limites = array();
list($limites['ouest'], $limites['sud']) = $this->convertirMetresEnPixels(
$this->coordonnees['xMin'], $this->coordonnees['yMin']);
list($limites['est'], $limites['nord']) = $this->convertirMetresEnPixels(
$this->coordonnees['xMax'], $this->coordonnees['yMax']);
return $limites;
}
private function convertirMetresEnPixels($x, $y) {
$longitude = ($x / self::ORIGINE) * 180;
$latitude = ($y / self::ORIGINE) * 180;
$latitude = 180 / M_PI * (2 * atan(exp($latitude * M_PI / 180.0)) - M_PI / 2.0);
return array(round($longitude, 6), round($latitude, 6));
}
private function ajouterStations($stations, $source) {
$grille = $this->recupererNoeuds('grille')->childNodes;
$index = 0;
$maille = $grille->item($index);
foreach ($stations as $station) {
if (!isset($station['lat']) || !isset($station['lng']) || !isset($station['commune'])) {
continue;
}
$idMaille = $maille->attributes->getNamedItem('id')->value;
$bbox = explode('_', substr($idMaille, 5));
$bbox[0] = floatval($bbox[0]);
$bbox[1] = floatval($bbox[1]);
while ($index < $grille->length && (
$bbox[1] > $station['lat'] || ($bbox[1] == $station['lat'] && $bbox[0] < $station['lng'])
)) {
$maille = $grille->item($index ++);
$idMaille = $maille->attributes->getNamedItem('id')->value;
$bbox = explode('_', substr($idMaille, 5));
$bbox[0] = floatval($bbox[0]);
$bbox[1] = floatval($bbox[1]);
}
if ($bbox[1] == $station['lat'] && $bbox[0] == $station['lng']) {
$this->ajouterCommentaire($station, $source, $maille);
$this->appliquerStyleMaille($source, $maille);
}
if ($index == $grille->length) {
break;
}
}
}
private function supprimerMaillesVides() {
$grille = $this->recupererNoeuds('grille')->childNodes;
$index = 0;
while ($index < $grille->length) {
if (!$grille->item($index)->hasAttribute('title')) {
$grille->item($index)->parentNode->removeChild($grille->item($index));
} else {
$index ++;
}
}
}
private function appliquerStyleMaille($source, & $maille) {
if ($maille->hasAttribute('class') && $maille->attributes->getNamedItem('class')->value != $source) {
$maille->setAttribute('class', 'tout');
} elseif (!$maille->hasAttribute('class')) {
$maille->setAttribute('class', $source);
}
}
private function ajouterCommentaire($station, $source, & $maille) {
$commentaires = array();
if ($maille->hasAttribute('title')) {
$commentaires = explode("; ", $maille->attributes->getNamedItem('title')->value);
}
$commentaire = ucfirst($source)." : {$station['commune']}, ";
if (strlen($station['date']) == 4) {
$commentaire .= "en {$station['date']} par {$station['auteur']}";
} else {
$date = preg_replace("/(\d{4})-(\d{2})-(\d{2})/", "$3/$2/$1", $station['date']);
$commentaire .= "le {$date} par {$station['auteur']}";
}
$commentaires[] = trim($commentaire);
$maille->setAttribute('title', implode('; ', $commentaires));
}
public function renvoyerCarte() {
$this->documentXML->documentElement->setAttribute("width", $this->format);
$this->documentXML->documentElement->setAttribute("height", $this->hauteur * $this->format / $this->largeur);
$retour = '';
if ($this->typeMime == self::MIME_MAP) {
$retour = $this->documentXML->saveHTML();
} else {
$retour = $this->convertirEnPng();
}
return $retour;
}
private function convertirEnPng() {
$this->image = imagecreatetruecolor($this->format, $this->hauteur * $this->format / $this->largeur);
imagefill($this->image, 0, 0, imagecolorallocate($this->image, 255, 255, 255));
$this->transformerLignesEnPng('departements');
$this->transformerPolygonesEnPng('grille');
// stocker le contenu encode de l'image generee dans une chaine de caracteres
ob_start();
imagepng($this->image);
$png = ob_get_contents();
ob_end_clean();
return $png;
}
private function transformerLignesEnPng($nomCouche) {
$facteur = floatval($this->format) / floatval($this->largeur);
$noeudCouche = $this->recupererNoeuds($nomCouche);
$couleurContour = $noeudCouche->attributes->getNamedItem('stroke')->value;
$couleurContour = ($this->format >= 300 ? $couleurContour : "rgb(192,192,192)");
for ($index = 0; $index < $noeudCouche->childNodes->length; $index ++) {
$noeudLigne = $noeudCouche->childNodes->item($index);
for ($indexPath = 0; $indexPath < $noeudLigne->childNodes->length; $indexPath ++) {
$coordonneesSvg = $noeudLigne->childNodes->item($indexPath)->attributes->getNamedItem('points')->value;
preg_match_all('/\d+.\d/', $coordonneesSvg, $coordonnees);
$coordonnees = current($coordonnees);
foreach ($coordonnees as $indexCoord => $valeur) {
$coordonnees[$indexCoord] = intval(floatval($valeur) * $facteur);
}
if ($couleurContour != 'none') {
for ($i = 0; $i < count($coordonnees) - 2; $i += 2) {
imageline($this->image, $coordonnees[$i], $coordonnees[$i+1], $coordonnees[$i+2],
$coordonnees[$i+3], $this->allouerCouleur($couleurContour));
}
}
}
}
}
private function transformerPolygonesEnPng($nomCouche) {
$couleurs = $this->recupererCouleursSources();
$facteur = floatval($this->format) / floatval($this->largeur);
$noeudCouche = $this->recupererNoeuds($nomCouche);
$couleurRemplissage = $noeudCouche->attributes->getNamedItem('fill')->value;
$couleurContour = $noeudCouche->attributes->getNamedItem('stroke')->value;
for ($index = 0; $index < $noeudCouche->childNodes->length; $index ++) {
$noeudPolygone = $noeudCouche->childNodes->item($index);
$couleurPolygone = 'none';
if ($noeudPolygone->hasAttribute('class')) {
$couleurPolygone = $couleurs[$noeudPolygone->attributes->getNamedItem('class')->value];
}
for ($indexPath = 0; $indexPath < $noeudPolygone->childNodes->length; $indexPath ++) {
$coordonneesSvg = $noeudPolygone->childNodes->item($indexPath)->attributes->getNamedItem('points')->value;
preg_match_all('/\d+.\d/', $coordonneesSvg, $coordonnees);
$coordonnees = current($coordonnees);
foreach ($coordonnees as $indexCoord => $valeur) {
$coordonnees[$indexCoord] = intval(floatval($valeur) * $facteur);
}
if ($couleurRemplissage != 'none') {
imagefilledpolygon($this->image, $coordonnees, count($coordonnees) / 2, $this->allouerCouleur($couleurRemplissage));
}
if ($couleurContour != 'none') {
imagepolygon($this->image, $coordonnees, count($coordonnees) / 2, $this->allouerCouleur($couleurContour));
}
if ($couleurPolygone != 'none') {
$contourGrille = "rgba(255,255,255,".($this->format >= 300 ? 0.4 : 0).")";
imagefilledrectangle($this->image, $coordonnees[0], $coordonnees[1], $coordonnees[4], $coordonnees[5],
$this->allouerCouleur($couleurPolygone));
imagerectangle($this->image, $coordonnees[0], $coordonnees[1], $coordonnees[4], $coordonnees[5],
$this->allouerCouleur($contourGrille));
}
}
}
}
private function allouerCouleur($couleurTexte) {
preg_match_all('/\d+/', $couleurTexte, $valeurs);
$rouge = $valeurs[0][0];
$vert = $valeurs[0][1];
$bleu = $valeurs[0][2];
$alpha = 0;
if (count($valeurs[0]) > 3) {
$valeurAlpha = floatval($valeurs[0][3].".".$valeurs[0][4]);
$alpha = intval((1.0 - $valeurAlpha) * 127.0);
}
return imagecolorallocatealpha($this->image, $rouge, $vert, $bleu, $alpha);
}
}
 
?>
/tags/v5.12-baouque/services/modules/0.1/moissonnage/cartes/LegendeCartes.php
New file
0,0 → 1,76
<?php
 
/**
* Classe qui fournit une legende recuperee dans une table d'ontologies pour la renvoyer au client
*
* @package framework-0.4
* @author Alexandre GALIBERT <alexandre.galibert@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 $Id$
* @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
*
*/
 
class LegendeCartes {
const TYPE_MIME = 'application/json';
const ID_CLASSE = '10';
private $tableOntologies = '';
private $ontologies = array();
private $legende = array();
public function __construct() {
$this->tableOntologies = Config::get('bdd_table_ontologies');
}
public function obtenirLegende() {
$this->chargerOntologies();
$this->chargerLegende();
$resultat = new ResultatService();
$resultat->corps = $this->legende;
$resultat->mime = self::TYPE_MIME;
return $resultat;
}
private function chargerOntologies() {
$bdd = new Bdd();
$requete = "SELECT * FROM {$this->tableOntologies}";
$resultats = $bdd->recupererTous($requete);
if (!is_array($resultats) || count($resultats) <= 0) {
$message = "Les données d'ontologies n'ont pu être chargées pour la ressource demandée";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
foreach ($resultats as $ontologie) {
$this->ontologies[$ontologie['id']] = $this->extraireComplementsOntologies($ontologie);
}
}
private function extraireComplementsOntologies($ontologie) {
if (strlen(trim($ontologie['complements'])) > 0) {
list($cle, $valeur) = explode('=', trim($ontologie['complements']));
$ontologie[trim($cle)] = trim($valeur);
}
return $ontologie;
}
private function chargerLegende() {
foreach ($this->ontologies as $ontologie) {
if ($ontologie['classe_id'] == self::ID_CLASSE && isset($ontologie['legende'])) {
$this->legende[] = array(
'code' => $ontologie['code'],
'couleur' => $ontologie['legende'],
'nom' => $ontologie['nom'],
'description' => $ontologie['description']
);
}
}
}
}
 
?>
/tags/v5.12-baouque/services/modules/0.1/moissonnage/Cartes.php
New file
0,0 → 1,345
<?php
 
/**
* Classe qui remplit un fond cartographique SVG a partir des observations en base de donnees
* pour un taxon de plante. Elle verifie dans un premier temps la validite des parametres saisis,
* puis charge le fond cartographique depuis le fichier, recupere dans la base de donnees
* les observations sur la France metropolitaine pour le taxon donne et remplit la carte
* en changeant le style CSS des mailles en fonction des coordonnees des points d'observation.
* Le format et la taille de la carte renvoyee au client est parametrable.
*
* Parametres :
* - referentiel : le referentiel taxonomique a interroger pour verifier le taxon. Pour l'instant,
* seul bdtfx (Tracheophytes de France metropolirtaine) est utilise par le web service
* - num_taxon : le numero taxonomique de la plante dont on veut obtenir la carte de repartition.
* Le rang des taxons traites par le web service sont la famille, le genre, l'espece et la sous-espece.
* La recherche des observations s'etend en pus sur les sous taxons et les synonymes.
* - source : une ou plusieurs sources de donnees a interroger. Si le parametre n'est pas indique,
* le web service ira rechercher les observatipons dans toutes les sources de donnees.
* - format : la largeur de la carte, exprimee dans une valeur entiere en pixels.
* Le ratio largeur:hauteur est conserve lors du redimensionnement de la carte pour le retour
* - retour : le type MIME (ou format de fichier) de retour. Sont acceptes par le web service
* le PNG (image/png) et le XML (text/html) pour renvoyer le web service
*
* @package framework-0.4
* @author Alexandre GALIBERT <alexandre.galibert@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 $Id$
* @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
*
*/
 
class MoissonnageCartes {
 
const MIME_MAP = "text/html";
const MIME_PNG = "image/png";
const METHODE_TELECHARGEMENT = "telecharger";
const METHODE_AFFICHAGE = "afficher";
private $ressources;
private $parametres;
private $referentiel = '';
private $taxon = null;
private $sources = array();
private $format = 0;
private $retour = self::MIME_MAP;
private $methode_livraison = self::METHODE_AFFICHAGE;
private $erreurs = array();
 
public function consulter($ressources, $parametres) {
$this->parametres = $parametres;
$this->ressources = $ressources;
$resultat = null;
$this->chargerClassesSousDossier();
if ($this->analyserRessources() == true) {
$resultat = $this->formerLegende();
} else {
$this->traiterParametres();
$resultat = $this->obtenirCarte();
if($this->methode_livraison == self::METHODE_TELECHARGEMENT) {
$this->telechargerCarte($resultat->corps);
}
}
return $resultat;
}
private function analyserRessources() {
$ok = false;
if (isset($this->ressources[0]) && $this->ressources[0] == 'legende') {
$ok = true;
}
return $ok;
}
private function formerLegende() {
$legende = new LegendeCartes();
$resultat = $legende->obtenirLegende();
return $resultat;
}
private function chargerClassesSousDossier() {
$this->verifierExistenceDossier("cartes");
$nomDossier = dirname(__FILE__).DS."cartes";
$dossier = opendir($nomDossier);
$fichiersAInclure = array();
while ($fichier = readdir($dossier)) {
if (filetype($nomDossier.DS.$fichier) == 'file') {
$fichiersAInclure[] = $nomDossier.DS.$fichier;
}
}
$fichiersAInclure = array_reverse($fichiersAInclure);
foreach ($fichiersAInclure as $fichier) {
include_once($fichier);
}
}
private function verifierExistenceDossier($nomDossier) {
$dossier = dirname(__FILE__).DS.$nomDossier;
if (!file_exists($dossier) || !is_dir($dossier)) {
$message = "Problème rencontré lors de la génération de la carte : des ressources ".
"nécessaires au fonctionnement du service n'ont pas été localisées sur le serveur.\n";
throw new Exception($message);
}
}
private function verifierExistenceFichier($nomFichier) {
if (!file_exists($nomFichier)) {
$message = "Problème rencontré lors de la génération de la carte : des ressources ".
"nécessaires au fonctionnement du service n'ont pas été localisées sur le serveur.\n";
throw new Exception($message);
}
}
private function traiterParametres() {
$this->verifierReferentielEtTaxon();
$this->verifierParametreSource();
$this->verifierParametreFormat();
$this->verifierParametreRetour();
$this->verifierParametreMethodeLivraison();
if (count($this->erreurs) > 0) {
$this->renvoyerErreurs();
}
}
private function verifierParametreFormat() {
if (!isset($this->parametres['format'])) {
$this->erreurs[] = "Le paramètre format (dimensions) de l'image n'a pas été indiqué dans l'URL du service.";
} elseif (preg_match('/^[1-9]\d{2}$/', $this->parametres['format']) != 1) {
$this->erreurs[] = "La valeur du paramètre format n'est pas acceptée par le service. ".
"Une largeur valide doit être un nombre entier compris entre 100 et 999.";
} else {
$this->format = $this->parametres['format'];
}
}
private function verifierParametreRetour() {
$typesMime = array(self::MIME_MAP, self::MIME_PNG);
if (!isset($this->parametres['retour'])) {
$this->erreurs[] = "Le paramètre type de retour de l'image n'a pas été indiqué dans l'URL du service.";
} elseif (!in_array($this->parametres['retour'], $typesMime)) {
$this->erreurs[] = "Le format de retour ".$this->parametres['retour']." n'est pas acceptée par le service. ".
" Seuls les types MIME suivants sont gérés : ".implode(',', $typesMime);
} else {
$this->retour = $this->parametres['retour'];
}
}
private function verifierParametreMethodeLivraison() {
$typesMethodeLivraison = array(self::METHODE_AFFICHAGE, self::METHODE_TELECHARGEMENT);
if (isset($this->parametres['methode']) && !in_array($this->parametres['methode'], $typesMethodeLivraison)) {
$this->erreurs[] = "Le format de methode de livraison ".$this->parametres['methode']." n'est pas acceptée par le service. ".
" Seuls les methodes suivantes sont gérés : ".implode(',', $typesMethodeLivraison);
} elseif(isset($this->parametres['methode']) && in_array($this->parametres['methode'], $typesMethodeLivraison)) {
$this->methode_livraison = $this->parametres['methode'];
}
}
private function verifierParametreSource() {
$sourcesDisponibles = explode(',', trim(Config::get('sourcesDonnees')));
if (isset($this->parametres['source'])) {
$sourcesParametre = explode(',', trim($this->parametres['source']));
foreach ($sourcesParametre as $source) {
if (!in_array($source, $sourcesDisponibles)) {
$this->erreurs[] = "La source de données $source n'est pas disponible pour ce service. ".
"Les sources suivantes sont utilisables : ".implode(',', $sourcesDisponibles).".";
} else {
$this->sources[] = $source;
}
}
} else {
$this->sources = $sourcesDisponibles;
}
}
private function verifierReferentielEtTaxon() {
if (!$this->estReferentielDisponible()) {
$this->erreurs[] = "Le référentiel ".$this->parametres['referentiel']." n'a pas été trouvé. ".
"La liste des référentiels disponibles pour ce service sont : ".Config::get('referentielsDispo');
} else {
$this->referentiel = $this->parametres['referentiel'];
$taxon = $this->recupererInformationsTaxon();
if (is_null($taxon)) {
$this->erreurs[] = "Le taxon d'espèce que vous avez demandé n'a pas été trouvé dans le référentiel.";
} else {
$this->taxon = $taxon;
}
}
}
private function renvoyerErreurs() {
$message = "Les erreurs suivantes ont été rencontrées : \n".implode('\n', $this->erreurs);
throw new Exception($message, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
private function estReferentielDisponible() {
$referentielsDispo = explode(',', Config::get('referentielsDispo'));
$estDisponible = (isset($this->parametres['referentiel'])
&& in_array($this->parametres['referentiel'], $referentielsDispo));
return $estDisponible;
}
private function recupererInformationsTaxon() {
$taxon = null;
if (isset($this->parametres['num_taxon'])) {
$numTaxon = $this->parametres['num_taxon'];
$nomTable = $this->recupererNomTableReferentiel();
$bdd = new Bdd();
$requete = "SELECT num_nom, num_nom_retenu, nom_sci, nom_complet, rang, num_taxonomique FROM {$nomTable} ".
"WHERE num_taxonomique={$numTaxon} ORDER BY If(num_nom=num_nom_retenu,0,1) LIMIT 0,1";
$taxon = $bdd->recuperer($requete);
if ($taxon === false) {
$taxon = null;
}
}
return $taxon;
}
private function recupererNomTableReferentiel() {
$tablesReferentiel = explode(',', Config::get('bdd_table_referentiel'));
$nomTable = '';
foreach ($tablesReferentiel as $table) {
if (strstr($table, $this->referentiel) !== false) {
$nomTable = $table;
}
}
return $nomTable;
}
 
/**
* Va chercher la carte dans le cache si elle existe et n'a pas dépassé la durée
* de vie $this->dureeCache; sinon, crée la carte et la met en cache.
* Avec le paramètre "recalculer=1", on force le vidage du cache et on recrée la carte
*/
protected function obtenirCarte() {
$carte = null;
$cacheActif = Config::get('cache_miseEnCache');
$cheminCache = Config::get('cache_stockageChemin');
$extension = "cache"; // par défaut; indique un problème de mimetype demandé par "retour="
if ($this->retour == self::MIME_PNG) {
$extension = "png";
} elseif ($this->retour == self::MIME_MAP) {
$extension = "svg";
}
$cheminCarteEnCacheSansExtension = $cheminCache . $this->referentiel . "-nt-" . $this->taxon['num_taxonomique'] . "-" . $this->format . ".";
$cheminCarteEnCache = $cheminCarteEnCacheSansExtension . $extension;
 
// a-t-on demandé à régénérer la carte de force ?
$recalculer = false;
if (isset($this->parametres['recalculer'])) {
$recalculer = ($this->parametres['recalculer'] === '1');
}
// le cache est-il actif ?
if ($cacheActif) {
// le fichier existe-t-il en cache ?
//echo "Chemin fichier: $cheminCarteEnCache<br/>";
if (file_exists($cheminCarteEnCache)) {
$limiteDuree = Config::get('cache_dureeDeVie'); // pour ne pas trop faire pipi
$dateFichier = filectime($cheminCarteEnCache);
$age = time() - $dateFichier;
// si le cache est trop vieux ou qu'on a demandé à recalculer
if (($age > $limiteDuree) || $recalculer) {
// détruire le fichier obsolète
unlink($cheminCarteEnCache);
// en cas de rechargement forcé, détruire les fichiers cache de même dimension
// et de formats différents, afin ne pas provoquer d'incohérences
// @ACHTUNG système minimaliste - si on modifie les dimensions, ça va foirer
if ($recalculer) {
foreach (glob($cheminCarteEnCacheSansExtension . "*") as $fichierCacheDeMemeDimension) {
unlink($fichierCacheDeMemeDimension);
}
}
} else {
// récupérer le fichier en cache
$carte = file_get_contents($cheminCarteEnCache);
}
}
}
// si la carte n'a pas été trouvée en cache
if ($carte === null) {
// calculer la nouvelle carte
$carte = $this->formerCarte();
// mettre la nouvelle carte en cache
if ($cacheActif) {
file_put_contents($cheminCarteEnCache, $carte);
}
}
 
// retour du service
$resultat = new ResultatService();
$resultat->mime = $this->retour;
$resultat->corps = $carte;
 
return $resultat;
}
 
/**
* Crée la carte - prend beaucoup de temps
* @return ResultatService
*/
protected function formerCarte() {
$suffixe = 'france_moissonnage';
// le fichier png avec les départements est illisible en petit format
// dans ce cas là un template plus simple est utilisé (sans les départements)
if($this->format < 300 && $this->retour == self::MIME_PNG) {
$suffixe = $suffixe."_sans_departements";
}
$nomFichierSVG = Config::get('chemin')."{$suffixe}.svg";
$this->verifierExistenceFichier($nomFichierSVG);
$formateur = new FormateurSVG($nomFichierSVG, $this->sources, $this->retour, $this->format);
$formateur->formaterCarte($this->taxon);
 
$resultat = $formateur->renvoyerCarte();
return $resultat;
}
private function telechargerCarte($fichier) {
if (function_exists('mb_strlen')) {
$taille = mb_strlen($fichier, '8bit');
} else {
$taille = strlen($fichier);
}
$extension = ($this->retour == "text/html") ? 'html' : 'png';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="carte.'.$extension.'"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: '.$taille);
}
}
 
?>
/tags/v5.12-baouque/services/modules/0.1/moissonnage/Ontologies.php
New file
0,0 → 1,366
<?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&param2=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 MoissonnageOntologies 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';
 
public function consulter($ressources, $parametres) {
$this->ressources = $ressources;
$this->parametres = $parametres;
$this->service = 'ontologies';
$this->traiterParametres();
$resultats = '';
$this->table = 'eflore_ontologies'; //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();
$resultat = $this->getBdd()->recupererTous($requete);
$versionResultat = $this->traiterResultat($resultat, '', $requete);
$resultats = $versionResultat;
return $resultats;
}
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' : 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) {
$this->format_reponse .= '/id';
preg_match('/^([^:]+):([^:]+)$/', $this->ressources[0], $match);
$this->requete_condition[] =
' id = (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]).'))';
} 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);
}
}
 
 
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() {
$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)) {
$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() {
$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/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 formaterOntologiesId($resultat) {
$table_retour = array();
foreach ($resultat as $key => $valeur) {
if ($valeur != '') {
$table_retour = array_merge($table_retour, $this->afficherDonnees($key, $valeur));
}
}
return $table_retour;
}
 
public function afficherDonnees($champ, $valeur) {
$retour[$champ] = $valeur;
if ($this->retour_format == 'max') {
if ($champ == 'classe_id') {
unset($retour[$champ]); // remplacer par classe.id
if ($valeur != "0") { // pas de parent
if (isset($this->parametres['retour_champs'])) {
switch ($this->parametres['retour_champs']) {
case 'classe' : $retour['classe'] = $this->ajouterClasseCorrespondante($valeur); break;
case 'classe.id' : $retour['classe.id'] = $valeur; break;
case 'classe.href' : $retour['classe.href'] = $this->ajouterHref('ontologies', $valeur); break;
case 'classe.*' : $retour['classe.id'] = $valeur; $retour['classe.href'] = $this->ajouterHref('ontologies', $valeur); break;
}
} else {
$nom_classe = $this->ajouterClasseCorrespondante($valeur);
if (isset($nom_classe)) $retour['classe'] = $nom_classe;
$retour['classe.id'] = $valeur;
$retour['classe.href'] = $this->ajouterHref('ontologies', $valeur);
}
}
}
}
return $retour;
}
 
/** 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;
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/insee-d/ZoneGeo.php
New file
0,0 → 1,446
<?php
/**
* Description :
* Classe ZoneGeo.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 region et
* éventuellement une relation hiérarchique avec un autre terme (=classe).
* Si l'url finit par /zone-geo 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 ? : /observations?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, masque.code, masque.nom, masque.region , recherche,
* distinct, retour.format, navigation.depart et navigation.limite.
*
* Encodage en entrée : utf8
* Encodage en sortie : utf8
* @package framework-v3
* @author Delphine Cauquil <delphine@tela-botanica.org>
* @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 ZoneGeo extends Commun {
 
protected $service = 'zone-geo';
 
/**
* Permet de stocker la requete formulée : /zone-geo | /zone-geo/#id | /zone-geo/#id/champ | /zone-geo/#id/relations
* Est remplit au cours de l'analyse des ressources (traiterRessources()), par défaut, a la valeur du service.
* Est utilisée principalement pr déterminer le format du tableau à retourner. */
protected $format_reponse = 'zone-geo';
 
/** Tri des résultats */
protected $tri = 'dep';
protected $ordre = 'ASC';
/**
* Permet de trier selon les clefs des tableaux reçus, et que ça marche (en
* fait faut faire des alias de colonnes correspondant aux clefs de sortie
* mais bon bref...)
*/
protected $corres_tri = array('code' => 'dep', 'nom' => 'nccenr');
 
/** Variables constituant les parametres de la requete SQL (champ, condition, group by, limit) remplie
* selon ressources et paramètres */
protected $requete_champ = ' * ';
protected $requete_condition = '';
protected $limite_requete = array(
'depart' => 0,
'limite' => 100
);
 
/** Stockage des ressources et paramétres */
protected $table_ressources = array();
protected $table_param = array();
 
/**
* Precise la contenance plus ou moins précise du tableau à retourner :
* - min = les données présentes dans la table
* - max = les données de la table + les informations complémentaires (pour les identifiants et les codes)
* - oss = la liste des nom_sci (uniquement pour noms et taxons)
*/
protected $retour_format = 'max';
 
/**
* Si "objet", renverra un objet dont les clefs sont les codes de départements;
* Si "liste", renverra une liste qui a le mérite de conserver l'ordre !
*/
protected $retour_type = 'objet';
 
/** Valeur du paramètre de requete recherche :
* - stricte : le masque est passé tel quel à l'opérateur LIKE.
* - etendue : ajout automatique du signe % à la place des espaces et en fin de masque avec utilisation de LIKE.
* - floue : recherche tolérante vis-à-vis d'approximations ou d'erreurs (fautes d'orthographe par exemple) */
protected $recherche;
 
/** Permet de stocker le tableau de résultat (non encodé en json) */
protected $table_retour = array();
 
/** Stocke le nombre total de résultats de la requete principale. Est calculée lors de l'assemblage de la requete */
protected $total_resultat;
 
// +-----------------------------------------------------------------------------------------------------+
public function traiterParametres() {
if (isset($this->parametres) && !empty($this->parametres)) {
$this->table_param = $this->parametres;
 
// masque : filtre la liste en fonction d'un masque de recherche portant sur le code, le nom ou la region.
// masque.code : filtre uniquement sur le code. masque.nom : filtre uniquement sur le nom.
// masque.region : filtre uniquement sur la region.
if (isset($this->parametres['recherche']) && $this->parametres['recherche'] != '') {
$this->recherche = $this->parametres['recherche'];
}
 
foreach ($this->parametres as $param => $valeur) {
switch ($param) {
case 'masque' :
$this->ajouterLeFiltreMasque('masque', $valeur);
break;
case 'masque.code' :
$this->ajouterLeFiltreMasque('dep', $valeur);
break;
case 'masque.nom' :
if ($valeur !== '') {
$this->ajouterLeFiltreMasque('nccenr', $valeur);
}
break;
case 'masque.region' :
$this->ajouterLeFiltreMasque('region', $valeur);
break;
case 'retour.format' :
$this->retour_format = $valeur;
break;
case 'retour.type' :
if (in_array($valeur, array('objet', 'liste')))
$this->retour_type = $valeur;
break;
case 'retour.tri' :
if ($valeur != '' ) {
if (in_array($valeur, array_keys($this->corres_tri))) {
$this->tri = $this->corres_tri[$valeur];
} else {
$this->tri = $valeur; // au petit bonheur la chance
}
}
break;
case 'retour.ordre' :
if (in_array(strtoupper($valeur), array('ASC', 'DESC')))
$this->ordre = $valeur;
break;
case 'navigation.depart' :
if ($valeur != '')
$this->limite_requete['depart'] = $valeur;
break;
case 'navigation.limite' :
if ($valeur != '')
$this->limite_requete['limite'] = $valeur;
break;
case 'recherche' :
break;
default :
$p = '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, $p);
}
}
}
}
 
public function ajouterLeFiltreMasque($nom_champ, $valeur) {
if ($nom_champ == 'dep' || $nom_champ == 'region') {
$this->requete_condition[] = $nom_champ.' = '.$this->getBdd()->proteger($valeur);
} else {
if ($this->recherche == 'floue') {
if ($nom_champ == 'masque') {
$this->requete_condition[] = '( dep = '.$this->getBdd()->proteger($valeur)
.' OR region = '.$this->getBdd()->proteger($valeur)
.' OR ( SOUNDEX(nccenr) = SOUNDEX(\''.$valeur.'\')'
.' OR SOUNDEX(REVERSE(nccenr)) = SOUNDEX(REVERSE(\''.$valeur.'\')) '
.')) ';
} else {
$this->requete_condition[] = '(SOUNDEX('.$nom_champ.') = SOUNDEX(\''.$valeur.'\')'
.' OR SOUNDEX(REVERSE('.$nom_champ.')) = SOUNDEX(REVERSE(\''.$valeur.'\'))) ';
}
} else {
if ($this->recherche == 'etendue') {
$valeur = str_replace(' ','%', $valeur);
$valeur .= '%';
}
 
if ($nom_champ == 'masque') {
$this->requete_condition[] = ' (dep = '.$this->getBdd()->proteger($valeur)
.' OR nccenr LIKE '.$this->getBdd()->proteger($valeur)
.' OR region = '.$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)) {
$this->table_ressources = $this->ressources;
if (isset($this->table_ressources[0]) && !empty($this->table_ressources[0])) {
//requete = /zone-geo/#id
$this->traiterRessourceId();
if (isset($this->table_ressources[1]) && !empty($this->table_ressources[1])) {
//dans le cas /zone-geo/#id/#champ ou /zone-geo/#id/relations
$this->traiterRessourceChampOuRelations();
}
}
}
}
 
//requete : /zone-geo/#id (ex : /zone-geo/7)
public function traiterRessourceId() {
if (is_numeric($this->table_ressources[0])) {
$this->requete_condition[] = ' dep = '.$this->getBdd()->proteger($this->table_ressources[0]);
$this->format_reponse .= '/id';
} else {
$r = 'Erreur dans les ressources de votre requête : </br> La ressource " '.$this->table_ressources[0].
' " n\'existe pas.';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r);
}
}
 
 
public function traiterRessourceChampOuRelations() {
//requete = /zone-geo/#id/relations :
if ($this->table_ressources[1] == 'relations') {
$this->format_reponse .= '/relations';
$this->requete_condition[] = 'region = (SELECT region FROM '.$this->table.' WHERE '
.implode(' AND ', $this->requete_condition).')';
//requete = /zone-geo/#id/#champ :
} else {
$this->format_reponse .= '/champ';
}
}
 
//+------------------------------------------------------------------------------------------------------+
public function assemblerLaRequete() {
//assemblage de la requete :
$requete = ' SELECT '.$this->requete_champ.
' FROM '.$this->table
.$this->formerRequeteCondition()
. ' ORDER BY ' . $this->tri . ' ' . $this->ordre
.$this->formerRequeteLimite();
return $requete;
}
 
public function formerRequeteCondition() {
$condition = '';
if ($this->requete_condition != null) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
 
 
//ajout d'une limite seulement pour les listes (pas plus de 100 resultats retournés pr les requetes
// suivantes : /zone-geo et /zone-geo/#id/relations)
public function formerRequeteLimite() {
if ($this->format_reponse != 'zone-geo' && $this->format_reponse != 'zone-geo/id/relations') {
$this->requete_limite = '';
} else {
$this->total_resultat = $this->recupererTotalResultat();
$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 /zone-geo)
$requete = 'SELECT count(*) as nombre FROM '
.$this->table
.$this->formerRequeteCondition();
$res = $this->getBdd()->recuperer($requete);
 
if ($res) {
$total = $res['nombre'];
} else {
$t = 'Fonction recupererTotalResultat() : <br/>Données introuvables dans la base';
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $t);
}
return $total;
}
 
//+------------------------------------------------------------------------------------------------------+
// determine en fct du service appelé (/zone-geo | /zone-geo/#id | /zone-geo/#id/champ |
// /zone-geo/#id/relations) le format du tableau à retourner.
public function retournerResultatFormate($resultat) {
$this->recupererTableConfig('correspondance_champs');
switch ($this->format_reponse) {
case 'zone-geo' : $reponse = $this->formaterZoneGeo($resultat); break;
case 'zone-geo/id' : $reponse = $this->formaterZoneGeoId($resultat[0]); break;
case 'zone-geo/id/champ' : $reponse = $this->formaterZoneGeoIdChamp($resultat[0]); break;
case 'zone-geo/id/relations' : $reponse = $this->formaterZoneGeoIdRelations($resultat); break;
default : break;
}
return $reponse;
}
 
public function formaterZoneGeo($resultat) {
//on remplit la table $table_retour_json['entete']
$this->table_retour['depart'] = $this->limite_requete['depart'];
$this->table_retour['limite'] = $this->limite_requete['limite'];
$this->table_retour['total'] = $this->total_resultat;
$url = $this->formulerUrl($this->total_resultat, '/zone-geo');
if (isset($url['precedent']) && $url['precedent'] != '') { $this->table_retour['href.precedent'] = $url['precedent']; }
if (isset($url['suivant']) && $url['suivant'] != '') { $this->table_retour['href.suivant'] = $url['suivant']; }
$table_retour_json['entete'] = $this->table_retour;
 
//on remplit la table $table_retour_json['resultat']
$this->table_retour = array();
if (isset($this->table_param['masque_nom'])) $resultat = $this->trierRechercheFloue($this->table_param['masque_nom'], $resultat, 'nccenr');
foreach ($resultat as $tab) {
foreach ($tab as $key => $valeur) {
if ($valeur != '') {
switch ($key) {
case 'dep' : $num = $valeur; $this->table_retour['code'] = $valeur; break;
case 'nccenr' : $this->table_retour['nom'] = $valeur; break;
default : break;
}
}
}
if ($this->retour_format == 'max') {
$this->table_retour['href'] = $this->ajouterHref('zone-geo', $num);
}
if ($this->retour_type == 'objet') {
$resultat_json[$num] = $this->table_retour;
} elseif ($this->retour_type == 'liste') {
$resultat_json[] = $this->table_retour;
}
$this->table_retour = array();
}
$table_retour_json['resultat'] = $resultat_json;
return $table_retour_json;
}
 
public function formaterZoneGeoId($resultat) {
foreach ($resultat as $key => $valeur) {
if ($valeur != '') {
$this->afficherDonnees($key, $valeur);
}
}
unset($this->table_retour['href']);
return $this->table_retour;
}
 
public function formaterZoneGeoIdRelations($resultat) {
if ($resultat == '') {
$retour = null;
} else {
//on remplit la table $table_retour_json['entete']
$this->table_retour['depart'] = $this->limite_requete['depart'];
$this->table_retour['limite'] = $this->limite_requete['limite'];
$this->table_retour['total'] = $this->total_resultat;
//formuler les urls
$url = $this->formulerUrl(count($resultat), '/zone-geo');
if ($url['precedent'] != '') { $this->table_retour['href.precedent'] = $url['precedent']; }
if ($url['suivant'] != '') { $this->table_retour['href.suivant'] = $url['suivant']; }
$retour['entete'] = $this->table_retour;
$this->table_retour = array();
 
//on remplit la table $table_retour_json['resultat']
foreach ($resultat as $tab) {
foreach ($tab as $key => $valeur) {
switch ($key) {
case 'dep' : $num = $valeur; $this->table_retour['code'] = $valeur; break;
case 'nccenr' : $this->table_retour['nom'] = $valeur; break;
default : break;
}
}
if ($this->retour_format == 'max') $this->table_retour['href'] = $this->ajouterHref('zone-geo', $num);
$resultat_json[$num] = $this->table_retour;
$this->table_retour = array();
}
$retour['resultat'] = $resultat_json;
}
return $retour;
}
 
public function formaterZoneGeoIdChamp($resultat) {
//on recupère tous les resultats possibles
$reponse = $this->formaterZoneGeoId($resultat);
$this->table_retour = array();
//on recupère les résultats demandés à partir du tableau de résultat complet
$this->table_retour['id'] = $reponse['code'];
$champs = explode(' ', $this->table_ressources[1]);
 
foreach ($champs as $champ) {
if ($this->verifierValiditeChamp($champ)) {
if (strrpos($champ, '.*') !== false) {
$this->afficherPointEtoile($champ, $reponse);
 
} else {
if (isset($reponse[$champ])) {
$this->table_retour[$champ] = $reponse[$champ];
} else {
$this->table_retour[$champ] = null;
}
}
}
}
return $this->table_retour;
}
 
public function verifierValiditeChamp($champ) {
preg_match('/^([^.]+)(\.([^.]+))?$/', $champ, $match);
$champs_possibles = $this->correspondance_champs;
$champs_possibles[] = 'nom.*';
 
if (in_array($match[1], $champs_possibles)) {
$validite = true;
} elseif (in_array($match[0], $champs_possibles)) {
$validite = true;
} else {
$champs_possibles = implode('</li><li>', $champs_possibles);
$c = 'Erreur dans votre requête : </br> Le champ "'.$champ_possibles.'" n\'existe pas. '.
'Les champs disponibles sont : <li>'.$champs_possibles.'</li>';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $c);
}
return $validite;
}
 
public function afficherPointEtoile($champ, $reponse) {
preg_match('/^([^.]+\.)\*$/', $champ, $match);
foreach ($reponse as $chp => $valeur) {
if (strrpos($chp, $match[1]) !== false) {
if ($valeur != '') {
$this->table_retour[$chp] = $valeur;
} else {
$this->table_retour[$chp] = null;
}
}
}
}
 
public function afficherDonnees($champ, $valeur) {
if ($this->retour_format == 'max') {
if ($champ == 'region' || $champ == 'chef_lieu') {
$projet = 'insee-'.substr($champ, 0, 1);
$this->table_retour[$champ.'.code'] = $valeur;
$this->table_retour[$champ.'.href'] = $this->ajouterHrefAutreProjet('zone-geo', '', $valeur, $projet);
} elseif ($champ == 'tncc') {
$url = $this->ajouterHref('ontologies', $valeur);
$res = $this->consulterHref($url);
$this->table_retour['type_nom'] = $res->nom;
$this->table_retour['type_nom.code'] = $valeur;
$this->table_retour['type_nom.href'] = $url;
} else {
$this->table_retour[$this->correspondance_champs[$champ]] = $valeur;
}
} else {
$this->table_retour[$this->correspondance_champs[$champ]] = $valeur;
}
}
 
}
 
?>
/tags/v5.12-baouque/services/modules/0.1/nvps/NomsVernaculaires.php
New file
0,0 → 1,652
<?php
/**
* Description :
* Classe NomsVernaculaires.php fournit une liste de noms vernaculaires et leur liaison à la bdtfx
* 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 langue et
* une relation avec un taxon de la bdtfx.
* Si l'url finit par /noms-vernaculaires on retourne une liste de noms (seulement les 100 premières par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /observations?param1=val1&param2=val2&...
*
* Les paramètres de requête disponibles sont : masque, masque.code, masque.nom, masque.region , recherche,
* distinct, retour.format, navigation.depart et navigation.limite.
*
* Encodage en entrée : utf8
* Encodage en sortie : utf8
* @package framework-v3
* @author Delphine Cauquil <delphine@tela-botanica.org>
* @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 NomsVernaculaires extends Commun {
protected $champ_infos = array(
'taxon' => array('service' => 'taxons', 'ressource' => 'nt:', 'projet' => 'bdtfx', 'nom' => 'nom_sci'));
 
protected $service = 'noms-vernaculaires';
 
/**
* Permet de stocker la requete formulée : /noms-vernaculaires | /noms-vernaculaires/#id |
* /noms-vernaculaires/#id/champ | /noms-vernaculaires/#id/relations
* Est remplit au cours de l'analyse des ressources (traiterRessources()), par défaut, a la valeur du service.
* Est utilisée principalement pr déterminer le format du tableau à retourner. */
protected $format_reponse = 'noms-vernaculaires';
 
/** Variables constituant les parametres de la requete SQL (champ, condition, limit) remplie
* selon ressources et paramètres */
protected $requete_champ = array(' * ');
protected $requete_condition = '';
protected $limite_requete = array(
'depart' => 0,
'limite' => 100
);
protected $champ_tri = 'code_langue';
protected $direction_tri = 'asc';
/**
* Indique les champs supplémentaires à retourner
* - conseil_emploi = conseil d'emploi du nom vernaculaire
* - genre = genre et nombre du nom
* - taxon = nom retenu associé à ce nom
*/
protected $champs_supp = array();
 
/**
* Precise la contenance plus ou moins précise du tableau à retourner :
* - min = les données présentes dans la table
* - max = les données de la table + les informations complémentaires (pour les identifiants et les codes)
* - oss = la liste des nom_sci (uniquement pour noms et taxons) */
protected $retour_format = 'max';
/** Valeur du paramètre de requete recherche :
* - stricte : le masque est passé tel quel à l'opérateur LIKE.
* - etendue : ajout automatique du signe % à la place des espaces et en fin de masque avec utilisation de LIKE.
* - floue : recherche tolérante vis-à-vis d'approximations ou d'erreurs (fautes d'orthographe par exemple) */
protected $recherche;
/** Permet de stocker le tableau de résultat (non encodé en json) */
protected $table_retour = array();
/** 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 $config;
public function __construct($config) {
$this->config = is_null($config) ? Config::get('NomsVernaculaires') : $config;
}
 
//+------------------------------------------------------------------------------------------------------+
// créer une condition en fonction du paramétre
public function traiterParametres() {
if (isset($this->parametres) && !empty($this->parametres)) {
 
if (isset($this->parametres['recherche']) && $this->parametres['recherche'] != '') {
$this->recherche = $this->parametres['recherche'];
}
foreach ($this->parametres as $param => $valeur) {
switch ($param) {
case 'masque' :
$this->ajouterFiltreMasque('nom_vernaculaire', $valeur);
break;
case 'masque.nt' :
$this->ajouterFiltreMasque('num_taxon', $valeur);
break;
case 'masque.nv' :
$this->ajouterFiltreMasque('nom_vernaculaire', $valeur);
break;
case 'masque.lg' :
$this->ajouterFiltreMasque('code_langue', $valeur);
break;
case 'masque.cce' :
$this->ajouterFiltreMasque('num_statut', $valeur);
break;
case 'retour.format' :
$this->retour_format = $valeur;
break;
case 'navigation.depart' :
$this->limite_requete['depart'] = $valeur;
break;
case 'navigation.limite' :
$this->limite_requete['limite'] = $valeur;
break;
case 'retour.champs' :
$this->champs_supp = explode(',',$valeur);
break;
case 'recherche' :
break;
case 'version.projet' :
break;
default :
$p = '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, $p);
}
}
}
}
 
public function ajouterFiltreMasque($nom_champ, $valeur) {
if ($nom_champ == 'num_taxon') { // si il s'agit d'un chiffre
$this->requete_condition[] = $nom_champ.' = '.$this->getBdd()->proteger($valeur);
} else {
if ($this->recherche == 'floue') {
$this->requete_condition[] = '(SOUNDEX('.$nom_champ.') = SOUNDEX(\''.$valeur.'\')'
.' OR SOUNDEX(REVERSE('.$nom_champ.')) = SOUNDEX(REVERSE(\''.$valeur.'\'))) ';
} else {
if ($this->recherche == 'etendue') {
$valeur = '%'.str_replace(' ','% ', $valeur);
$valeur .= '%';
}
$this->requete_condition[] = $nom_champ.' LIKE '.$this->getBdd()->proteger($valeur);
}
}
}
 
//+------------------------------------------------------------------------------------------------------+
// en fonction de la présence des ressources modifie requete_champ et requete_condition
public function traiterRessources() {
if (isset($this->ressources) && !empty($this->ressources)) {
if (isset($this->ressources[0]) && !empty($this->ressources[0])) {
$this->traiterRessourceId(); // ajoute condition id=#valeur
if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
$this->traiterRessourceChamp(); //modifie requete_champ ou requete_condition
}
}
} else { //rajoute distinct pour ne pas avoir plusieurs fois le même nom
$this->requete_champ = array('distinct(id)', 'nom_vernaculaire ');
}
}
 
//requete : /noms-vernaculaires/#id (ex : /noms-vernaculaires/7)
public function traiterRessourceId() {
if (is_numeric($this->ressources[0])) {
$this->requete_condition[] = ' id = '.$this->getBdd()->proteger($this->ressources[0]);
$this->format_reponse .= '/id';
} elseif ($this->ressources[0] == 'attributions') {
$this->format_reponse .= '/attributions';
} else {
$r = 'Erreur dans les ressources de votre requête : </br> La ressource " '.$this->ressources[0].
' " n\'existe pas.';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r);
}
}
 
 
public function traiterRessourceChamp() {
$this->format_reponse .= '/champ';
$this->analyserChamp();
}
 
public function analyserChamp() {
$this->requete_champ = array();
$this->recupererTableConfig('champs_possibles');// s'il y a plusieurs champs correspondant au champ demandé ils sont séparé par des |
$champs = explode(' ', $this->ressources[1]);
foreach ($champs as $champ) {
preg_match('/^([^.]+)(\.([^.]+))?$/', $champ, $match);
if (isset($this->champs_possibles[$match[1]])) {
$this->requete_champ[] = str_replace('|', ', ', $this->champs_possibles[$match[1]]);
} elseif (isset($this->champs_possibles[$match[0]])) {
$this->requete_champ[] = str_replace('|', ', ', $this->champs_possibles[$match[0]]);
} else {
$champs_possibles = implode('</li><li>', array_keys($this->champs_possibles));
$c = 'Erreur dans votre requête : </br> Le champ "'.$champ_possibles.'" n\'existe pas. '.
'Les champs disponibles sont : <li>'.$champs_possibles.'</li> et leurs déclinaisons (ex. ".code").';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $c);
}
}
}
 
//+------------------------------------------------------------------------------------------------------+
public function assemblerLaRequete() {
$requete = ' SELECT '.$this->formerRequeteChamp().
' FROM '.$this->table
.$this->formerRequeteCondition()
.$this->formerRequeteLimite();
return $requete;
}
 
public function formerRequeteChamp() {
if (in_array('*', $this->requete_champ)) {
$champ = ' * ';
} else {
$champ = implode(', ', $this->requete_champ);
}
return $champ;
}
 
public function formerRequeteCondition() {
$condition = '';
if ($this->requete_condition != null) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
 
//ajout d'une limite seulement pour les listes (pas plus de 100 resultats retournés pr les requetes
// suivantes : /noms-vernaculaires et /noms-vernaculaires/#id/relations)
public function formerRequeteLimite() {
if (in_array($this->format_reponse , array($this->service.'/id', $this->service.'/id/champs'))) {
$this->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
$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;
}
 
//on récupère le nombre total de résultats de la requete (ex : le nombre d'id contenu dans la liste /noms-vernaculaires)
public function recupererTotalResultat() {
$distinct = ($this->format_reponse == 'noms-vernaculaires/attributions') ? 'id' : 'distinct(id)';
$requete = 'SELECT count('.$distinct.') as nombre FROM '
.$this->table
.$this->formerRequeteCondition();
$res = $this->getBdd()->recuperer($requete);
 
if ($res) {
$total = $res['nombre'];
} else {
$t = 'Fonction recupererTotalResultat() : <br/>Données introuvables dans la base '.$requete;
$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $t);
}
return $total;
}
 
//+------------------------------------------------------------------------------------------------------+
// determine en fct du service appelé (/noms-vernaculaires | /noms-vernaculaires/#id | /noms-vernaculaires/#id/champ |
// /noms-vernaculaires/#id/relations) le format du tableau à retourner.
public function retournerResultatFormate($resultat) {
$this->recupererTableConfig('correspondance_champs');
switch ($this->format_reponse) {
case 'noms-vernaculaires' :
$reponse = ($this->retour_format == 'oss') ? $this->formaterEnOss($resultat) : $this->formaterNomsVernaculaires($resultat); break;
case 'noms-vernaculaires/attributions' : $reponse = $this->formaterNomsVernaculairesAttributions($resultat); break;
case 'noms-vernaculaires/id' : $reponse = $this->formaterNomsVernaculairesId($resultat); break;
case 'noms-vernaculaires/id/champ' : $reponse = $this->formaterNomsVernaculairesIdChamp($resultat); break;
default : break;
}
return $reponse;
}
public function ajouterJsonEnTeteNV() {
$table_retour_json['masque'] = $this->recupererMasque();
$table_retour_json['depart'] = $this->limite_requete['depart'];
$table_retour_json['limite'] = $this->limite_requete['limite'];
$table_retour_json['total'] = $this->total_resultat;
$url = $this->formulerUrl($this->total_resultat, '/noms-vernaculaires');
if (isset($url['precedent']) && $url['precedent'] != '') {
$table_retour_json['href.precedent'] = $url['precedent'];
}
if (isset($url['suivant']) && $url['suivant'] != '') {
$table_retour_json['href.suivant'] = $url['suivant'];
}
return $table_retour_json;
}
public function ajouterJsonResultatNV($resultat) {
foreach ($resultat as $tab) {
foreach ($tab as $key => $valeur) {
if ($valeur != '') {
switch ($key) {
case 'id' : $num = $valeur; break;
case 'nom_vernaculaire' : $this->table_retour['nom'] = $valeur; break;
default : break;
}
}
}
if ($this->retour_format == 'max') $this->table_retour['href'] = $this->ajouterHref('noms-vernaculaires', $num);
$resultat_json[$num] = $this->table_retour;
$this->table_retour = array();
}
return $resultat_json;
}
 
public function formaterNomsVernaculaires($resultat) {
$table_retour_json['entete'] = $this->ajouterJsonEnTeteNV();
$resultat = $this->hierarchiserResultat($resultat);
$table_retour_json['resultat'] = $this->ajouterJsonResultatNV($resultat);
return $table_retour_json;
}
public function hierarchiserResultat($resultat) {
//tri recherche floue
if (isset($this->parametres['masque.nv'])) {
$resultat = $this->trierRechercheFloue($this->parametres['masque.nv'], $resultat, 'nom_vernaculaire');
}
if (isset($this->parametres['masque'])) {
$resultat = $this->trierRechercheFloue($this->parametres['masque'], $resultat, 'nom_vernaculaire');
}
return $resultat;
}
public function recupererMasque() {
$tab_masque = array();
foreach ($this->parametres as $param=>$valeur) {
if (strstr($param, 'masque') != false) {
$tab_masque[] = $param.'='.$valeur;
}
}
$masque = implode('&', $tab_masque);
return $masque;
}
public function formaterEnOss($resultat) {
$table_nom = array();
$oss = '';
foreach ($resultat as $tab) {
if (isset($tab['nom_vernaculaire']) ) {
if (!in_array($tab['nom_vernaculaire'], $table_nom)) {
$table_nom[] = $tab['nom_vernaculaire'];
$oss [] = $tab['nom_vernaculaire'];
}
}
}
if (isset($this->masque)) $masque = implode('&', $this->masque);
else $masque = 'Pas de masque';
$table_retour_oss = array($masque, $oss);
return $table_retour_oss;
}
public function formaterNomsVernaculairesAttributions($resultat) {
//on remplie la table $table_retour_json['entete']
$table_retour_json['entete']['masque'] = $this->recupererMasque();
$table_retour_json['entete']['depart'] = $this->limite_requete['depart'];
$table_retour_json['entete']['limite'] = $this->limite_requete['limite'];
$table_retour_json['entete']['total'] = $this->total_resultat;
$url = $this->formulerUrl($this->total_resultat, '/noms-vernaculaires/attributions');
if (isset($url['precedent']) && $url['precedent'] != '') {
$table_retour_json['entete']['href.precedent'] = $url['precedent'];
}
if (isset($url['suivant']) && $url['suivant'] != '') {
$table_retour_json['entete']['href.suivant'] = $url['suivant'];
}
foreach ($resultat as &$tab) {
$resultat_json[$tab['id']]['id'] = $tab['id'];
$resultat_json[$tab['id']]['nom_vernaculaire'] = $tab['nom_vernaculaire'];
$resultat_json[$tab['id']]['code_langue'] = $tab['code_langue'];
$resultat_json[$tab['id']]['taxon.code'] = 'bdtfx.nt:'.$tab['num_taxon'];
if ($this->retour_format == 'max') {
$resultat_json[$tab['id']]['num_taxon'] = $tab['num_taxon'];
$resultat_json[$tab['id']]['nom_retenu.code'] = $tab['num_taxon'];
$resultat_json[$tab['id']]['taxon'] = $tab['num_taxon'];
$this->taxons[] = $tab['num_taxon']; // utilisé pour chercher les noms latins plus bas
$resultat_json[$tab['id']]['href'] = $this->ajouterHref('noms-vernaculaires', $tab['id']);
if($this->champs_supp != array()) {
$resultat_json[$tab['id']] = $this->ajouterChampsOntologieLigneResultat($tab);
}
}
}
if ($this->retour_format == 'max') {
// On est obligé de faire un deuxième boucle pour demander tous les taxons présents en une
// fois et les attribuer aux noms car c'est beaucoup plus rapide
$noms_sci = $this->recupererNomTaxons();
foreach ($resultat_json as $num_nom => &$tab) {
$tab = $this->ajouterTaxonsAttributionsLigneResultat($tab, $noms_sci);
if($tab == null) {
unset($resultat_json[$num_nom]);
}
}
}
uasort($resultat_json, array($this,'trierLigneTableau'));
$table_retour_json['resultat'] = $resultat_json;
return $table_retour_json;
}
/**
* Ajoute les champs d'ontologie supplémentaires si necéssaire
* en faisant appels aux web services associés
* @param array $ligne_resultat
*
* @return array la ligne modifiée
*/
public function ajouterChampsOntologieLigneResultat($ligne_resultat) {
$intitule = '';
foreach($this->champ_infos as $cle => $champs_supplementaires) {
if(in_array($cle, $this->champs_supp)) {
extract($champs_supplementaires);
$valeur_recherche = '';
switch($cle) {
case 'taxon':
$valeur_recherche = $ligne_resultat['num_taxon'];
$intitule = 'taxon.code';
break;
}
$code_valeur = '';
if(trim($valeur_recherche) != '') {
$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur_recherche, $projet);
$code_valeur = $this->chercherSignificationCode($url, $nom);
}
$ligne_resultat[$intitule] = $code_valeur;
}
}
return $ligne_resultat;
}
/**
* Fonction qui ajoute les attributions à une ligne de résultats
*
* @param array $ligne_tableau_resultat
* @param array $nom_sci
*/
public function ajouterTaxonsAttributionsLigneResultat(&$ligne_tableau_resultat, &$noms_sci) {
if (isset($noms_sci[$ligne_tableau_resultat['num_taxon']])) {
$ligne_tableau_resultat['nom_retenu.code'] = $noms_sci[$ligne_tableau_resultat['num_taxon']]['id'];
$ligne_tableau_resultat['taxon'] = $noms_sci[$ligne_tableau_resultat['num_taxon']]['nom_sci'];
} else {
$ligne_tableau_resultat = null;
}
return $ligne_tableau_resultat;
}
private function trierLigneTableau($a, $b) {
$retour = 0;
if ($a[$this->champ_tri] == $b[$this->champ_tri]) {
$retour = 0;
}
if($this->champ_tri == 'code_langue') {
if ($a[$this->champ_tri] == 'fra' && $b[$this->champ_tri] != 'fra') {
$retour = ($this->direction_tri == 'asc') ? -1 : 1;
} else if ($a[$this->champ_tri] != 'fra' && $b[$this->champ_tri] == 'fra') {
$retour = ($this->direction_tri == 'asc') ? 1 : -1;
} else {
$retour = $this->comparerChaineSelonDirectionTri($a[$this->champ_tri], $b[$this->champ_tri]);
}
} else {
$retour = $this->comparerChaineSelonDirectionTri($a[$this->champ_tri], $b[$this->champ_tri]);
}
return $retour;
}
private function comparerChaineSelonDirectionTri($a, $b) {
if($this->direction_tri == 'asc') {
return ($a < $b) ? -1 : 1;
} else {
return ($a > $b) ? -1 : 1;
}
}
// formatage de la reponse /id ss la forme
// id, nom_vernaculaire, attributions
// langue
// num_nom (correspond à un taxon bdtfx)
public function formaterNomsVernaculairesId($resultat) {
foreach ($resultat as $taxon) { // pour chaque attribution à un taxon bdtfx
// on crée les variables qui serviront de clés et on les enléves du tableau
$num_nom = $taxon['id']; // unique pour un trinôme id, langue, taxon
$langue = $taxon['code_langue'];
unset($taxon['code_langue']);
 
foreach ($this->correspondance_champs as $key => $correspondance) { // ordonne les infos pour affichage
if (isset($taxon[$key]) && $taxon[$key] != "") {
$this->afficherDonnees($correspondance, $taxon[$key], $langue, $num_nom);
}
}
foreach ($taxon as $key => $valeur) { // rajoute les champs non prévus dans l'api
if (!isset($this->correspondance_champs[$key]) && $valeur != "") {
$this->afficherDonnees($key, $valeur, $langue, $num_nom);
}
}
}
if ($this->retour_format == 'max') $this->afficherTaxons(); // va chercher les noms de tous les taxons
unset($this->table_retour['href']);
return $this->table_retour;
}
 
public function afficherDonnees($champ, $valeur, $langue = '', $num_nom = '') {
if ($champ == 'id' || $champ == 'nom_vernaculaire') {
$this->table_retour[$champ] = $valeur;
} elseif (preg_match('/^(.*)\.code$/', $champ, $match)) {
switch ($match[1]) {
case 'taxon' : if ($this->retour_format == 'max') {$this->taxons[$num_nom] = $valeur;}
$this->afficherPointCode($match[1], $langue, $num_nom, $valeur); break;
case 'langue' : //$this->afficherPointCode($match[1], 'iso-639-3', 'langues', $valeur);
break;
default : break;
}
 
} elseif ($langue != '') {
$this->table_retour['attributions'][$langue][$num_nom][$champ] = $valeur;
} else {
$this->table_retour[$champ] = $valeur;
}
}
 
public function afficherPointCode($nomChamp, $langue, $num_nom, $valeur) {
if (isset($this->champ_infos[$nomChamp])) {
extract($this->champ_infos[$nomChamp]);
}
 
if ($this->retour_format == 'max') {
$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur, $projet);
if ($service == 'taxons') {
$code_valeur = '';
$this->table_retour['attributions'][$langue][$num_nom]['nom_retenu.code'] = $code_valeur;
} else {
$code_valeur = $this->chercherSignificationCode($url, $nom);
}
if ($projet != '') $projet .= '.';
$this->table_retour['attributions'][$langue][$num_nom][$nomChamp] = $code_valeur;
$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.code'] = $projet.$ressource.$valeur;
$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.href'] = $url;
} else {
if ($projet != '') $projet .= '.';
$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.code'] = $projet.$ressource.$valeur;
}
}
 
public function chercherSignificationCode($url, $nom) {
if (isset($this->signification_code[$url])) {
$valeur = $this->signification_code[$url];
} else {
$res = $this->consulterHref($url);
$valeur = $res->$nom;
$this->signification_code[$url] = $valeur;
}
return $valeur;
}
 
public function afficherTaxons() {
$resultat = $this->recupererNomTaxons();
foreach ($this->table_retour['attributions'] as $code_langue=>$langue) {
foreach ($langue as $num_nom=>$taxon) {
$num_tax = ltrim($taxon['taxon.code'], 'bdtfx.nt:');
if (isset($resultat[$num_tax])) {
$this->table_retour['attributions'][$code_langue][$num_nom]['nom_retenu.code'] = $resultat[$num_tax]['id'];
$this->table_retour['attributions'][$code_langue][$num_nom]['taxon'] = $resultat[$num_tax]['nom_sci'];
}
}
}
}
public function recupererNomTaxons() {
$taxons = array_unique($this->taxons);
$url = Config::get('url_service_base').'bdtfx/taxons?navigation.limite=500&ns.structure=au&masque.nt='.implode(',', $taxons);
$res = $this->consulterHref($url);
foreach ($res->resultat as $id=>$taxon) {
$resultat[$taxon->num_taxonomique]['id'] = 'bdtfx.nn:'.$id;
$resultat[$taxon->num_taxonomique]['nom_sci'] = $taxon->nom_sci_complet;
}
return $resultat;
}
 
public function formaterNomsVernaculairesIdChamp($resultat) {
$this->table_retour['id'] = $this->ressources[0];
$champs = explode(' ', $this->ressources[1]);
if (in_array('attributions', $champs) != false) {
$this->formaterNomsVernaculairesId($resultat);
unset($this->table_retour['nom_vernaculaire']);
} else {
$champ_attributions = array('num_taxon', 'genre', 'notes');
foreach ($resultat as $taxon) {
foreach ($taxon as $key=>$valeur) {
if ($key == 'code_langue' && in_array('langue', $champs) != false) {
$this->table_retour['attributions']['langue'][] = $valeur;
} elseif (in_array($key, $champ_attributions) != false) {
$this->afficherPoint($this->correspondance_champs[$key] , $valeur, $taxon['code_langue'], $taxon['id']);
} elseif (in_array($key, $champs) != false) {
$this->table_retour[$key] = $valeur;
}
}
}
}
return $this->table_retour;
}
 
public function afficherPoint($champ, $valeur, $langue, $num_nom) {
preg_match('/^(.*)\.code$/', $champ, $match);
$champ = $match[1];
if (isset($this->champ_infos[$champ])) {
extract($this->champ_infos[$champ]);
$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur, $projet);
$projet .= '.';
}
 
$champs = explode(' ', $this->ressources[1]);
if (in_array($champ.'.*', $champs) !== false && isset($projet)) {
$this->table_retour['attributions'][$langue][$num_nom][$champ.'.code'] = $projet.$ressource.$valeur;
$this->table_retour['attributions'][$langue][$num_nom][$champ.'.href'] = $url;
}
if (in_array($champ.'.code', $champs) !== false && isset($projet)) {
$this->table_retour['attributions'][$langue][$num_nom][$champ.'.code'] = $projet.$ressource.$valeur;
}
if (in_array($champ.'.href', $champs) !== false && isset($projet)) {
$this->table_retour['attributions'][$langue][$num_nom][$champ.'.href'] = $url;
}
if (in_array($champ, $champs) !== false) {
if (isset($url)) {
$this->table_retour['attributions'][$langue][$num_nom][$champ] = $this->chercherSignificationCode($url, $nom);
} else {
$this->table_retour['attributions'][$langue][$champ] = $valeur;
}
}
}
 
public function afficherLangue($nomChamp, $projet, $service, $valeur, $ressource = '', $nom = 'nom') {
if ($this->retour_format == 'max') {
$this->table_retour['attributions'][$nomChamp] = $nom;
$this->table_retour['attributions'][$nomChamp.'.code'] = $projet.$ressource.$valeur;
$this->table_retour['attributions'][$nomChamp.'.href'] = $url;
} else {
$this->table_retour['attributions'][$nomChamp.'.code'] = $projet.$ressource.$valeur;
}
}
 
 
}
?>
/tags/v5.12-baouque/services/modules/0.1/baseflor/GraphiquesTaxonsSup.php
New file
0,0 → 1,146
<?php
/**
* Classe GraphiquesTaxonsSup.php transforme les données écologiques de la table baseflor_rang_sup_ecologie
* en graphique svg
* graphiques/#typegraphique/#bdnt.nn:#num_nomen --> renvoie un graphique avec les données connues
*
*
* @package eflore-projets
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @author Mathilde SALTHUN-LASSALLE <mathilde@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)
*/
 
class GraphiquesTaxonsSup extends CommunGraphiques{
 
 
public function definirTable($version){
$this->table = Config::get('bdd_table_rang_sup')."_v".$version;
}
//+---- ressources ----+
public function traiterReferentieletNum(){
if (!empty($this->ressources[1])) {
if(preg_match('/^(.+)\.nn:([0-9]+)$/', $this->ressources[1], $retour) == 1){
switch ($retour[1]) {
case 'bdtfx' : // pour le moment un seul referentiel disponible
$this->requete_condition[]= "num_nomen = ".$retour[2]." AND bdnt = 'bdtfx' ";
break;
default :
$e = "Le référentiel {$retour[1]} n'existe pas.";
throw new Exception( $e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
break;
}
}else {
$e = "Erreur dans l'url de votre requête :".
" précisez le référentiel et le numéro nomenclatural sous la forme {bdnt}.nn:{nn}.";
throw new Exception( $e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
} else {
throw new Exception( "Erreur dans l'url de votre requête :".
" précisez le référentiel et le numéro nomenclatural sous la forme {bdnt}.nn:{nn}.",
RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
public function traiterTypeGraphique(){
if (!empty($this->ressources[0])) {
switch ($this->ressources[0]) {
case 'climat' :
$this->requete_champs = ' ve_lumiere_min, ve_lumiere_max, ve_temperature_min,'.
' ve_temperature_max, ve_continentalite_min,'.
' ve_continentalite_max, ve_humidite_atmos_min,'.
' ve_humidite_atmos_max' ;
$this->nomGraphique= 'climat_min_max';
break;
case 'sol' :
$this->requete_champs = ' ve_humidite_edaph_min , ve_humidite_edaph_max,'.
' ve_reaction_sol_min, ve_reaction_sol_max, '.
' ve_nutriments_sol_min, ve_nutriments_sol_max,'.
' ve_salinite_min, ve_salinite_max,'.
' ve_texture_sol_min, ve_texture_sol_max,'.
've_mat_org_sol_min,ve_mat_org_sol_max ' ;
$this->nomGraphique = 'sol_min_max';
break;
default :
$e = "Erreur dans l'url de votre requête :".
"</br> précisez le graphique -> \"sol\" ou \"climat\".";
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
break;
}
}else {
throw new Exception("Erreur dans l'url de votre requête :".
"</br> precisez le graphique -> \"sol\" ou \"climat\".", RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
//+-------------------------- formatage du résultat -------------------------------------------+
public function changerValeursSVG(){
$this->ajouterValeursIntermediaires();
$Dompath = new DOMXPath($this->dom);
foreach ($this->valeurs_en_pourcentage as $cle => $val){
$val = preg_replace('/,/','.', $val);
$grad_id = array_search($val,$this->graduations_id);
$champs = preg_replace('/_min|_max|_[0-9]/','', $cle);
// dans le cas de mauvaises données, pour ne pas que tout le graphique
$case = $Dompath->query("//*[@id='".$grad_id."_".$champs."']")->item(0);
if($case != null) {
$case->setAttribute('fill','#EA6624');
$case->setAttribute('stroke','#EA6624');
$this->ajouterInfoAuSurvol($champs,$case);
}
$changement = true;
}
$this->ajusterFormatSVG();
}
public function ajouterValeursIntermediaires(){
$champs_ecolo = array_keys($this->champs_ontologiques);
foreach ($champs_ecolo as $chps ){
$min = !empty($this->valeurs_en_pourcentage[$chps.'_min']) ? $this->valeurs_en_pourcentage[$chps.'_min'] : -1;
$max = !empty($this->valeurs_en_pourcentage[$chps.'_max']) ? $this->valeurs_en_pourcentage[$chps.'_max'] : -1;
if ($min < ($max-0.1) ){
$i = $min + 0.1;
$num = 1;
for ($i ; $i < $max; $i += 0.1) {
$this->valeurs_en_pourcentage[$chps.'_'.$num] = $i;
$num++;
}
}
}
}
public function ajouterInfoAuSurvol($champs, $case){
$min = $this->valeurs_champs[$champs."_min"];
$max = $this->valeurs_champs[$champs."_max"];
if ($min != $max){
$valeurMin = $this->recupererOntologies($min, $champs );
$valeurMax = $this->recupererOntologies($max, $champs );
$valeurMin = $this->traiterIntermediaires($valeurMin->nom, $champs, $champs.'_min');
$valeurMax = $this->traiterIntermediaires($valeurMax->nom, $champs, $champs.'_max');
$case->setAttribute('title',"de $min: $valeurMin à $max: $valeurMax " );
} else {
$valeurMin = $this->recupererOntologies($min, $champs );
$valeurMin = $this->traiterIntermediaires($valeurMin->nom, $champs, $champs.'_min');
$case->setAttribute('title',"$min: $valeurMin" );
}
}
}
?>
/tags/v5.12-baouque/services/modules/0.1/baseflor/InformationsTaxonsSup.php
New file
0,0 → 1,274
<?php
 
/**
* Classe InformationsTaxonsSup.php permet de faire des requetes pour les rangs superieurs de baseflor
* du référentiel BDTFX et avec un numéro nomenclatural ( différent de 0 ).
* fin d'url possibles :
*
* /informations/#bdnt.nn:#num_nomen?champs=ecologie --> retourne champs ecologiques pour un BDNT et un num_nomen
*
*
* Encodage en entrée : utf8
* Encodage en sortie : utf8
* @package eflore-projets
* @author Mathilde SALTHUN-LASSALLE <mathilde@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)
*/
 
class InformationsTaxonsSup extends Commun{
protected $table = "";
private $champs_ontologiques = array();
private $format_reponse = 'informations';
protected $serviceNom = 'informations';
private $retour_format = 'max';
private $Bdd;
private $requete_condition = "";
private $champs_recherches = '*';
public function consulter($ressources, $parametres) {
$this->ressources = $ressources;
$this->parametres = $parametres;
$this->traiterParametres();
$this->definirTables();
$this->traiterRessources();
$resultats = '';
foreach ($this->table_version as $version) {
$this->table = $version;
$requete = $this->assemblerLaRequete();
$resultat = $this->Bdd->recupererTous($requete);
$versionResultat = $this->analyserResultat($resultat);
if (count($this->table_version) > 1) {
$resultats[$version] = $versionResultat;
} else {
$resultats = $versionResultat;
}
}
return $resultats;
}
public function analyserResultat($resultat) {
$versionResultat = null;
if ($resultat == '') {
$message = 'La requête SQL formée comporte une erreur!';
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
} elseif ($resultat) {
$versionResultat = $this->retournerResultatFormate($resultat);
}
return $versionResultat;
}
public function __construct(Conteneur $Conteneur) {
$this->Bdd = $Conteneur->getBdd();
}
//+--------------------------traitement ressources ou paramètres -------------------------------------------+
public function traiterRessources() {
if(preg_match('/^(.+)\.nn:([0-9]+)$/', $this->ressources[0], $retour)==1){
switch ($retour[1]) {
case 'bdtfx' :
$this->requete_condition[] = "num_nomen = ".$retour[2]." AND bdnt = 'bdtfx' ";
break;
default :
$e = 'Erreur dans l\'url de votre requête : </br> Le référentiel " '
.$retour[1].' " n\'existe pas.';
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
break;
}
}
}
//+---- paramètres ----+
public function traiterParametres() {
if (isset($this->parametres) && !empty($this->parametres) ) {
foreach ($this->parametres as $param => $valeur) {
switch ($param) {
case 'categorie' :
if ($valeur == "ecologie"){
$this->champs_recherches = ' num_nomen, bdnt, ve_lumiere_min , ve_lumiere_max,'
.' ve_temperature_min, ve_temperature_max, ve_continentalite_min,'
.' ve_continentalite_max, ve_humidite_atmos_min, ve_humidite_atmos_max,'
.' ve_humidite_edaph_min, ve_humidite_edaph_max, ve_reaction_sol_min,'
.' ve_reaction_sol_max, ve_nutriments_sol_min, ve_nutriments_sol_max,'
.' ve_salinite_min, ve_salinite_max, ve_texture_sol_min,ve_texture_sol_max,'
.' ve_mat_org_sol_min, ve_mat_org_sol_max ';
} else {
$e = "Valeur de paramètre inconnue pour 'categorie'. Ce paramètre n'est pas autorisé pour informations/#id";
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
break;
case 'retour.format' :
if ($valeur == 'min' || $valeur == 'max') {
$this->retour_format = $valeur;
break;
} else {
$e = "Valeur de paramètre inconnue pour 'retour.format'. Ce paramètre n'est pas autorisé pour informations/#id";
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
case 'navigation.depart' :
$this->definirNavigationDepart($valeur);
break;
case 'navigation.limite' :
$this->definirNavigationLimite($valeur);
break;
case 'version.projet' :
$this->traiterVersion($valeur);
break;
default :
$e = 'Erreur dans les parametres de votre requête : </br> Le paramètre " '
.$param.' " n\'existe pas.';
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE); break;
}
}
}
}
 
//+++------------------------------traitement des versions----------------------------------------++
public function traiterVersion($valeur) {
if (preg_match('/^[0-9]+(?:[._][0-9]+)*$/', $valeur) || $valeur == '*' || $valeur == '+') {
$this->version_projet = $valeur;
} else {
$e = "Erreur : La version est inconnue.";
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
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);
}
}
 
public function definirTables() {
$table_num_version = $this->recupererVersionDisponible();
$prefixe_table = config::get('bdd_table_rang_sup');
if ( in_array($this->version_projet,$table_num_version) ) {
$this->table_version[] = $prefixe_table.'_v'.$this->version_projet;
} elseif ($this->version_projet == '+') {
$derniere_version = $table_num_version[count($table_num_version) - 1];
$this->table_version[] = $prefixe_table.'_v'.str_replace('.', '_', $derniere_version);
} elseif ($this->version_projet == '*') {
foreach ($table_num_version as $num_version) {
$this->table_version[] = $prefixe_table.'_v'.str_replace('.', '_', $num_version);
}
} else {
$e = "Erreur : La version est inconnue.";
throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
//+--------------------------formatages de resultats -------------------------------------------+
public function retournerResultatFormate($resultat) {
$this->resultat_json = $resultat[0];
if ($this->retour_format == 'max') {
$graphique_presence = $this->traiterEcologie() ;
if ($graphique_presence) {
$this->ajouterLiensGraphique($graphique_presence);
}
}
return $this->resultat_json ;
}
public function traiterEcologie() {
$donnees_presence = false;
$this->champs_ontologiques = Commun::s_recupererTableauConfig('Paramètres.champs_ontologiques');
foreach ($this->champs_ontologiques as $cle => $valeur){
/* Les deux tests commentés ci-dessous étaient présents dans eflore-test (uniquement) jusqu'à juin 2013.
La valeur 0 pose question.
cf baseflor_v2012_12_31
cf services/modules/0.1/baseflor/CommunGraphiques.php traiterValeursEcologiques() */
if ($this->resultat_json[$cle.'_min'] != "") { // && $this->resultat_json[$cle.'_min'] != 0) {
$donnees_presence[$this->getNomGraphique($valeur)] = true;
$tab_ontologie = $this->recupererOntologies($this->resultat_json[$cle.'_min'], $cle.'_min');
unset($this->resultat_json[$cle.'_min']);
}
if ($this->resultat_json[$cle.'_max'] != "") { // && $this->resultat_json[$cle.'_max'] != 0) {
$this->recupererOntologies($this->resultat_json[$cle.'_max'], $cle.'_max');
unset($this->resultat_json[$cle.'_max']);
}
}
return $donnees_presence;
}
//donne le nom du graphique correspondant à un champ écologique
public function getNomGraphique($code_ecolo) {
$graphique = null;
if (in_array($code_ecolo, explode(',',Config::get('Paramètres.climat')))) {
$graphique = 'climat';
} elseif (in_array($code_ecolo, explode(',', Config::get('Paramètres.sol')) )) {
$graphique = 'sol';
}
return $graphique;
}
public function ajouterLiensGraphique($graphique_presence) {
if ($graphique_presence['climat']) {
$this->resultat_json['graphique_climat']['libelle'] = 'climat';
$this->resultat_json['graphique_climat']['href'] = $this->ajouterHref('graphiques/climat',
strtolower($this->resultat_json['bdnt']).'.nn:'.$this->resultat_json['num_nomen']);
}
if ($graphique_presence['sol']) {
$this->resultat_json['graphique_sol']['libelle'] = 'sol';
$this->resultat_json['graphique_sol']['href'] = $this->ajouterHref('graphiques/sol',
strtolower($this->resultat_json['bdnt']).'.nn:'.$this->resultat_json['num_nomen']);
}
}
//+--------------------------traitement ontologies -------------------------------------------+
public function recupererOntologies($valeur, $champs){
$chps_sans = preg_replace("/_min|_max/", '', $champs);
$url = Config::get('url_service_base').Config::get('nom_projet').
'/ontologies/'.$this->champs_ontologiques[$chps_sans].':'.urlencode(urlencode($valeur));
try {
$val = $this->getBdd()->recuperer(sprintf(
"SELECT a.nom FROM baseflor_ontologies a LEFT JOIN baseflor_ontologies b ON a.id = b.id LEFT JOIN baseflor_ontologies c ON b.classe_id = c.id WHERE".
" b.code = BINARY '%s' AND c.code = BINARY '%s' LIMIT 0, 100",
$valeur,
$this->champs_ontologiques[$chps_sans]),
Bdd::MODE_OBJET);
$this->resultat_json[$champs.'.libelle'] = $val->nom;
$this->resultat_json[$champs.'.code'] = $valeur;
$this->resultat_json[$champs.'.href'] = $url;
} catch (Exception $e) {
$this->resultat_json[$champs.'.libelle'] = '';
$this->resultat_json[$champs.'.code'] = '';
$this->resultat_json[$champs.'.href'] = '';
}
}
//+--------------------------FONCTIONS D'ASSEMBLAGE DE LA REQUETE-------------------------------------------+
public function assemblerLaRequete() {
$requete = ' SELECT '.$this->champs_recherches.' FROM '.$this->table.' '
.$this->retournerRequeteCondition();
return $requete;
}
public function retournerRequeteCondition() {
$condition = '';
if (empty($this->requete_condition) == false) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
}
?>