Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 784 | Rev 1117 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
/**
* Description :
* Classe Observations.php permettant de fournir des informations sur les observations.
* Si l'url finit par /observations on retourne une liste d'observations (seulement les 100 premières par défaut) :
* espèce, lieu, date, observateur.
* 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.type (type d'observation : chorologie), 
* masque.date_observation (date d'observation), masque.station (département), masque.determination (nom scientifique de l'espèce)
* masque.observateur (prénom, nom), masque.nn (identifiant du nom), 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 Observations extends Commun {
        
        protected $serviceNom = 'observations';
        
        /** Stockage des paramétres */
        protected $table_param = array();
        /** 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 = 'stricte';
        /** Valeur du paramètre de requete distinct (=0|1)
         * Indique que l'on veut les noms distincts (par défaut tous les noms, même semblable, sont renvoyés)         */
        protected $distinct = null;
        protected $retour_format = 'max';
        protected $presenceChorologie = '';
        
        /** Variables constituant les parametres de la requete SQL (champ, condition, group by, limit) remplie 
         * selon ressources et paramètres       */
        protected $requete_champ = ' id, num_nom, nom_sci ';
        protected $requete_condition = array();
        /** Une observation est défini par départ qui correspont à un num_nom et dept qui correspond à un departement        */
        protected $limite_requete        = array( 
                'depart' => 0, 
                'dept' => 01,
                'limite' => 20
        );
        
        /**
         * Permet de stocker la requete formulée : 
         *   - noms | noms/#id | noms/#id/#champ+#champ
         *   - noms/#id/relations | noms/#id/relations/synonymie | noms/#id/relations/homonymie | noms/#id/relations/flores
         *   - noms/stats/rangs | noms/stats/annees | noms/stats/initiales 
         * Est remplit au cours de l'analyse des ressources (traiterRessources()). 
         * Est utilisée principalement pr déterminer le format du tableau à retourner.
         */
        protected $format_reponse = 'observations';

// +-------------------------------------------------------------------------------------------------------------------+        
        public function consulter($ressources, $parametres) {
                $this->parametres = $parametres;
                $this->traiterVersionProjet($ressources);
                $this->traiterRessources($ressources);
                $resultat_formate = '';
                
                if ($this->corps_http == '' && $this->entete_http == '') {
                        foreach ($this->table_version as $version) {
                                $this->table = $version; //on stocke le nom de la table correspondant à la version du projet en cours
                                $this->traiterParametres($parametres);
                                $requete = $this->assemblerLaRequete(); //print_r($requete);
                                $resultat = $this->getBdd()->recupererTous($requete);
                                $res_version = $this->testerResultat($resultat, $requete);
                        }
                        if ($this->corps_http == '' && $this->entete_http == '') {
                                if (isset($res_version)) {
                                        $resultat_formate = $res_version;
                                }
                        }
                } 
                return $resultat_formate; 
        }
        
        public function testerResultat($resultat, $requete) {
                if ($resultat == '') { //cas ou la requete comporte des erreurs
                        $s = 'La requête SQL resultat formée comporte une erreur !!';
                        Debug::printr($requete);
                        $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $s);
                } elseif ($resultat) {
                        if (count($this->table_version) > 1) {
                                $res_version[$version] = $this->retournerResultatFormate($resultat);
                        } else {
                                $res_version = $this->retournerResultatFormate($resultat);
                        }
                } else {
                        if ($this->format_reponse == 'zone-geo/id/relations') { 
                        //si aucune relations n'existe, la valeur null est retournée
                                $res_version = null;
                        } else {
                                $d = 'Données recherchées introuvables dans la base'.$requete;
                                $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $d);
                                Debug::printr($requete);
                        }
                }
                return $res_version;
        }
        
        public function assemblerLaRequete() {
                $requete = "SELECT ".$this->formerRequeteChamp().
                        " FROM ".$this->table.$this->formerRequeteCondition().
                        ' LIMIT '.$this->limite_requete['depart'].', '.$this->limite_requete['limite'];//echo $requete;
                return $requete;
        }
        
        public function formerRequeteChamp() {
                if (!isset($this->table_ressources)) {
                        if (!isset($this->table_param['masque_station']) && !isset($this->table_param['masque_contributeur']) ) {
                                $champ = ' * ';
                        } else {
                                $champ = $this->requete_champ;
                        }
                } else {
                        $champ = $this->requete_champ;
                }
                return $champ;
        }
        
        public  function formerRequeteCondition() {
                $condition = '';
                if ($this->requete_condition != null) { 
                        $condition = ' WHERE '.implode(' AND ', $this->requete_condition);
                } 
                return $condition;
        }
        
