Subversion Repositories eFlore/Applications.cel

Rev

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

<?php

// In : utf8
// Out : utf8

/*

Octobre 2010 David Delon.
Import d'observations dans le carnet en ligne à partir d'un fichier excel chargé par l'utilisateur
et liaison d'images déjà chargee aux observations ainsi crées.

Nom des colonnes imposé, mais présence de toutes les colonnes non obligatoires, ordre non imposé
Aucune valeur dans les colonnes n'est obligatoire
Pour une ligne donnée, si tous les champs vides on ne fait rien, ou si seul le champ image est présent.
Si la seule différence entre deux lignes est la valeur de la colonne image, on considère que c'est la même observation à laquelle on associe plusieurs images.
Si au moins deux lignes (ou plus) sont complètement identiques on prend en compte une seule ligne (les doublons sont éliminés).

*/


// Nom des colonnes

define('COMMUNE','commune'); // soit un nom de commune, soit un code INSEE (5 chiffres), ou "nom de commune (numero departement)"
define('LIEUDIT','lieu-dit'); // Texte libre
define('STATION','station'); // Texte libre
define('MILIEU','milieu'); // Texte libre
define('LATITUDE','latitude'); // En decimal systeme WGS84
define('LONGITUDE','longitude'); // En decimal systeme WGS84 
define('NOTES','notes'); // Texte libre
define('DATEOBS','date'); // date au format jj/mm/aaaa
define('ESPECE','espece'); // texte libre, nom latin, ou code nomenclatural (format BDNFFnn999999)
define('IMAGE','image'); //  nom des fichiers images préalablement uploadés sur le CEL séparés par des "/"
define('DEPARTEMENT','departement'); //  Texte libre
define('TRANSMETTRE','transmettre'); //  "1" ou "oui", toute autre valeur (y compris vide) sera consideree comme "non""


// Resultat de l'analyse d'une ligne
define('LIGNE_VIDE',1); //  
define('LIGNE_NORMALE',2); //  
define('LIGNE_IMAGE_SEULEMENT',3); //  

// Parser de Nom
include('NameParser.php');

