Subversion Repositories eFlore/Projets.eflore-projets

Compare Revisions

No changes between revisions

Ignore whitespace Rev 996 → Rev 997

/branches/v5.3-amandaie/chargerDonnees.sh
New file
0,0 → 1,50
#!/bin/bash
##############################################################################################################
# But : téléchargement automatique en local des données des projets depuis le serveur de Tela Botanica par ftp
# Auteur : Jean-Pascal Milcent <jpm@tela-botanica.org> (translate bat file to shell script)
# License : GPL v3
# Création : 07 decembre 2011
# Version: 0.1
# 2011-12-07 - Création
# $Id$
##############################################################################################################
# Constante
NBREPARAM=$#
APPDIR_ABSOLU=`pwd`;
DOSSIER_LOCAL="$APPDIR_ABSOLU/donnees/"
DOSSIER_DISTANT="/www/eflore/donnees/"
# Aide
E_OPTERR=65
if [ "$1" = '--help' ]
then # Le script a besoin d'au moins un argument sur la ligne de commande
echo "Usage $0 -[parameters -u, -p ]"
echo "Paramétres : "
echo " -h: indiquer l'hote ftp"
echo " -u: indiquer le nom de l'utilisateur ftp"
echo " -p: indiquer le mot de passe de l'utilisateur ftp"
exit $E_OPTERR
fi
 