// +-------------------------------------------------------------------------------------------------------------------+        
        public function traiterRessources(&$ressources) {
                if (isset($ressources) && !empty($ressources)) {
                        $this->table_ressources = $ressources;
                        if (isset($this->table_ressources[0]) && !empty($this->table_ressources[0])) {
                                $this->traiterRessourceId();
                                if (isset($this->table_ressources[1]) && !empty($this->table_ressources[1])) {
                                        $this->traiterRessourceChamp;
                                }
                        } 
                }
        }
        
        public function traiterRessourceId() {
                //requete : /observations/#num_nom:#dept (ex : /observations/10:34)
                if (preg_match('/^([0-9]*):([0-9]{2})$/', $this->table_ressources[0], $conditions)) {
                        $this->requete_condition[] = ' num_nom = '.$this->getBdd()->proteger($conditions[1]).' AND `'.$conditions[2]."` != '' ";
                        $this->requete_champ .= ' ,catminat, rang, num_tax, freq_abs, freq_rel, rare_nat, `'.$conditions[2].'`';
                        $this->format_reponse .= '/id';
                        
                //requete : /observations/nom:#dept (ex : /observations/coquelicot:30)
                } elseif (preg_match('/^(.*):([0-9]{2})$/', $this->table_ressources[0], $conditions)) {
                        $this->requete_condition[] = ' nom_sci like '.$this->getBdd()->proteger($conditions[1].'%').' AND `'.$conditions[2]."` != '' ";
                        $this->requete_champ .= ' ,catminat, rang, num_tax, freq_abs, freq_rel, rare_nat, `'.$conditions[2].'`';
                        $this->format_reponse .= '/id';
                //requete : /observations/num_nom:#num_nom (ex : /observations/num_nom:290) ??
                } elseif (strrpos($this->table_ressources[0], ':') !== false) {
                                
                } 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 traiterParametres($parametres) {
                if (isset($parametres) && !empty($parametres)) {
                        $this->table_param = $parametres;
                        
                        if (isset($parametres['recherche']) && $parametres['recherche'] != '') {
                                $this->recherche = $parametres['recherche']; 
                        }
                        foreach ($parametres as $param => $valeur) {                            
                                switch ($param) {
                                        case 'masque'                           : $this->ajouterLeFiltreMasque($valeur);                                                break;
                                        case 'masque.date.observation' :                                                                                                                        break;
                                        case 'masque.station'           : $this->limite_requete['dept'] = $valeur;
                                                                                                        $this->ajouterUnFiltre('station', $valeur);                                     break;
                                        case 'masque.departement'               :
                                                                                                        $this->ajouterUnFiltre("`".$valeur."`", '1');                                   break;
                                        case 'masque.determination'     : $this->ajouterUnFiltre('nom_sci', $valeur);                                   break;
                                        case 'masque.determination.nn' : 
                                                        $this->requete_condition[] = '`num_nom` = '.$this->getBdd()->proteger($valeur);         break;
                                        case 'masque.determination.nt' :
                                                $this->requete_condition[] = '`num_tax` = '.$this->getBdd()->proteger($valeur);         break;                          case 'masque.observateur'       : $this->ajouterLeFiltreContributeur($valeur);                                  break;
                                        case 'masque.valeur'            : $this->presenceChorologie = $valeur;                                                  break;
                                        case 'retour.format'            : $this->retour_format = $valeur;                                                               break;
                                        case 'navigation.depart'        : $this->ajouterLimiteDepart($valeur);                                                  break;
                                        case 'navigation.limite'        : if ($valeur !== '') $this->limite_requete['limite'] = $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); break;
                                }
                        }
                }
        }
        
        /** fonction d'ajout dans la requete SQL des conditions (WHERE ...) en fonctions des parametres demandés
         * @param $nom_champ
         * @param $valeur
         * @param $masque
         */
        public function ajouterUnFiltre($nom_champ, $valeur) {
                if ($nom_champ == 'station') {
                        if (!preg_match('/^\s*([0-9]{2})\s*$/', $valeur, $colonne)) { // si le nom est passé
                                $this->requete_condition[] = '1';
                                                /*      $url = $this->ajouterHrefAutreProjet('zone-geo',$key,'INSEE-D');// d'apres nom
                                $dept = $this->rest_client->consulter($url);
                                $entete = $this->rest_client->getReponseEntetes();
                                if (isset($entete['wrapper_data'])) {                                                                                                   
                                        $colonne = json_decode($relation);
                                } else {
                                        $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, 
                                                'Le service '.$this->service.' de ce projet comporte des erreurs. url lancée : '.$url);
                                }*/
                        } else {
                                $this->requete_condition[] = '`'.$valeur."` != '' ";
                                $this->requete_champ .= ', `'.$valeur.'` ';
                        }
                } else { 
                // recherche floue
                        if ($this->recherche == 'floue') {//ajout_soundex
                                $this->requete_condition[] = '(SOUNDEX('.$nom_champ.') = SOUNDEX(\''.$valeur.'\')'
                                        .' OR SOUNDEX(REVERSE('.$nom_champ.')) = SOUNDEX(REVERSE(\''.$valeur.'\'))) ';
                // recherche étendue
                        } elseif ($this->recherche == 'etendue') {
                                $valeur = str_replace(' ','%', $valeur);
                                $valeur .= '%';
                        }
                // recherche stricte
                        $this->requete_condition[] = $nom_champ.' LIKE '.$this->getBdd()->proteger($valeur);
                }
        }
        
        /** fonction d'ajout dans la requete SQL des conditions (WHERE ...) quand le paramètre passé est masque
         * @param $valeur
         */
        public function ajouterLeFiltreMasque($valeur) {
                $this->ajouterUnfiltre('station', $valeur);
                $condition = '(( '.array_pop($this->requete_condition);
                $this->ajouterUnfiltre('num_nom', $valeur);
                $condition .= ' ) OR ('.array_pop($this->requete_condition);
                $condition = str_replace('( 1 ) OR', '', $condition); // si la valeur passée est une varchar supprime le filtre station
                $this->ajouterUnfiltre('nom_sci', $valeur);
                $this->requete_condition[] = $condition.' ) OR ('.array_pop($this->requete_condition).' )) ';
        }
        
        /** fonction d'ajout dans la requete SQL des conditions (WHERE ...) quand le paramètre passé est masque.contributeur
         * @param $valeur
         */
        public function ajouterLeFiltreContributeur($valeur) {
                $requete_contr = $this->creerRequeteContributeur($valeur);
                $res = $this->getBdd()->recupererTous($requete_contr);
                if ($res == '') { //cas ou la requete comporte des erreurs
                        $c = 'La requête SQL formée comporte une erreur !!';
                        $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $c);
                        Debug::printr($requete_contr);
                } elseif ($res) {
                        unset($res[0]['id'],$res[0]['nom'],$res[0]['prenom'],$res[0]['courriel']);
                        // si il y a un masque station et que le contributeur n'a pas de données dans ce dept
                        if (isset($this->table_param['masque_station']) && isset($res[0][$this->table_param['masque_station']])) {
                                if ($res[0][$this->table_param['masque_station']] != 1) {
                                        $d = "Les données recherchées sont introuvables pour l'observateur ".$valeur." dans le département "
                                                .$this->table_param['masque_station'];
                                        $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $d);
                                }
                        } else {
                                foreach ($res[0] as $dept=>$presence) {
                                        if ($presence == 1) {
                                                $this->ajouterUnfiltre('station', $dept);
                                                $requete_condition[] = array_pop($this->requete_condition); // recupere le filtre créé précédement
                                        }
                                }
                                $this->requete_condition[] = '(( '.implode(' ) OR ( ', $requete_condition).' ))'; // créé un filtre sur les dept
                        }
                } else {
                        $i = "Les données recherchées sont introuvables pour l'observateur ".$valeur;
                        $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $i);
                }       
        }
        
        public function creerRequeteContributeur($valeur) {
                $condition = '';
                if (preg_match('/(.*@[a-z]+\.[a-z]{2,3})/', $valeur, $match)) {// cherche sur le mail
                        $condition = 'courriel = '.$this->getBdd()->proteger($match[1]);
                } elseif (preg_match('/^(\w+)\s+(\w+)$/', $valeur, $match)) {// cherche sur les nom prenom
                        $condition = ' ((nom = '.$this->getBdd()->proteger($match[1]).' OR prenom = '.$this->getBdd()->proteger($match[1]).
                                ' ) AND (nom = '.$this->getBdd()->proteger($match[2]).' OR prenom = '.$this->getBdd()->proteger($match[2]).'))'.
                                ' OR ( nom LIKE '.$this->getBdd()->proteger($valeur.'%').')';
                } else {// cherche si nom association
                        $condition = 'nom LIKE '.$this->getBdd()->proteger($valeur.'%');
                }
                list($table, $version) = explode('_v',$this->table);
                $requete_contr = "SELECT * FROM chorodep_contributeurs_v$version WHERE ".$condition;
        }

        /**
         * @param type $id un offset ou une combinaison de la forme "num_nom:departement"
         */
        public function ajouterLimiteDepart($id) {
                if ($id !== '') {
                        // $id est de la forme nn:dept - wtf ? en plus ça marche pas, le lien
                        // "href.suivant" génère du caca d'oie
                        $d = explode(":", $id);
                        if (count($d) == 2) {
                                $this->limite_requete['depart'] = 0;
                                $this->limite_requete['dept'] = $d[1];
                                if (!isset($this->parametres['masque.determination.nn'])) {
                                        $requete_condition = (is_numeric($d[0])) ? '`num_nom` = '.$d[0]  : '`nom_sci` like "'.urldecode($d[0]).'%"';
                                        $requete = "SELECT id FROM $this->table WHERE ".$requete_condition;
                                        $res = $this->getBdd()->recuperer($requete);
                                        if ($res == '') { //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 ($res) {
                                                $this->limite_requete['depart'] = $res['id'] - 1;
                                        } else {
                                                $i = "Les données recherchées sont introuvables";
                                                $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $i);
                                        }
                                }
                        } else {
                                // $id est un simple offset
                                $this->limite_requete['depart'] = $id;
                        }
                }
        }
        