Class InventoryImportExcel extends DBAccessor  {

// Element constituant une observation 

        var $format_observation=array(COMMUNE ,LIEUDIT ,STATION , DEPARTEMENT, MILIEU ,LATITUDE ,LONGITUDE ,NOTES ,DATEOBS ,ESPECE ,TRANSMETTRE, IMAGE );

// Fichier configuration
        var $config;

// Encapsulation classe lecture fichier excel
        var $extendExcelReader;

// Dernier numero d'ordre utilise
        var $dernier_ordre=1;
        
        var $cpt_images_liees=0;

/**
 Constructeur
**/
        function InventoryImportExcel($config) {

                $this->config=$config;
                // Pas d'heritage multiple en php :(

                $this->extendExcelReader = new ExcelReader();
                $this->extendExcelReader->initExcelReader();
        }

/**
 Sur post
**/
        function createElement($pairs) {


                $pairs['utilisateur']= $_POST['identifiant'];
                if(!isset($_SESSION)) {session_start();}
        $this->controleUtilisateur($pairs['utilisateur']);

        foreach($_FILES as $file) { // C'est le plus simple
            $infos_fichier = $file ;
        }

                // Chargement tableau en memoire
                $data = new Spreadsheet_Excel_Reader($infos_fichier['tmp_name'], false); // false : pour menager la memoire.
                $arr = array();

                $rowcount=$data->rowcount(0);
                $colcount=$data->colcount(0);

                if ($rowcount<=1) { // TODO : retour erreur
                        print "Tableau vide";
                        exit;
                }

                // Chargement tableau 
        for($row=1;$row<=$rowcount;$row++) 
            for($col=1;$col<=$colcount;$col++) 
                $arr[$col][$row] = $data->val($row,$col,0); // Attention, inversion voulue
              
                // 1 : Traitement intitules
                $line = array();

                /* Les colonnes ne sont pas forcemment dans l'ordre  : on les extrait pour traitement futur  */
        for($col=1;$col<=$colcount;$col++) {
            $colonne=strtolower($arr[$col][1]);
            $colonne=trim($colonne);
            $colonne=cp1252_to_utf8($colonne);
            $colonne=remove_accent($colonne);
            switch ($colonne) {  // On ne garde que les colonnes que l'on souhaite traiter
                case COMMUNE:
                case LIEUDIT:
                case STATION:
                case MILIEU:
                case DEPARTEMENT:
                case LATITUDE:
                case LONGITUDE:
                case NOTES:
                case DATEOBS:
                case ESPECE:
                case TRANSMETTRE:
                case IMAGE:
                    $selection=array_values($arr[$col]);
                    array_shift($selection); // On ne garde pas la premiere ligne, qui contient les intitules
                    $line[$colonne]=$selection;
                    break;

            }
        }       
                // 1 : Traitement lignes
                $cpt_obs=0;
                $cpt_img=0;

        /* Recherche dernier numero d'ordre utilise : pas de mise a jour concurente a priori */
        $DB=$this->connectDB($this->config,'database_cel'); 
        $query="SELECT MAX(ordre) AS ordre FROM cel_inventory WHERE identifiant='".$DB->escapeSimple($pairs['utilisateur'])."' ";

        $res =& $DB->query($query);
        if (DB::isError($res)) {
            die($res->getMessage());
        }

        while ($row =& $res->fetchrow(DB_FETCHMODE_ASSOC)) {
            $this->dernier_ordre=$row['ordre']; // 1  par defaut
        }

                for ($i=0;$i<=$rowcount-1;$i++) {
                        // On saute les eventuelles lignes vides du debut et les lignes contenant des information sur image uniquement
                        while ((in_array($retour_analyse=$this->analyserLigne($line,$i),array(LIGNE_IMAGE_SEULEMENT, LIGNE_VIDE))) && ($i<=$rowcount)) {
                                if  ($retour_analyse==LIGNE_IMAGE_SEULEMENT) {
                                        // print "image non rattachee a une observation";
                                }
                                else {
                                        // print "vide";
                                }
                                $i++;
                        }
                        while (($this->analyserLigne($line,$i)==LIGNE_NORMALE) && ($i<=$rowcount)) {
                                $ordre=$this->traiterLigne($line,$i,$pairs['utilisateur'],$DB);
                                if ($ordre>0) {
                                        $cpt_obs++; // Compteur d'observations crees
                                }
                                $i++;
                                // On saute les lignes vide ou on traite les lignes suivantes contenant des informations sur image seulement
                                while ((in_array($retour_analyse=$this->analyserLigne($line,$i),array(LIGNE_IMAGE_SEULEMENT, LIGNE_VIDE))) && ($i<=$rowcount)) {
                                        if  ($retour_analyse==LIGNE_IMAGE_SEULEMENT) {
                                                $this->traiterLigneComplement($line,$i,$pairs['utilisateur'],$ordre); // images supplementaires
                                        }
                                        else {
                                                // print "vide";
                                        }
                                        $i++;
                                }       
                        }
                }
                //print $cpt_obs ." nouvelle(s) observation(s) !";
                $message = '';
                
                if($this->cpt_images_liees > 0) {
                        $message = $this->cpt_images_liees.' images liees pour ';
                }
                
                $message .= $cpt_obs;
                print $message;

        }

function analyserLigne($line,$i) {
        
        $ligne_vide=true;
        $ligne_image_seulement=true;
        $ligne_normale=true;
        
        $ligne_identique_sauf_image = true;
        
        foreach ($this->format_observation as $colonne) {
                
                if($i < 1) {
                        $ligne_identique_sauf_image = false;
                } else {
                        
                        if($colonne!= IMAGE && isset($line[$colonne]) && isset($line[$colonne][$i - 1]) && isset($line[$colonne][$i]) 
                                && $line[$colonne][$i - 1] != $line[$colonne][$i] && $line[$colonne][$i] != '') {
                                $ligne_identique_sauf_image = false;
                        }
                } 
                
                if (isset ($line[$colonne][$i]) && $line[$colonne][$i]!='') {
                        if ($colonne!=IMAGE) {
                                $ligne_image_seulement=false;
                                $ligne_vide=false;
                        }               
                        $ligne_vide=false;
                }               
        }
        
        if ($ligne_vide) {
                return LIGNE_VIDE;
        }
        else {
                if ($ligne_image_seulement || $ligne_identique_sauf_image) {
                        return LIGNE_IMAGE_SEULEMENT;
                }
                else {
                        return LIGNE_NORMALE;
                }
        }
        

}

function traiterLigne($line,$i,$utilisateur,$DB) { // Controle donnee et insertion
        
        $info_image=array();
        $info_transmettre = "0";
        
        foreach ($this->format_observation as $colonne) {
                if (isset ($line[$colonne][$i]) && $line[$colonne][$i]!='') {
                        switch ($colonne) {  // On ne garde que les colonnes que l'on souhaite traiter
                                case COMMUNE:
                                        $info_commune=$this->traiterCommune($line[COMMUNE][$i]);
                                        break;
                                case LIEUDIT:
                                        $info_lieudit=$this->traiterLieudit($line[LIEUDIT][$i]);
                                        break;
                                case STATION:
                                        $info_station=$this->traiterStation($line[STATION][$i]);
                                        break;
                                case MILIEU:
                                        $info_milieu=$this->traiterMilieu($line[MILIEU][$i]);
                                        break;
                case DEPARTEMENT:
                                        $info_commune['code']=$this->traiterDepartement($line[DEPARTEMENT][$i]);
                                        break;
                                case LATITUDE:
                                        $info_latitude=$this->traiterLatitude($line[LATITUDE][$i]);
                                        break;
                                case LONGITUDE:
                                        $info_longitude=$this->traiterLongitude($line[LONGITUDE][$i]);
                                        break;
                                case NOTES:
                                        $info_notes=$this->traiterNotes($line[NOTES][$i]);
                                        break;
                                case DATEOBS:
                                        $info_dateobs=$this->traiterDateObs($line[DATEOBS][$i]);
                                        break;
                                case TRANSMETTRE:
                                        $info_transmettre=$this->traiterTransmettre($line[TRANSMETTRE][$i]);
                                break;
                                case ESPECE:
                                        $info_espece=$this->traiterEspece($line[ESPECE][$i]);
                    if (isset($info_espece['en_id_nom']) && $info_espece['en_id_nom']!='') {
                        $complement=$this->rechercherInformationsComplementaires($info_espece['en_id_nom']);
                        $info_espece['nom_ret']=$complement['Nom_Retenu'];
                        $info_espece['num_nom_ret']=$complement['Num_Nom_Retenu'];
                        $info_espece['num_taxon']=$complement['Num_Taxon'];
                        $info_espece['famille']=$complement['Famille'];
                    }
                    break;
                                case IMAGE:
                                        $info_image=$this->traiterImage($line[IMAGE][$i],$utilisateur); // Image separee par des / +  utilisateur
                                        break;
                        }
                }
                else {  
                        switch($colonne) {
                                case COMMUNE:
                                        $info_commune['name']="000null";
                                        break;
                                case LIEUDIT:
                                        $info_lieudit="000null";
                                        break;
                                case STATION:
                                        $info_station="000null";
                                        break;
                                case MILIEU:
                                        $info_milieu="000null";
                                        break;
                                case DEPARTEMENT:
                            if (!isset ($info_commune['code']) || $info_commune['code']=='') {
                                            $info_commune['code']="000null";
                    }
                                        break;
                                case LATITUDE:
                                        $info_latitude="000null";
                                        break;
                                case LONGITUDE:
                                        $info_longitude="000null";
                                        break;
                                case NOTES:
                                        $info_notes='';
                                        break;
                                case TRANSMETTRE:
                                        $info_transmettre = "0";
                                break;

                        }

                }
        }

                $this->dernier_ordre++;

                list($jour,$mois,$annee)=split("/",$info_dateobs);
                $info_dateobs=$annee."-".$mois."-".$jour." 0:0:0";
                $query  = "INSERT INTO cel_inventory (identifiant,ordre,nom_sel,num_nom_sel,nom_ret,num_nom_ret,num_taxon,famille,location,id_location,date_observation,lieudit,station, milieu, commentaire, transmission, date_creation,date_modification,coord_x,coord_y) " .
                    " VALUES('".$DB->escapeSimple($utilisateur)."','".
                    $DB->escapeSimple($this->dernier_ordre)."','".
                    $DB->escapeSimple($info_espece['nom_sel'])."','".
                    $DB->escapeSimple($info_espece['en_id_nom'])."','".
                    $DB->escapeSimple($info_espece['nom_ret'])."','".
                    $DB->escapeSimple($info_espece['num_nom_ret'])."','".
                    $DB->escapeSimple($info_espece['num_taxon'])."','".
                    $DB->escapeSimple($info_espece['famille'])."','".
                    $DB->escapeSimple($info_commune['name'])."','".
                    $DB->escapeSimple($info_commune['code'])."','".
                    $DB->escapeSimple($info_dateobs)."','".
                    $DB->escapeSimple($info_lieudit)."','".
                    $DB->escapeSimple($info_station)."','".
                    $DB->escapeSimple($info_milieu)."','".
                    $DB->escapeSimple($info_notes)."','".
                    $DB->escapeSimple($info_transmettre)."',".
                    "now() , now(),'".
                    $DB->escapeSimple($info_latitude)."','".
                    $DB->escapeSimple($info_longitude)."')";
//              print "\n";
                   $res =& $DB->query($query);

                if (PEAR::isError($res)) {
                        return false;
                }
        
        // creation lien image
        foreach ($info_image as $pic) {

                $query = 'INSERT INTO cel_obs_images (coi_ce_image, coi_ce_utilisateur, coi_ce_observation ) VALUES ("'.$DB->escapeSimple($pic['ci_id_image']).'","'.$DB->escapeSimple($utilisateur).'",    "'.$DB->escapeSimple($this->dernier_ordre).'") ON DUPLICATE KEY UPDATE coi_ce_image = coi_ce_image' ;       

                $res =& $DB->query($query);

                if (PEAR::isError($res)) {
                        return false;
                } else {
                        $this->cpt_images_liees++;
                }
        }

                return $this->dernier_ordre;


}

function traiterLigneComplement($line,$i,$utilisateur, $ordre = null) {

        $info_image=$this->traiterImage($line[IMAGE][$i],$utilisateur); // Image separee par des / +  utilisateur
        
        // creation lien image
        foreach ($info_image as $pic) {

                $DB=$this->connectDB($this->config,'cel_db');
                $query = 'INSERT INTO cel_obs_images (coi_ce_image, coi_ce_utilisateur, coi_ce_observation) VALUES ("'.$DB->escapeSimple($pic['ci_id_image']).'","'.$DB->escapeSimple($utilisateur).'",    "'.$DB->escapeSimple($this->dernier_ordre).'") ON DUPLICATE KEY UPDATE coi_ce_image = coi_ce_image' ;        

                $res =& $DB->query($query);

        if (PEAR::isError($res)) {
            return false;
        } else {
                $this->cpt_images_liees++;
        }
        }
}
function traiterCommune($identifiant_commune) {  // Recherche correspondance sur nom, si pas unique, correspondance dep. sinon code insee

    $identifiant_commune=trim($identifiant_commune);
    $identifiant_commune=utf8_encode($identifiant_commune); // FIXME : devrait deja etre en utf8 a ce niveau

        preg_match('/(.*) \(([0-9][0-9]*)\)/',$identifiant_commune,$elements);

    $DB=$this->connectDB($this->config,'database_cel'); // FIXME regarder si opportun ici

        if (isset($elements[1])) { // commune + departement : montpellier (34)
                $nom_commune=$elements[1];
                $code_commune=$elements[2];
            $query="SELECT DISTINCT name, code  FROM locations WHERE name = '".$DB->escapeSimple($nom_commune)."' AND code ='".$DB->escapeSimple($code_commune)."'";
        }
        else { // Code insee seul 
        preg_match('/([0-9][0-9]*)|(2A[0-9][0-9]*)|(2B[0-9][0-9]*)/',$identifiant_commune,$elements);
        if (isset($elements[1])) { // code insee  commune
            $code_insee_commune=$elements[1];
            $query="SELECT DISTINCT name, code  FROM locations WHERE insee_code ='".$DB->escapeSimple($code_insee_commune)."'";
        }       
        else { // Commune seule (le departement sera recupere dans la colonne departement si elle est presente, on prend le risque ici de retourner une mauvaise
               // Commune
            preg_match('/(.*)/',$identifiant_commune,$elements);
            if (isset($elements[1])) { // commune 
                $nom_commune=$elements[1];
                $nom_commune=trim($nom_commune);
                $nom_commune=utf8_decode($nom_commune);
                $nom_commune=cp1252_to_utf8($nom_commune);
                $nom_commune=remove_accent($nom_commune);
                $nom_commune=preg_replace("/ /","%",$nom_commune);
                $query="SELECT DISTINCT name, code  FROM locations WHERE name like '".$DB->escapeSimple($nom_commune)."'";
            }
        }
        }

        $res =& $DB->query($query);
    if (DB::isError($res)) {
                 die($res->getMessage());
        }
        
        $commune_code = $res->fetchrow(DB_FETCHMODE_ASSOC);
        
        // cas de la commune introuvable dans le référentiel
        if(!is_array($commune_code) || count($commune_code) == 0) {
                $commune_code['name'] = fix_latin($identifiant_commune);
                $commune_code['code'] = '000null';
        }
        return $commune_code;
}

function traiterLieudit($lieudit) { // texte libre

        //echo "traitement lieudit";
    $lieudit=fix_latin($lieudit);
        return trim($lieudit);
}

function traiterStation($station) { // texte libre
//      echo "traitement station";
    $station=fix_latin($station);
        return trim($station);
}

function traiterMilieu($milieu) { // texte libre
//      echo "traitement milieu";
    $milieu=fix_latin($milieu);
        return trim($milieu);
}

function traiterDepartement($departement) { // texte libre

        if(is_numeric($departement) && strlen($departement) == 5) {
                $departement = substr($departement,0,2);
        }
        
        if(is_numeric($departement) && strlen($departement) == 4) {
                $departement = substr($departement,0,1);
                $departement = "0"+$departement;
        }

        if(is_numeric($departement) && $departement <= 9) {
                $departement = "0"+$departement;
        }
        return utf8_encode(trim($departement));
}

function traiterLatitude($latitude) {   //  verifier formal decimal + limite france ? TODO 
//      echo "traitement latitude";
        return trim($latitude);
}

function traiterLongitude($longitude) { // verifier format decimal + limite france ? TODO 
//      echo "traitement longitude";
        return trim($longitude);
}

function traiterNotes($notes) { // texte libre
//      echo "traitement notes";
    $notes=remove_accent($notes);
        return utf8_encode(trim($notes));
}

function traiterDateObs($dateobs) { // verifier jj/mm/aaaa sinon date vide TODO 
//      echo "traitement dateobs";
        return trim($dateobs);
}

function traiterTransmettre($transmettre) {
        
        $transmission = '0';
        
        if (trim($transmettre) == "1" || trim($transmettre) == "oui") { 
                $transmission = '1';
        }
        
        return $transmission;
}

function traiterEspece($identifiant_espece) {  // texte libre, nom scientifique , ou code nomenclatural (format BDNFFnn999999) ou code taxonomique (format BDNFFnt999999)

//      echo "traitement  espece";
        $identifiant_espece=trim($identifiant_espece);
 
        $identifiant_espece=utf8_encode($identifiant_espece); // FIXME : devrait deja etre en utf8 a ce niveau

            preg_match('/BDNFFnn([0-9][0-9]*)/',$identifiant_espece,$elements);
        
                if (isset($elements[1])) { // Numero nomenclatural 


            // Recherche du nom associe
            $DB=$this->connectDB($this->config); // FIXME : gerer cache de connection
            $query = "SELECT DISTINCT en_nom_genre, en_epithete_espece, en_nom_supra_generique, en_epithete_infra_generique,".
                "   auteur_bex.enaia_intitule_abrege AS abreviation_auteur_basio_ex ".
                " , auteur_b.enaia_intitule_abrege AS abreviation_auteur_basio ".
                " , auteur_mex.enaia_intitule_abrege AS abreviation_auteur_modif_ex ".
                " , auteur_m.enaia_intitule_abrege AS abreviation_auteur_modif ".
                " , en_epithete_espece, en_epithete_infra_specifique, enrg_abreviation_rang, en_id_nom" .
                " FROM eflore_nom, eflore_nom_rang, eflore_selection_nom a,  " .
                " eflore_naturaliste_intitule_abreviation AS auteur_bex ".
                " , eflore_naturaliste_intitule_abreviation AS auteur_b ".
                " , eflore_naturaliste_intitule_abreviation AS auteur_mex ".
                " , eflore_naturaliste_intitule_abreviation AS auteur_m ".
                " WHERE a.esn_id_nom= '".$elements[1]. "'".
                " AND a.esn_id_version_projet_taxon = 25 ".
                " AND en_ce_rang = enrg_id_rang" .
                " AND en_id_nom = a.esn_id_nom" .
                " AND en_ce_auteur_basio_ex = auteur_bex.enaia_id_intitule_naturaliste_abrege ".
                " AND en_ce_auteur_basio = auteur_b.enaia_id_intitule_naturaliste_abrege  ".
                " AND en_ce_auteur_modif_ex = auteur_mex.enaia_id_intitule_naturaliste_abrege ".
                " AND en_ce_auteur_modif = auteur_m.enaia_id_intitule_naturaliste_abrege ".
                " AND a.esn_id_version_projet_taxon=en_id_version_projet_nom ";

            $res =& $DB->query($query);


            if (DB::isError($res)) {
                die($res->getMessage());
            }

            $row =& $res->fetchrow(DB_FETCHMODE_ASSOC);
            return array("nom_sel"=>$this->formaterNom($row),"en_id_nom"=>$elements[1]);

                }

                else { //  Numero taxonomique ou nom scientifique
                preg_match('/BDNFFnt([0-9][0-9]*)/',$identifiant_espece,$elements);
                        
                    if (isset($elements[1])) { // Numero taxonomique
    
                $DB=$this->connectDB($this->config);

                $query = "SELECT DISTINCT en_nom_genre, en_epithete_espece, en_nom_supra_generique, en_epithete_infra_generique,".
                    "   auteur_bex.enaia_intitule_abrege AS abreviation_auteur_basio_ex ".
                    " , auteur_b.enaia_intitule_abrege AS abreviation_auteur_basio ".
                    " , auteur_mex.enaia_intitule_abrege AS abreviation_auteur_modif_ex ".
                    " , auteur_m.enaia_intitule_abrege AS abreviation_auteur_modif ".
                    " , en_epithete_espece, en_epithete_infra_specifique, enrg_abreviation_rang, en_id_nom" .
                    " FROM eflore_nom, eflore_nom_rang," .
                    "     eflore_naturaliste_intitule_abreviation AS auteur_bex ".
                    "   , eflore_naturaliste_intitule_abreviation AS auteur_b ".
                    "   , eflore_naturaliste_intitule_abreviation AS auteur_mex ".
                    "   , eflore_naturaliste_intitule_abreviation AS auteur_m ".
                    " , eflore_selection_nom ".
                    " WHERE esn_id_taxon = '".$elements[1]. "'".
                    " AND esn_id_version_projet_taxon = 25 ".
                    " AND esn_ce_statut=3 ".
                    " AND en_id_nom = esn_id_nom" .
                    " AND en_ce_rang = enrg_id_rang" .
                    " AND en_ce_auteur_basio_ex = auteur_bex.enaia_id_intitule_naturaliste_abrege ".
                    " AND en_ce_auteur_basio = auteur_b.enaia_id_intitule_naturaliste_abrege  ".
                    " AND en_ce_auteur_modif_ex = auteur_mex.enaia_id_intitule_naturaliste_abrege ".
                    " AND en_ce_auteur_modif = auteur_m.enaia_id_intitule_naturaliste_abrege ".
                    " AND esn_id_version_projet_taxon=en_id_version_projet_nom ";

                $res =& $DB->query($query);

                if (DB::isError($res)) {
                    die($res->getMessage());
                }

                $row =& $res->fetchrow(DB_FETCHMODE_ASSOC);
                return array("nom_sel"=>$this->formaterNom($row),"en_id_nom"=>$row['en_id_nom']);


            }

            else { // Nom scientifique
                $nameparser=new NameParser();
                $nom_latin_decoupe=$nameparser->parse($identifiant_espece);

//print_r($nom_latin_decoupe);
                    $DB=$this->connectDB($this->config); // FIXME regarder si opportun ici

                        // requete sous espece (on privilegie les noms retenu cf tri par esn_ce_statut) 
                        if (isset($nom_latin_decoupe['infra']) && $nom_latin_decoupe['infra']!="") {
                            $query="SELECT DISTINCT en_id_nom, esn_ce_statut" .
                                            " FROM eflore_nom, eflore_nom_rang, eflore_selection_nom " .
                                            " WHERE en_id_version_projet_nom = '25' AND en_nom_genre = '".$DB->escapeSimple($nom_latin_decoupe['genus'])."' " .
                                            " AND enrg_abreviation_rang = '".$DB->escapeSimple($nom_latin_decoupe['infra_type'])."' " .
                                            " AND en_epithete_infra_specifique = '".$DB->escapeSimple($nom_latin_decoupe['infra'])."' " .
                                            " AND esn_id_nom= en_id_nom ".
                                            " AND esn_id_version_projet_taxon=en_id_version_projet_nom " .
                                            " AND en_epithete_espece =  '".$DB->escapeSimple($nom_latin_decoupe['species'])."' AND en_ce_rang = enrg_id_rang " .
                                            " ORDER BY esn_ce_statut ".
                                            " LIMIT 1";
                        }
                        else { // espece  (on privilegie les noms retenu cf tri par esn_ce_statut)
                             $query="SELECT DISTINCT en_id_nom, esn_ce_statut" .
                                            " FROM eflore_nom, eflore_nom_rang, eflore_selection_nom " .
                                            " WHERE en_id_version_projet_nom = '25' AND en_nom_genre = '".$DB->escapeSimple($nom_latin_decoupe['genus'])."' " .
                                            " AND enrg_abreviation_rang = 'sp.' " .
                                            " AND esn_id_nom= en_id_nom ".
                                            " AND esn_id_version_projet_taxon=en_id_version_projet_nom " .
                                            " AND en_epithete_espece =  '".$DB->escapeSimple($nom_latin_decoupe['species'])."' AND en_ce_rang = enrg_id_rang " .
                                            " ORDER BY esn_ce_statut ".
                                            " LIMIT 1";
                        
                        }
                $res =& $DB->query($query);
                if (DB::isError($res)) {
                     die($res->getMessage());
                }

                $id_nom=$res->fetchrow(DB_FETCHMODE_ASSOC);

                // Recherche du nom associe
                $DB=$this->connectDB($this->config); // FIXME : gerer cache de connection
                $query = "SELECT DISTINCT en_nom_genre, en_epithete_espece, en_nom_supra_generique, en_epithete_infra_generique,".
                    "   auteur_bex.enaia_intitule_abrege AS abreviation_auteur_basio_ex ".
                    " , auteur_b.enaia_intitule_abrege AS abreviation_auteur_basio ".
                    " , auteur_mex.enaia_intitule_abrege AS abreviation_auteur_modif_ex ".
                    " , auteur_m.enaia_intitule_abrege AS abreviation_auteur_modif ".
                    " , en_epithete_espece, en_epithete_infra_specifique, enrg_abreviation_rang, en_id_nom" .
                    " FROM eflore_nom, eflore_nom_rang, eflore_selection_nom a,  " .
                    "         eflore_naturaliste_intitule_abreviation AS auteur_bex ".
                    "   , eflore_naturaliste_intitule_abreviation AS auteur_b ".
                    "   , eflore_naturaliste_intitule_abreviation AS auteur_mex ".
                    "   , eflore_naturaliste_intitule_abreviation AS auteur_m ".
                    " WHERE a.esn_id_nom= '".$id_nom['en_id_nom']. "'".
                    " AND a.esn_id_version_projet_taxon = 25 ".
                    " AND en_ce_rang = enrg_id_rang" .
                    " AND en_id_nom = a.esn_id_nom" .
                    " AND en_ce_auteur_basio_ex = auteur_bex.enaia_id_intitule_naturaliste_abrege ".
                    " AND en_ce_auteur_basio = auteur_b.enaia_id_intitule_naturaliste_abrege  ".
                    " AND en_ce_auteur_modif_ex = auteur_mex.enaia_id_intitule_naturaliste_abrege ".
                    " AND en_ce_auteur_modif = auteur_m.enaia_id_intitule_naturaliste_abrege ".
                    " AND a.esn_id_version_projet_taxon=en_id_version_projet_nom ";
                $res =& $DB->query($query);


                if (DB::isError($res)) {
                    die($res->getMessage());
                }

                if ($res->numRows() > 0 ) {
                    $row =& $res->fetchrow(DB_FETCHMODE_ASSOC);
                    return array("nom_sel"=>$this->formaterNom($row),"en_id_nom"=>$id_nom['en_id_nom']);
                }
                else {
                    return array("nom_sel"=>$identifiant_espece);
                }


                }
            }
        

}



function traiterImage($images,$utilisateur) { // recherche id image de ce nom 

        $DB=$this->connectDB($this->config,'cel_db');

        $liste_images = explode("/",$images) ;

        $row =array();
        foreach($liste_images as $image) {

                $query="SELECT * FROM cel_images WHERE ci_ce_utilisateur='".$DB->escapeSimple($utilisateur)."' AND ci_nom_original='".$DB->escapeSimple($image)."'";

                $res  =& $DB->query($query);
                $row [] =& $res->fetchrow(DB_FETCHMODE_ASSOC);

                if (DB::isError($res)) {
                    die($res->getMessage());
                }

        }
        return $row;


}

       function rechercherInformationsComplementaires($numNom) { // Num taxon, Num retenu ...

                $DB=$this->connectDB($this->config);

                $query = "SELECT DISTINCT en_nom_genre, en_epithete_espece, en_nom_supra_generique, en_epithete_infra_generique,".
                    "   auteur_bex.enaia_intitule_abrege AS abreviation_auteur_basio_ex ".
                    " , auteur_b.enaia_intitule_abrege AS abreviation_auteur_basio ".
                    " , auteur_mex.enaia_intitule_abrege AS abreviation_auteur_modif_ex ".
                    " , auteur_m.enaia_intitule_abrege AS abreviation_auteur_modif ".
                    " , en_epithete_espece, en_epithete_infra_specifique, enrg_abreviation_rang, b.esn_id_taxon, b.esn_id_nom" .
                    " FROM eflore_nom, eflore_nom_rang," .
                    "     eflore_naturaliste_intitule_abreviation AS auteur_bex ".
                    "   , eflore_naturaliste_intitule_abreviation AS auteur_b ".
                    "   , eflore_naturaliste_intitule_abreviation AS auteur_mex ".
                    "   , eflore_naturaliste_intitule_abreviation AS auteur_m ".
                    " ,eflore_selection_nom a, eflore_selection_nom b".
                    " WHERE a.esn_id_nom= ".$numNom.
                    " AND a.esn_id_version_projet_taxon = 25 ".
                    " AND a.esn_id_taxon=b.esn_id_taxon ".
                    " AND b.esn_ce_statut=3 ".
                    " AND a.esn_id_version_projet_taxon=b.esn_id_version_projet_taxon" .
                    " AND en_ce_rang = enrg_id_rang" .
                    " AND en_id_nom = b.esn_id_nom" .
                    " AND en_ce_auteur_basio_ex = auteur_bex.enaia_id_intitule_naturaliste_abrege ".
                    " AND en_ce_auteur_basio = auteur_b.enaia_id_intitule_naturaliste_abrege  ".
                    " AND en_ce_auteur_modif_ex = auteur_mex.enaia_id_intitule_naturaliste_abrege ".
                    " AND en_ce_auteur_modif = auteur_m.enaia_id_intitule_naturaliste_abrege ".
                    " AND a.esn_id_version_projet_taxon=en_id_version_projet_nom ";


                $res =& $DB->query($query);



                if (DB::isError($res)) {
                    die($res->getMessage());
                }

                // Nom retenu, Num Nomenclatural nom retenu, Num Taxon,

                $value=array('Nom_Retenu'=>"",'Num_Nom_Retenu'=>"0",'Num_Taxon'=>"0",'Famille'=>"");

                while ($row =& $res->fetchrow(DB_FETCHMODE_ASSOC)) {
                    $fam=$this->rechercherFamille($row['esn_id_taxon'],$DB);

                    // Recherche Famille 
                    while (($fam['en_ce_rang']!='fin') && ($fam['en_ce_rang'] !=120)) {
                        $fam=$this->rechercherFamille($fam['etr_id_taxon_2'],$DB);
                    }
                    if ($fam['en_ce_rang']==120) {
                        $famille=$fam['en_nom_supra_generique'];
                    }
                    else {
                        $famille="Famille inconnue";
                    }

                    $value=array('Nom_Retenu'=>$this->formaterNom($row),'Num_Nom_Retenu'=>$row['esn_id_nom'],'Num_Taxon'=>$row['esn_id_taxon'],'Famille'=>$famille);
                }

                return $value;



        }

function formaterNom($rawnom) {


                // Constitution du nom:
                $nom = '';

                if ($rawnom['en_nom_supra_generique'] != '') {
                    $nom .= $rawnom['en_nom_supra_generique'];
                } else if ($rawnom['en_epithete_infra_generique'] != '') {
                    $nom .= $rawnom['en_epithete_infra_generique'];
                } else {
                        if ($rawnom['en_nom_genre'] != '') {
                            $nom .=  $rawnom['en_nom_genre'];
                        }
                        if ($rawnom['en_epithete_espece']!= '') {
                            $nom .= ' '.$rawnom['en_epithete_espece'];
                        }
                        if ($rawnom['en_epithete_infra_specifique'] != '') {
                                if (!empty($rawnom['enrg_abreviation_rang'])) {
                                        $nom .= ' '.$rawnom['enrg_abreviation_rang'].'';
                                }
                                $nom .= ' '.$rawnom['en_epithete_infra_specifique'];
                        }

                }

                return $nom .$this->retournerAuteur($rawnom) ;

 }


function rechercherFamille($taxon,&$DB) {

    $row=array();

    $query="SELECT DISTINCT en_ce_rang, etr_id_taxon_2, en_id_nom, en_nom_supra_generique ".
        " FROM eflore_taxon_relation, eflore_selection_nom, eflore_nom ".
        " WHERE etr_id_taxon_1 = ".$taxon.
        " AND etr_id_version_projet_taxon_1 = 25 ".
        " AND etr_id_categorie_taxon = 3 ".
        " AND etr_id_valeur_taxon = 3 ".
        " AND esn_id_taxon =  etr_id_taxon_2 ".
        " AND esn_ce_statut = 3 ".
        " AND esn_id_version_projet_taxon = etr_id_version_projet_taxon_1 ".
        " AND en_id_nom = esn_id_nom ".
        " AND esn_id_version_projet_taxon=en_id_version_projet_nom  ";
    $res =& $DB->query($query);

    if (DB::isError($res)) {
        die($res->getMessage());
    }

    if ($row =& $res->fetchrow(DB_FETCHMODE_ASSOC)) {
        return $row;
    }
    else {
        $row['en_ce_rang']='fin';
        return $row;
    }

}


function retournerAuteur($rawnom) {

    $auteurs = '';
    $auteur_basio = '';
    $auteur_modif = '';
    if (!empty($rawnom['abreviation_auteur_basio_ex']) && $rawnom['abreviation_auteur_basio_ex']!='-' )  {
        $auteur_basio .= $rawnom['abreviation_auteur_basio_ex'];
        if (!empty($rawnom['abreviation_auteur_basio']) && $rawnom['abreviation_auteur_basio']!='-') {
            $auteur_basio .= ' ex '.$rawnom['abreviation_auteur_basio'];
        }
    } else if (!empty($rawnom['abreviation_auteur_basio']) && $rawnom['abreviation_auteur_basio']!='-') {
        $auteur_basio .= $rawnom['abreviation_auteur_basio'];
    }

    if (!empty($rawnom['abreviation_auteur_modif_ex']) && $rawnom['abreviation_auteur_modif_ex']!='-') {
        $auteur_modif .= $rawnom['abreviation_auteur_modif_ex'];
        if (!empty($rawnom['abreviation_auteur_modif']) && $rawnom['abreviation_auteur_modif']!='-') {
            $auteur_modif .= ' ex '.$rawnom['abreviation_auteur_modif'];
        }
    } else if (!empty($rawnom['abreviation_auteur_modif']) && $rawnom['abreviation_auteur_modif']!='-')  {
        $auteur_modif .= $rawnom['abreviation_auteur_modif'];
    }

    if (!empty($auteur_modif)) {
        $auteurs = ' ('.$auteur_basio.') '.$auteur_modif;
    } elseif (!empty($auteur_basio)) {
        $auteurs = ' '.$auteur_basio;
    }

    return $auteurs ;
}




}