# Récupération des paramètres et des options de la ligne de commande
TEMP=`getopt -o u:p:h: -l help: -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
eval set -- "$TEMP"
while [ ! -z "$1" ] ; do
#echo $1" # "$2
case "$1" in
-h) HOST=$2;;
-u) FTP_USER=$2;;
-p) FTP_PASSWD=$2;;
--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
shift 2
done
 
# Transfert sur le serveur par FTP
if [ $NBREPARAM -eq 0 ]; then
echo "Pas de transfert sur le serveur. Utiliser --help pour voir les options de transfert."
else
echo "Téléchargement en cours :";
lftp ftp://$FTP_USER:$FTP_PASSWD@$HOST -e "set ftp:passive off; mirror -e --no-symlinks -x '.*cel\/images\/.*' -x '.*osm\/.*' -x '.*plantscan\/.*' -x '.*coste\/cles\/.*' -x '.*coste\/descriptions\/.*' -x '.*coste\/images\/.*' -x '.*coste\/ressources\/.*' $DOSSIER_DISTANT $DOSSIER_LOCAL ; quit"
fi;
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:executable
+*
\ No newline at end of property
/branches/v5.3-amandaie/services/modules/0.1/nvjfl/NomsVernaculaires.php
New file
0,0 → 1,840
<?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)
*/
 
// 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
);
 
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;
 
private $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() {
$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']);
}
return sprintf(
'SELECT %s, IF(num_statut="",1,0) AS is_null' .
' FROM %s WHERE %s ORDER BY 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',
$nolimit ? '' : $limiteClause,
__FILE__, __LINE__);
}
 
//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;
}
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'])) {
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'];
}
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') {
// 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]);
}
}
}
$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;
}
 
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', '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;
}
 
public function afficherPoint($champ, $valeur, $langue, $num_nom) {
preg_match('/^(.*)\.code$/', $champ, $match);
$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;
}
}
}
}
}
 
}
?>
/branches/v5.3-amandaie/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;
}
}
?>
/branches/v5.3-amandaie/services/modules/0.1/moissonnage/Cartes.php
New file
0,0 → 1,271
<?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->formerCarte();
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;
}
private function formerCarte() {
$suffixe = 'france_moissonnage';
$nomFichierSVG = Config::get('chemin')."{$suffixe}.svg";
$this->verifierExistenceFichier($nomFichierSVG);
$formateur = new FormateurSVG($nomFichierSVG, $this->sources, $this->retour, $this->format);
$formateur->formaterCarte($this->taxon);
$resultat = new ResultatService();
$resultat->corps = $formateur->renvoyerCarte();
$resultat->mime = $this->retour;
//echo '<pre>'.print_r($resultat,true).'</pre>';exit;
 
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);
}
}
 
?>
/branches/v5.3-amandaie/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;
}
}
?>
/branches/v5.3-amandaie/services/modules/0.1/moissonnage/cartes/FormateurSVG.php
New file
0,0 → 1,321
<?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;
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);
}
}
 
?>
/branches/v5.3-amandaie/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']
);
}
}
}
}
 
?>
/branches/v5.3-amandaie/services/modules/0.1/moissonnage/cartes/SourceDonnees.php
New file
0,0 → 1,186
<?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();
 
$nom = ($source == "baznat") ? implode('%',explode(' ',$this->taxon['nom_complet'] )) : $this->taxon['nom_sci'] ;
$criteres[] = "nom_scientifique_complet LIKE ".$this->bdd->proteger($nom);
if ($this->nomRang == 'espece' || $this->nomRang == 'sous_espece') {
foreach ($this->taxons as $sousTaxon) {
$nom = ($source == "baznat") ? implode('%',explode(' ',$sousTaxon['nom_complet'] )) : $sousTaxon['nom_sci'];
$criteres[] = "nom_scientifique_complet LIKE ".$this->bdd->proteger($nom);
}
} 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);
}
}
 
?>
/branches/v5.3-amandaie/services/modules/0.1/insee-d/ZoneGeo.php
New file
0,0 → 1,405
<?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';
 
/** 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';
/** 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' :
$this->ajouterLeFiltreMasque('nccenr', $valeur);
break;
case 'masque.region' :
$this->ajouterLeFiltreMasque('region', $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 '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()
.$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 = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
//cas où la requete presente un navigation.depart supérieur au nb total de resultats.
$this->limite_requete['depart'] =
(($nb - $this->limite_requete['limite']) < 0) ? 0 : ($nb - $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 /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);
}
$resultat_json[$num] = $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;
}
}
 
}
 
?>
/branches/v5.3-amandaie/services/modules/0.1/nva/NomsVernaculaires.php
New file
0,0 → 1,653
<?php
/**
* Description :
* Classe NomsVernaculaires.php fournit une liste de noms vernaculaires et leur liaison à la bdtxa
* 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 bdtxa.
* 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' => 'bdtxa', '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;
private $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 '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[] = 'nva.'.$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(nva.num_nom_vernaculaire)', 'nva.nom_vernaculaire ');
}
}
 
//requete : /noms-vernaculaires/#id (ex : /noms-vernaculaires/7)
public function traiterRessourceId() {
if (is_numeric($this->ressources[0])) {
$this->requete_condition[] = ' nva.num_nom_vernaculaire = '.$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().
', CASE nva.code_langue WHEN "fra" THEN 1 ELSE 0 END AS tri '.
' FROM '.str_replace('nva', 'nva_index', $this->table).' inva'.
' LEFT JOIN '.$this->table.' nva ON nva.num_nom_vernaculaire = inva.num_nom_vernaculaire '
.$this->formerRequeteCondition().
' ORDER BY tri DESC, nva.nom_vernaculaire ASC '
.$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') ? '*' : 'distinct nva.num_nom_vernaculaire';
$requete = 'SELECT count('.$distinct.') as nombre FROM '
.str_replace('nva', 'nva_index', $this->table).' inva '
.'INNER JOIN '.$this->table.' nva ON nva.num_nom_vernaculaire = '
.'inva.num_nom_vernaculaire '
.$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 'num_nom_vernaculaire' : $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'];
}
}
}
$masque = $this->recupererMasque();
if($masque == "") {
$masque = "Pas de masque";
}
$table_retour_oss = array($masque, $oss);
return $table_retour_oss;
}
public function formaterNomsVernaculairesAttributions($resultat) {
$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) {
unset($tab['tri']);
$id_nom = $tab['num_nom_vernaculaire'];
$resultat_json[$id_nom]['id'] = $id_nom;
$resultat_json[$id_nom]['nom_vernaculaire'] = $tab['nom_vernaculaire'];
$resultat_json[$id_nom]['code_langue'] = $tab['code_langue'];
$resultat_json[$id_nom]['taxon.code'] = 'bdtxa.nt:'.$tab['num_taxon'];
if ($this->retour_format == 'max') {
$resultat_json[$id_nom]['num_taxon'] = $tab['num_taxon'];
$resultat_json[$id_nom]['nom_retenu.code'] = $tab['num_taxon'];
$resultat_json[$id_nom]['taxon'] = $tab['num_taxon'];
$this->taxons[] = $tab['num_taxon']; // utilisé pour chercher les noms latins plus bas
$resultat_json[$id_nom]['href'] = $this->ajouterHref('noms-vernaculaires', $id_nom);
if($this->champs_supp != array()) {
$resultat_json[$id_nom] = $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]);
}
}
}
$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 bdtxa)
public function formaterNomsVernaculairesId($resultat) {
foreach ($resultat as $taxon) { // pour chaque attribution à un taxon bdtxa
// 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->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 == 'num_nom_vernaculaire' || $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'], 'bdtxa.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').'bdtxa/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'] = 'bdtxa.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;
}
 
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;
}
}
}
?>
/branches/v5.3-amandaie/services/modules/0.1/iso-3166-1/ZoneGeo.php
New file
0,0 → 1,401
<?php
/**
* Description :
* Classe ZoneGeo.php fournit des informations sur un ensemble de lieux à une échelle donnée.
* 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 zones (seulement les 100 premières par défaut).
* L'url peut contenir des paramètres optionnels passés après le ? : /zone-geo?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';
 
/** 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';
/** 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('codet', $valeur);
break;
case 'masque.nom' :
$this->ajouterLeFiltreMasque('nom', $valeur);
break;
case 'masque.statut' :
$this->ajouterLeFiltreMasque('codet_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 '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); break;
}
}
}
}
 
public function ajouterLeFiltreMasque($nom_champ, $valeur) {
if ($nom_champ == 'codet') {
$this->requete_condition[] .= $nom_champ.' = '.$this->getBdd()->proteger($valeur);
} else {
if ($this->recherche == 'floue') {
if ($nom_champ == 'masque') {
$this->requete_condition[] = ' ( codet = '.$this->getBdd()->proteger($valeur)
.' OR (SOUNDEX(nom_francais) = SOUNDEX(\''.$valeur.'\')'
.' OR SOUNDEX(REVERSE(nom_francais)) = SOUNDEX(REVERSE(\''.$valeur.'\')) OR '
.'SOUNDEX(nom_anglais) = SOUNDEX(\''.$valeur.'\')'
.' OR SOUNDEX(REVERSE(nom_anglais)) = SOUNDEX(REVERSE(\''.$valeur.'\'))) '
.' OR ( SOUNDEX(codet_statut) = SOUNDEX(\''.$valeur.'\')'
.' OR SOUNDEX(REVERSE(codet_statut)) = SOUNDEX(REVERSE(\''.$valeur.'\')) '
.')) ';
} elseif ($nom_champ == 'nom') {
$this->requete_condition[] = '(SOUNDEX(nom_francais) = SOUNDEX(\''.$valeur.'\')'
.' OR SOUNDEX(REVERSE(nom_francais)) = SOUNDEX(REVERSE(\''.$valeur.'\'))) OR
(SOUNDEX(nom_anglais) = SOUNDEX(\''.$valeur.'\')'
.' OR SOUNDEX(REVERSE(nom_anglais)) = 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[] = '(codet = '.$this->getBdd()->proteger($valeur)
.' OR nom_francais LIKE '.$this->getBdd()->proteger($valeur)
.' OR nom_anglais LIKE '.$this->getBdd()->proteger($valeur)
.' OR codet_statut LIKE '.$this->getBdd()->proteger($valeur).')';
} elseif ($nom_champ == 'nom') {
$this->requete_condition[] = '(nom_francais LIKE '.$this->getBdd()->proteger($valeur).' OR '
.'nom_anglais 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)) {
$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])) {
//requete = /zone-geo/#id/#champ ou /zone-geo/#id/relations
$this->traiterRessourceChampOuRelations();
}
}
}
}
 
public function traiterRessourceId() {
//requete : /zone-geo/#id (ex : /zone-geo/7)
if ($this->table_ressources[0]) {
$this->requete_condition[] = ' codet = '.$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() {
if ($this->table_ressources[1] == 'relations') {
$r = 'Erreur dans les ressources de votre requête : </br> La ressource " '.$this->table_ressources[1].
' " n\'existe pas.';
$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r);
} else {
$this->format_reponse .= '/champ';
}
}
 
// +-------------------------------------------------------------------------------------------------------------------+
public function assemblerLaRequete() {
//assemblage de la requete :
$requete = ' SELECT '.$this->requete_champ.
' FROM '.$this->table
.$this->formerRequeteCondition()
.$this->formerRequeteLimite();
return $requete;
}
 
//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->requete_limite = '';
} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
//cas ou la requete presente un navigation.depart supérieur au nb total de resultats.
$this->limite_requete['depart'] =
(($nb - $this->limite_requete['limite']) < 0) ? 0 : ($nb - $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 formerRequeteCondition() {
$condition = '';
if ($this->requete_condition != null) {
$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
}
return $condition;
}
 
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. Encode en json
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;
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, 'nom_francais');
foreach ($resultat as $tab) {
foreach ($tab as $key => $valeur) {
$valeur = rtrim($valeur);
if ($valeur != '') {
switch ($key) {
case 'codet' : $num = $valeur; $this->table_retour['code'] = $valeur; break;
case 'nom_francais' : $this->table_retour['nom'] = $valeur; break;
case 'nom_anglais' : if ($tab['nom_francais'] == '') $this->table_retour['nom'] = $valeur; break;
case 'codet_statut' : $this->table_retour['statut'] = $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();
}
$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 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 ($champ == 'nom') $champ = 'nom.fr';
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 == 'codet_statut') {
$this->table_retour[$this->correspondance_champs[$champ]] = $valeur;
$this->table_retour[$this->correspondance_champs[$champ].'.href'] =
$this->ajouterHref('ontologies', 'masque.nom=Codet '.$valeur, '?');
} else {
$this->table_retour[$this->correspondance_champs[$champ]] = $valeur;
}
} else {
$this->table_retour[$this->correspondance_champs[$champ]] = $valeur;
}
}
 
// +-------------------------------------------------------------------------------------------------------------------+
/** Permet de retourner l'url http://tela-botanica.org/service:eflore:0.1/[projet]/[version_projet]/[service]/[ressource]:[valeur]
* @param $service : correspond au nom de la ressource à laquelle on souhaite acceder
* @param $val : correspond au paramètre de la ressource (ex :
* @param $projet : est remplit dans les cas suivants :
* - si le projet dans lequel se trouve l'information est différent de celui du service appelé
* - si on souhaite rappeler le meme projet avec la meme ressource mais un parametre de ressource différent
*/
public function ajouterHref($service, $val, $separation = '/') {
$val = $this->encoderUrl($val);
if ($this->version_projet == '+') {
$url = Config::get('url_service_base').Config::get('nom_projet').'/'.$service.$separation.$val;
} else {
$url = Config::get('url_service_base').Config::get('nom_projet').'/'.$this->version_projet.'/'.$service.$separation.$val;
}
return $url;
}
 
public function encoderUrl($url) {
$url = str_replace(' ', '%20', $url);
$url = str_replace('?', urlencode('?'), $url);
return $url;
}
}
?>
/branches/v5.3-amandaie/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;
private $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;
}
}
 
 
}
?>
/branches/v5.3-amandaie/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" );
}
}
}
?>
/branches/v5.3-amandaie/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;
}
}
?>