// +-------------------------------------------------------------------------------------------------------------------+
        public function retournerResultatFormate($resultat) {
                $this->table_retour = array(); // stocke les données générales d'une observation et écrase les données d'un dep
                $this->chargerInfosGenerales();
                switch ($this->format_reponse) {
                        case 'observations'             : $reponse = $this->formaterObservations($resultat);                     break;
                        case 'observations/id'          : $reponse = $this->formaterObservationsId($resultat[0]);        break;
                        case 'observations/id/champ': $reponse = $this->formaterObservationsIdChamp($resultat[0]); break;
                        default : break;
                }
                return $reponse;
        }
        
        
        public function formaterObservations($resultat) {       
                $num = 0; // compte le nombre d'observations pour retourner le nombre d'obs indiqué
                $depart = false; //le depart du resultat est noté ss forme #ligne:#departement $depart indique le departement est correct
                //on remplit la table $table_retour_json['resultat']
                $this->table_retour = array();
                foreach ($resultat as $tab) {
                        foreach ($tab as $key => $valeur) {
                                switch ($key) {
                                        case 'id'               : break;
                                        case 'catminat' : break;
                                        case 'rang'             : break;
                                        case 'num_tax'  : break;
                                        case 'freq_abs' : break;
                                        case 'freq_rel' : break;
                                        case 'rare_nat' : break;
                                        case 'num_nom'  : ($valeur == 'nc')? $num_nom = urlencode($tab['nom_sci']) : $num_nom = $valeur ; break;
                                        case 'nom_sci'  : $this->table_retour['determination.nom_sci'] = $valeur;       break;
                                        default                 : // pour les depts
                                                if (isset($this->parametres['masque.station'])) {
                                                        if ($key == $this->parametres['masque.station']) {
                                                                $id = $num_nom.":".$key;
                                                                $this->completerDonnees($key, $valeur, $id);
                                                                $resultat_json[$id] = $this->table_retour;
                                                                $num++;
                                                        }
                                                } else {
                                                        if ($depart == true && $valeur != '') {
                                                                if (($this->presenceChorologie != '' && $valeur == $this->presenceChorologie) || 
                                                                        ($this->presenceChorologie == '' && $valeur != $this->presenceChorologie)) {
                                                                        $id = $num_nom.":".$key;
                                                                        $this->completerDonnees($key, $valeur, $id);
                                                                        $resultat_json[$id] = $this->table_retour;
                                                                        $num++;
                                                                }
                                                        }
                                                        if ($key == $this->limite_requete['dept']) $depart = true;
                                                }
                                                break;
                                }
                                if ($num == $this->limite_requete['limite']) {
                                        break;
                                }
                        } 
                        if ($num == $this->limite_requete['limite']) {
                                break;
                        }
                        $this->table_retour = array();
                }
                //on remplit la table $table_retour_json['entete']      
                // Mode moderne rétrocompatible : les départ sont toujours de simples offsets
                if (strpos($this->limite_requete['depart'], ':') === false) {
                        $id = $this->limite_requete['depart'] + $this->limite_requete['limite'];
                }
                //formuler les urls precedentes et suivantes affichées dans l'entete du resultat
                $url = $this->formulerUrlObs($id, $num, '/observations');
                if ($url['precedent'] != '') { $this->table_entete['href.precedent'] = $url['precedent']; }
                if ($url['suivant']   != '') { $this->table_entete['href.suivant']   = $url['suivant']; }
                $this->table_entete['total']  = $num;
                $table_retour_json['entete'] = $this->table_entete;
                $table_retour_json['resultat'] = $resultat_json; 
                return $table_retour_json;
        }
        
        public function completerDonnees($key, $valeur, $id) {
                if ($this->retour_format == 'max' ) {
                        $this->afficherDonneesMax($key, $valeur);
                        $this->table_retour['href'] = $this->ajouterHref('observations',$id);
                } else {
                        $this->table_retour['station.departement.code'] = 'INSEE-D.'.$key;
                        $this->table_retour['valeur.code'] = $valeur;
                }
        }
        
        public function formaterObservationsId($resultat) {
                foreach ($resultat as $key => $valeur) {
                        switch ($key) {
                                case 'id'               : break;
                                case 'catminat' : if ($this->retour_format == 'max') $this->table_retour['determination.catminat'] = $valeur;   break;  
                                case 'rang'     : $this->table_retour['determination.rang'] = $valeur;                                  break;
                                case 'num_tax'  : $this->table_retour['determination.num_tax'] = $valeur;                               break;
                                case 'freq_abs' :                                                                                                                                               break;
                                case 'freq_rel' :                                                                                                                                               break;
                                case 'rare_nat' : $this->table_retour['determination.rarete_nationale.code'] = $valeur; break;
                                case 'nom_sci'  : $this->table_retour['determination.nom_sci'] = $valeur;                               break;
                                case 'num_nom'  : $this->table_retour['determination.num_nom'] = $valeur;                               break;
                                default                 :       if ($this->retour_format == 'max') { 
                                                                                $this->afficherDonneesMax($key, $valeur, true);
                                                                        } else {
                                                                                $this->table_retour['station.departement.code'] = 'INSEE-D.'.$key;
                                                                                $this->table_retour['valeur.code'] = $valeur;
                                                                        }                                                                                                                                       break;
                        }
                }
                return $this->table_retour;
        }
        
        public function afficherDonneesMax($key, $valeur, $id = false) {
                if ($key != 20) { //à part la Corse
                        $url_dep = $this->ajouterHrefAutreProjet('zone-geo','',$key, 'insee-d');
                        $dep = $this->consulterHref($url_dep);
                        if (isset($dep)) {
                                $this->table_retour['station.departement'] = $dep->nom;
                                $this->table_retour['station.departement.code'] = 'INSEE-D.'.$key;
                                $this->table_retour['station.departement.href'] = $url_dep;
                        } else {
                                $this->table_retour['station.departement.code'] = 'INSEE-D.'.$key;
                        }
                } else {
                        $this->table_retour['station.departement.code'] = 'INSEE-D.'.$key;
                }
                //double encodage des paramétres contre validation de Apache
                $url_val = $this->ajouterHref('ontologies', 'presenceChorologie:'.urlencode(urlencode($valeur)));
                $val = $this->consulterHref($url_val);
                $this->table_retour['valeur'] = $val->nom;
                $this->table_retour['valeur.code'] = $valeur;
                $this->table_retour['valeur.href'] = $url_val; 
                if ($this->format_reponse == 'observations/id') { // si on est 
                        $contr = $this->chargerContributeurs($key);
                        if (isset($contr['general'])) {
                                $this->table_retour['contributeur'] = $contr['general'];
                                $this->table_retour['contributeur.details'] = $contr['details'];
                        }
                        $source = $this->chargerSources($key);
                        if (isset($source['general'])) $this->table_retour['sources'] = $source['general'];
                        if (isset($source['autres'])) $this->table_retour['sources.autres'] = $source['autres'];
                }
        }
        
        public function chargerInfosGenerales() {
                list($table, $version) = explode('_v',$this->table);
                $version = str_replace('_', '.', $version);
                $requete = "SELECT createurs, date_creation FROM chorodep_meta WHERE version = \"$version\";";
                $resultat = $this->getBdd()->recuperer($requete); //Debug::printr($resultat);
                
                if ($resultat == '') { //cas ou la requete comporte des erreurs
                        $r = 'La requête SQL metadonnees formée comporte une erreur !!';
                        $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $r);
                        Debug::printr($requete);
                } elseif ($resultat) {
                        $this->table_retour['type'] = 'chorologie';
                        $this->table_retour['date_observation'] = $resultat['date_creation'];
                        $this->table_retour['observateur.details'] = $this->traiterChampFormateDCSV($resultat['createurs']);
                }
        }
        
        public function chargerContributeurs($dept) {
                $contributeur = array();
                list($table, $version) = explode('_v',$this->table);
                $requete = "SELECT prenom, nom, courriel FROM chorodep_contributeurs WHERE `$dept` = '1';";
                $resultat = $this->getBdd()->recupererTous($requete); //Debug::printr($resultat);
                
                if ($resultat == '') { //cas ou la requete comporte des erreurs
                        $r = 'La requête SQL contributeurs formée comporte une erreur !!';
                        $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $r);
                        Debug::printr($requete);
                } elseif ($resultat) {
                        $contributeur['general'] = '';
                        foreach ($resultat as $res) {
                                $contributeur['general'] .= $res['prenom'].' '.$res['nom'].', ';
                                foreach ($res as $cle => $valeur) {
                                        if ($valeur == "") {
                                                unset($res[$cle]);
                                        }
                                }
                                $type = ($res['prenom'] == '') ? 'o' : 'p';
                                $url = $this->ajouterHrefAutreProjet('ontologies', 'contactType:', $type, 'eflore');
                                $val = $this->consulterHref($url);
                                $res['type'] = $val->nom;
                                $res['type.code'] = $type;
                                $res['type.href'] = $url;
                                $contributeur['details'][] = $res;
                        }
                }
                return $contributeur;
        }
        
        // prend en paramètre un champ comme createur, contributeur... sous forme p.prenom=ygggg,p.nom=fk;p.prenom=fdfs,p.nom=ek
        //retourne un tableau
        public function creerPointDetails($resultat) {
                $organismes = explode(';', $resultat);
                $num_org = 1;
                $general = '';
                foreach ($organismes as $organisme) {
                        $infos = explode(',', $organisme);
                        $t = '';
                        $type = '.'; 
                        
                        foreach ($infos as $info) {
                                list($key, $val) = explode('=', $info);
                                list($type, $champ) = explode('.', trim($key));
                                if ($type == 'p' && $champ == 'prenom') $general .= $val.' ';
                                if (($type == 'p' || $type == 'o') && $champ == 'nom') $general .= $val.' ';
                                $res[$num_org][$champ] = $val;
                                $res[$num_org]['type'] = $type;// à modifier
                        }
                        $general = rtrim($general).', ';
                        $num_org ++;
                }
                $this->table_retour['observateur'] = rtrim($general, ', ');
                $this->table_retour['observateur.details'] = $res;
        }
        /**
         * Recupère à partir de la valeur du champ les différentes informations séparées par ';' (stocke ds un tableau)
         * pour éditeurs, créateurs, contributeurs,...
         * (ex : nom=Tela Botanica,guid=urn:lsid:tela-botanica.org,courriel=accueil@tela-botanica.org,...
         */ 
        public function traiterChampFormateDCSV($val) {
                $tab = array(); 
                $num_entite = 0;
                $type = '';
                
                // découpe chaque participant
                $tab_entites = explode(';', $val);
                foreach ($tab_entites as $entite) {
                        $tab[$num_entite] = array();
                        
                        if ($entite != '') {
                                // découpe les informations du participant
                                $entite_detail = explode(',', $entite); 
                                foreach ($entite_detail as $detail) {
                                        
                                        if ($detail != '') {
                                                if (preg_match('/^([^=]*)\.([^=]+)=([^=]*)$/', $detail, $match)) {
                                                        $tab[$num_entite][$match[2]] = $match[3];
                                                        if ($match[1] != $type) $type = $match[1];
                                                } else {
                                                        $tab[$num_entite][] = $detail;
                                                }
                                        }
                                }
                                if ($type != '') {
                                        if ($this->retour_format == 'max') {
                                                
                                        }
                                }
                        }
                        $num_entite++;
                }
                return $tab;
        }
        
        public function chargerSources($dept) {
                $contributeur = array();
                $requete = "SELECT biblio FROM chorodep_sources WHERE `$dept` = '1';";
                $resultat = $this->getBdd()->recupererTous($requete); //Debug::printr($resultat);
                
                if ($resultat == '') { //cas ou la requete comporte des erreurs
                        $r = 'La requête SQL sources formée comporte une erreur !!';
                        $this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $r);
                        Debug::printr($requete);
                } elseif ($resultat) {
                        foreach ($resultat as $cle=>$res) {
                                if ($cle == 0) {
                                        $contributeur['general'] = $res['biblio'];
                                } else {
                                        $contributeur['autres'][] = $res['biblio'];
                                }
                        }
                }
                return $contributeur;
        }
        
        