function init_byte_map(){
    $byte_map = array();
    for($x=128;$x<256;++$x){
        $byte_map[chr($x)]=utf8_encode(chr($x));
    }
    $cp1252_map=array(
            "\x80"=>"\xE2\x82\xAC",    // EURO SIGN
            "\x82" => "\xE2\x80\x9A",  // SINGLE LOW-9 QUOTATION MARK
            "\x83" => "\xC6\x92",      // LATIN SMALL LETTER F WITH HOOK
            "\x84" => "\xE2\x80\x9E",  // DOUBLE LOW-9 QUOTATION MARK
            "\x85" => "\xE2\x80\xA6",  // HORIZONTAL ELLIPSIS
            "\x86" => "\xE2\x80\xA0",  // DAGGER
            "\x87" => "\xE2\x80\xA1",  // DOUBLE DAGGER
            "\x88" => "\xCB\x86",      // MODIFIER LETTER CIRCUMFLEX ACCENT
            "\x89" => "\xE2\x80\xB0",  // PER MILLE SIGN
            "\x8A" => "\xC5\xA0",      // LATIN CAPITAL LETTER S WITH CARON
            "\x8B" => "\xE2\x80\xB9",  // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
            "\x8C" => "\xC5\x92",      // LATIN CAPITAL LIGATURE OE
            "\x8E" => "\xC5\xBD",      // LATIN CAPITAL LETTER Z WITH CARON
            "\x91" => "\xE2\x80\x98",  // LEFT SINGLE QUOTATION MARK
            "\x92" => "\xE2\x80\x99",  // RIGHT SINGLE QUOTATION MARK
            "\x93" => "\xE2\x80\x9C",  // LEFT DOUBLE QUOTATION MARK
            "\x94" => "\xE2\x80\x9D",  // RIGHT DOUBLE QUOTATION MARK
            "\x95" => "\xE2\x80\xA2",  // BULLET
            "\x96" => "\xE2\x80\x93",  // EN DASH
            "\x97" => "\xE2\x80\x94",  // EM DASH
            "\x98" => "\xCB\x9C",      // SMALL TILDE
            "\x99" => "\xE2\x84\xA2",  // TRADE MARK SIGN
            "\x9A" => "\xC5\xA1",      // LATIN SMALL LETTER S WITH CARON
            "\x9B" => "\xE2\x80\xBA",  // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
            "\x9C" => "\xC5\x93",      // LATIN SMALL LIGATURE OE
            "\x9E" => "\xC5\xBE",      // LATIN SMALL LETTER Z WITH CARON
            "\x9F" => "\xC5\xB8"       // LATIN CAPITAL LETTER Y WITH DIAERESIS
                );
    foreach($cp1252_map as $k=>$v){
        $byte_map[$k]=$v;
    }
    
    return $byte_map;
}