/*      public function formaterObservationsIdChamp($resultat) {
                
                //on recupère tous les resultats possibles
                $reponse = $this->formaterObservationsId($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['id'];
                $champs = explode(' ', $this->table_ressources[1]);
                
                foreach ($champs as $champ) {
                        
                        if ($this->verifierValiditeChamp($champ, $reponse)) {
                                
                                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;
        }*/
        
// +-------------------------------------------------------------------------------------------------------------------+        
/**
         * Description : 
         * Est appelée pour former l'url complete des resultats precedants ou suivants.
         * @param int : Permet de connaitre le nombre de noms obtenus par la requete
         * @return string Retourne l'url complete des resultats precedents ou suivant sous la forme d'un tableau
         */
        public function formulerUrlObs($suivant, $total, $id = null) {
                $debut_url = Config::get('url_service').$id.'?';
                //on recrée l'url sans les parametres de navigation qui seront rajouter ci-apres. On les enlève dc de la table des parametres
                $table_bis = $this->table_param;
                if (isset($table_bis['navigation.depart'] )) {
                        unset($table_bis['navigation.depart']);
                }
                if (isset($table_bis['navigation.limite'])) {
                        unset($table_bis['navigation.limite']);
                }
                $parametre_url = http_build_query($table_bis);
                //on recupere les limites
                $url['suivant']   = $this->recupererLesLimitesSuivantesObs($suivant, $total);
                $url['precedent'] = $this->recupererLesLimitesPrecedentesObs($suivant);
                //on reconstitue les deux urls avec leurs limites
                foreach ($url as $key => $limite) {
                        if ($limite != '') {
                                if ($parametre_url == '') {
                                        //si il n'y a aucun parametres, seules les limites sont à ajouter.On enleve dc le signe & du début
                                        $limite = str_replace('&navigation.depart=', 'navigation.depart=', $limite);
                                        if (strpos($limite, 'navigation.depart') === false) {
                                                $limite = str_replace('&navigation.limite=', 'navigation.limite=', $limite);
                                        }
                                }
                                $url_complete = $debut_url.$parametre_url.$limite;
                                $url[$key] = $url_complete;
                        }
                }
                return $url;
        }
        
        /**
         * Description : 
         * Permet de former les limites de la requete retournant les résultats suivants.
         * Cette url sera afficher dans l'entete de la reponse retournée en format JSON (retour.format=defaut).
         * @param int : $nb_resultat : Permet de connaitre le nombre de résultats obtenus par la requete
         * @return string : la fin de l'url decrivant les limites des resultats suivants. Si aucun résultats ne suient, 
         * une chaine de caractère vide est retournée
         */
        public function recupererLesLimitesSuivantesObs($suivant, $total) {
                if ($this->limite_requete['limite'] <= $total) {
                        $url_suivante = '&navigation.depart='.$suivant.'&navigation.limite='.$this->limite_requete['limite'];
                } else {
                        $url_suivante = '';
                }
                return $url_suivante;
        }
        
        /**
         * Description : 
         * Permet de former les limites de la requete retournant les résultats precedents.
         * Cette url sera afficher dans l'entete de la taxons/105reponse retournée en format JSON (retour.format=defaut)
         * @return string : la fin de l'url decrivant les limites des resultats precedents. 
         * Si aucun résultats ne precedent, une chaine de caractère vide est retournée
         */
        public function recupererLesLimitesPrecedentesObs($suivant) {
                $url_precedente = '';
                // tentative de fonctionnement normal
                if (strpos($this->limite_requete['depart'], ':') === false && $this->limite_requete['depart'] != 0) {
                        $departPrec = max(0, $this->limite_requete['depart'] - $this->limite_requete['limite']);
                        $url_precedente = "&navigation.depart=$departPrec&navigation.limite=" . $this->limite_requete['limite'];
                }
                if (isset($this->table_param['navigation_depart'])) { // si on utilise un parametre de départ
                        // si l'adresse d'appel de la page est inférieur au départ
                        $regex = '/http:\/\/.*\/service:eflore:0.1\/chorodep\/observations\?.*navigation.depart=(.*\:[0-9]*).*/';
                        if (isset($_SERVER['HTTP_REFERER']) && preg_match($regex, $_SERVER['HTTP_REFERER'], $match)) {
                                if ($match[1] != $this->table_param['navigation_depart'] && $match[1] != $suivant) {
                                        $url_precedente = '&navigation.depart='.$match[1].'&navigation.limite='.$this->limite_requete['limite'];
                                }
                        } else {
                                $url_precedente = '&navigation.limite='.$this->limite_requete['limite'];
                        }
                }
                return $url_precedente;
        }

}
?>