function fix_latin($instr){
    
    $byte_map = init_byte_map();
    
    $ascii_char='[\x00-\x7F]';
    $cont_byte='[\x80-\xBF]';
    $utf8_2='[\xC0-\xDF]'.$cont_byte;
    $utf8_3='[\xE0-\xEF]'.$cont_byte.'{2}';
    $utf8_4='[\xF0-\xF7]'.$cont_byte.'{3}';
    $utf8_5='[\xF8-\xFB]'.$cont_byte.'{4}';
    
    $nibble_good_chars = "@^($ascii_char+|$utf8_2|$utf8_3|$utf8_4|$utf8_5)(.*)$@s";

    if(mb_check_encoding($instr,'UTF-8'))return $instr; // no need for the rest if it's all valid UTF-8 already
    $outstr='';
    $char='';
    $rest='';
    while((strlen($instr))>0){
        if(1==@preg_match($nibble_good_chars,$instr,$match)){
            $char=$match[1];
            $rest=$match[2];
            $outstr.=$char;
        }elseif(1==@preg_match('@^(.)(.*)$@s',$instr,$match)){
            $char=$match[1];
            $rest=$match[2];
            $outstr.=$byte_map[$char];
        }
        $instr=$rest;
    }
    return $outstr;
}


function remove_accent($str)
{
  $a = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î',
             'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß',
             'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î',
             'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Ā',
             'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ', 'ĉ', 'Ċ', 'ċ', 'Č', 'č', 'Ď', 'ď',
             'Đ', 'đ', 'Ē', 'ē', 'Ĕ', 'ĕ', 'Ė', 'ė', 'Ę', 'ę', 'Ě', 'ě', 'Ĝ', 'ĝ', 'Ğ',
             'ğ', 'Ġ', 'ġ', 'Ģ', 'ģ', 'Ĥ', 'ĥ', 'Ħ', 'ħ', 'Ĩ', 'ĩ', 'Ī', 'ī', 'Ĭ', 'ĭ',
             'Į', 'į', 'İ', 'ı', 'IJ', 'ij', 'Ĵ', 'ĵ', 'Ķ', 'ķ', 'Ĺ', 'ĺ', 'Ļ', 'ļ', 'Ľ',
             'ľ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'Ń', 'ń', 'Ņ', 'ņ', 'Ň', 'ň', 'ʼn', 'Ō', 'ō', 'Ŏ',
             'ŏ', 'Ő', 'ő', 'Œ', 'œ', 'Ŕ', 'ŕ', 'Ŗ', 'ŗ', 'Ř', 'ř', 'Ś', 'ś', 'Ŝ', 'ŝ',
             'Ş', 'ş', 'Š', 'š', 'Ţ', 'ţ', 'Ť', 'ť', 'Ŧ', 'ŧ', 'Ũ', 'ũ', 'Ū', 'ū', 'Ŭ',
             'ŭ', 'Ů', 'ů', 'Ű', 'ű', 'Ų', 'ų', 'Ŵ', 'ŵ', 'Ŷ', 'ŷ', 'Ÿ', 'Ź', 'ź', 'Ż',
             'ż', 'Ž', 'ž', 'ſ', 'ƒ', 'Ơ', 'ơ', 'Ư', 'ư', 'Ǎ', 'ǎ', 'Ǐ', 'ǐ', 'Ǒ', 'ǒ',
             'Ǔ', 'ǔ', 'Ǖ', 'ǖ', 'Ǘ', 'ǘ', 'Ǚ', 'ǚ', 'Ǜ', 'ǜ', 'Ǻ', 'ǻ', 'Ǽ', 'ǽ', 'Ǿ', 'ǿ');
             
  $b = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I',
             'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's',
             'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i',
             'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a',
             'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd',
             'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g',
             'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i',
             'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l',
             'N', 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R',
             'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't',
             'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y',
             'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u', 'A', 'a', 'I',
             'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o');
  return str_replace($a, $b, $str);
}


function cp1252_to_utf8($str) {
$cp1252_map = array ("\xc2\x80" => "\xe2\x82\xac",
"\xc2\x82" => "\xe2\x80\x9a",
"\xc2\x83" => "\xc6\x92",    
"\xc2\x84" => "\xe2\x80\x9e",
"\xc2\x85" => "\xe2\x80\xa6",
"\xc2\x86" => "\xe2\x80\xa0",
"\xc2\x87" => "\xe2\x80\xa1",
"\xc2\x88" => "\xcb\x86",
"\xc2\x89" => "\xe2\x80\xb0",
"\xc2\x8a" => "\xc5\xa0",
"\xc2\x8b" => "\xe2\x80\xb9",
"\xc2\x8c" => "\xc5\x92",
"\xc2\x8e" => "\xc5\xbd",
"\xc2\x91" => "\xe2\x80\x98",
"\xc2\x92" => "\xe2\x80\x99",
"\xc2\x93" => "\xe2\x80\x9c",
"\xc2\x94" => "\xe2\x80\x9d",
"\xc2\x95" => "\xe2\x80\xa2",
"\xc2\x96" => "\xe2\x80\x93",
"\xc2\x97" => "\xe2\x80\x94",

"\xc2\x98" => "\xcb\x9c",
"\xc2\x99" => "\xe2\x84\xa2",
"\xc2\x9a" => "\xc5\xa1",
"\xc2\x9b" => "\xe2\x80\xba",
"\xc2\x9c" => "\xc5\x93",
"\xc2\x9e" => "\xc5\xbe",
"\xc2\x9f" => "\xc5\xb8"
);
return strtr ( utf8_encode ( $str ), $cp1252_map );
}

/* +--Fin du code ---------------------------------------------------------------------------------------+
* $Log$
*
*
*/


?>