* @copyright Tela-Botanica 1999-2010 * @link http://www.tela-botanica.org/wikini/RTaxMethodo/wakka.php?wiki=MaNuel * @licence GPL v3 & CeCILL v2 * @version $Id$ */ // +-------------------------------------------------------------------------------------------------------------------+ class Importation extends ScriptCommande { const SCRIPT_NOM = 'importation'; const MANUEL_VERSION = '4.3'; private $referentiel = null; /*public $parametres = array( '-r' => array(true, true, 'referentiel de base'), '-f' => array(true, true, 'fichier à comparer'));*/ private $noms_supprimes = null; private $noms_colonnes = array(); private $rangs_bdnt_taxref = null; private $statuts_bdnt_taxref = null; private $correspondance_colonnes = array("CD_NOM" => "", "CD_SUP" => "", "CD_REF" => "", "RANG" => "rang", "LB_NOM" => "nom_sci", "LB_AUTEUR" => array("auteur","annee"), "FR" => "presence", "FR-FRA" => "presence_Ga", "FR-COR" => "presence_Co", "REU" => "presence", "GUA" => "presence_Guadeloupe", "SMSB" => array("presence_Saint_Martin", "presence_Saint_Barthelemy"), "SM" => "presence_Saint_Martin", "SB" => "presence_Saint_Barthelemy", "MAR" => "presence_Martinique", "GF" => "presence", "MAY" => "presence_Mayotte", "TAAF" => "presence_Taaf", "SPM" => "presence_Guadeloupe", "PF" => "presence_Polynesie", "NC" => "presence_Nouvelle_Caledonie", "BIBLIO" => "biblio_origine", "BDNGM" => "num_nom", "NUM_NOM" => "num_nom", "NOM_VERN" => "nom_francais"); private $sans_correspondance = array( "FG_VALIDITE", "habitat", "WF", "CLI", "EPA", "EU", "WLD", "ORACLE", "DATE_CREA", "ORIGINE_CREA", "NOM_COMPLET", "NOM_COMPLET_HTML", "GENRE", "ESPECE", "SOUS_ESPECE", "ANNEE"); /*public function executer() { $this->referentiel = $this->getParam('r'); // Lancement du test demandé $fichier = $this->getParam('f'); if (file_exists($fichier)) { $manuel_chemin = Config::get('chemin_appli').DS.'..'.DS.'configurations'.DS; $manuel_config_nom = 'referentiel_v'.self::MANUEL_VERSION.'.ini'; $this->manuel = parse_ini_file($manuel_chemin.$manuel_config_nom); $this->creerCorrespondanceRangBdntTaxref(); $donnees = $this->traiterFichierTaxref($fichier); Debug::printr("Fin du traitement du fichier."); $this->connecterPDO(); $this->creerTableTaxref(); $this->ajouterColonneCDNOM(); Debug::printr("Fin de la création de la table."); $this->ajouterDonneesTaxRef($donnees); Debug::printr("Fin de l'insertion des données."); $this->creerTableComparaison(); Debug::printr("Fin de la création de la table comparaison."); } }*/ public function executer() { // Récupération du dernier traitement demandé $this->traitementDao = new TraitementDao(); $this->traitement = $this->traitementDao->getDernierTraitement('tout', self::SCRIPT_NOM); if (isset($this->traitement)) { $this->referentiel = $this->traitement['referentiel_code']; // Récupération du nom de projet $fichier = $this->traitement['script_parametres']; if (file_exists($fichier)) { Debug::printr('Debute:'.$this->traitementDao->debuterTraitement($this->traitement['id_traitement'])); // Nettoyage des traitements obsolètes $traitements_obsoletes = $this->traitementDao->getTraitementsObsoletes($this->referentiel, self::SCRIPT_NOM); if (isset($traitements_obsoletes)) { Debug::printr('Supp. obsoletes:'.$this->traitementDao->supprimer($traitements_obsoletes)); } Debug::printr("Début du traitement du fichier."); $manuel_chemin = Config::get('chemin_appli').DS.'..'.DS.'configurations'.DS; $manuel_config_nom = 'referentiel_v'.self::MANUEL_VERSION.'.ini'; $this->manuel = parse_ini_file($manuel_chemin.$manuel_config_nom); $this->creerCorrespondanceRangBdntTaxref(); $donnees = $this->traiterFichierTaxref($fichier); Debug::printr("Fin du traitement du fichier."); $this->connecterPDO(); $this->creerTableTaxref(); $this->ajouterColonneCDNOM(); Debug::printr("Fin de la création de la table."); $this->ajouterDonneesTaxRef($donnees); Debug::printr("Fin de l'insertion des données."); $this->decouperNomSciTaxRef(); $this->creerTableComparaison(); Debug::printr("Fin de la création de la table comparaison."); Debug::printr('Termine:'.$this->traitementDao->terminerTraitement($this->traitement['id_traitement'])); } else { Debug::printr("Fichier introuvable".$fichier); Debug::printr('Termine:'.$this->traitementDao->terminerTraitement($this->traitement['id_traitement'])); } } else { Debug::printr("Pas de traitement"); } } // +-------------------------------------------------------------------------------------------------------------------+ private function creerTableTaxref() { $requete = "DROP TABLE IF EXISTS {$this->referentiel}_taxref; ". "CREATE TABLE {$this->referentiel}_taxref AS SELECT * FROM {$this->referentiel};". "ALTER TABLE {$this->referentiel}_taxref ADD PRIMARY KEY (num_nom);"; $resultat = $this->executerRequeter($requete); } private function ajouterColonneCDNOM() { $requete = "ALTER TABLE {$this->referentiel}_taxref ADD ". "`CD_NOM` INT( 15 ) NULL DEFAULT NULL COMMENT 'numéro correspondant dans la base taxref.';"; $resultat = $this->executerRequeter($requete); } private function ajouterDonneesTaxRef($liste_noms) { $i = 0; $j = 0; $requete = ""; foreach ($liste_noms as $nom) { $i++; $requete .= "UPDATE {$this->referentiel}_taxref SET ".implode(' , ', $nom). " WHERE {$nom['num_nom']} ;";//echo $requete; if ($i == 1000 || ($j*1000+$i) == count($liste_noms) ) { $j++; $resultat = $this->executerRequeter($requete.'commit;'); if ($resultat == null) { $resultat = $this->executerRequeter($requete.'commit;'); } $i = 0; $requete = ""; } } } private function creerTableComparaison() { foreach ($this->noms_colonnes as $colonne) { if (isset($this->correspondance_colonnes[$colonne]) && $this->correspondance_colonnes[$colonne] != "") { $nom_champ = $this->correspondance_colonnes[$colonne]; if (is_array($nom_champ)) { foreach ($nom_champ as $nom) { $champs_tax[] = "t.{$nom} AS tax_{$nom}"; $champs_tax[] = "b.{$nom} AS {$nom}"; $concat[] = "IF(t.{$nom} != b.{$nom}, '{$nom}, ', '')"; } } else { $champs_tax[] = "t.{$nom_champ} AS tax_{$nom_champ}"; $champs_tax[] = "b.{$nom_champ} AS {$nom_champ}"; $concat[] = "IF(t.{$nom_champ} != b.{$nom_champ}, '{$nom_champ}, ', '')"; } } } date_default_timezone_set('Europe/London'); $requete = "CREATE TABLE {$this->referentiel}_comparaison_".date("Y_m_d_H_i_s")." AS". " SELECT CONCAT(".implode(', ', $concat).") AS difference, ".implode(', ', $champs_tax). " FROM {$this->referentiel} b, {$this->referentiel}_taxref t". " WHERE b.num_nom = t.num_nom AND (b.nom_sci != t.nom_sci or b.auteur != t.auteur or b.annee != t.annee);"; //echo $requete; $resultat = $this->executerRequeter($requete); } // +-------------------------------------------------------------------------------------------------------------------+ private function traiterFichierTaxref($fichier) { $donnees = array(); if (($pointeur = fopen($fichier, "r")) !== FALSE) { $this->noms_colonnes = fgetcsv($pointeur, 1000, chr(9)); $num_nom = 0;//print_r($this->noms_colonnes); while (($ligne = fgetcsv($pointeur, 1000, chr(9))) !== FALSE) { $nombreChamps = count($ligne); $taxref[$ligne[0]] = $ligne;//print_r($ligne); for ($c=0; $c < $nombreChamps; $c++) { if (isset($this->correspondance_colonnes[$this->noms_colonnes[$c]])) { if (is_array($this->correspondance_colonnes[$this->noms_colonnes[$c]])) { if ($this->noms_colonnes[$c] == 'LB_AUTEUR') { if (preg_match('/(.*), +([0-9]{4})/', utf8_encode($ligne[$c]), $matches) == 1) { $nom['auteur'] = 'auteur="'.$matches[1].'"'; $nom['annee'] = 'annee="'.trim($matches[2]).'"'; } else { $nom['auteur'] = 'auteur="'.utf8_encode($ligne[$c]).'"'; $nom['annee'] = 'annee=""'; } } else { foreach ($this->correspondance_colonnes[$this->noms_colonnes[$c]] as $a=>$nom_colonne) { $nom[$nom_colonne] = $nom_colonne.'="'.$ligne[$c].'"'; } } } elseif ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "") { $nom[$this->noms_colonnes[$c]] = $ligne[$c]; } else { if ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "rang") { $rang = $this->rangs_bdnt_taxref[$ligne[$c]]; // à remettre si on décide de prendre les rangs taxref //$nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] = //$this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.$this->rangs_bdnt_taxref[$ligne[$c]].'"'; } elseif ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "num_nom") { $num_nom = $ligne[$c]; $nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] = $this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.$ligne[$c].'"'; } elseif ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "nom_sci") { $nom_sci = $ligne[$c]; $nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] = $this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.trim($ligne[$c]).'"'; } else { $nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] = $this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.trim(utf8_encode($ligne[$c])).'"'; } } } } $nom['exclure_taxref'] = 'exclure_taxref="0"'; $donnees[$num_nom] = $nom; $correspondance_taxref_bdnt[$nom['CD_NOM']] = $num_nom; } fclose($pointeur); $donnees = $this->changerNumerotation($donnees, $correspondance_taxref_bdnt, $taxref); } return $donnees; } private function changerNumerotation($donnees, $correspondance, $taxref) { $i=0;$j=0;$k=0; foreach ($donnees as $num_nom=>$infos) { if (isset($correspondance[$infos['CD_SUP']])) { $donnees[$num_nom]['num_tax_sup'] = "num_tax_sup=".$correspondance[$infos['CD_SUP']]; $i++; } elseif ($infos['CD_SUP'] != '') { $donnees[$num_nom]['num_tax_sup'] = "num_tax_sup=''"; //$sup[$infos['CD_NOM']] = $taxref[$infos['CD_NOM']]; $sup[$infos['CD_SUP']] = $infos['CD_SUP']; } unset($donnees[$num_nom]['CD_SUP']); if (isset($correspondance[$infos['CD_REF']])) { $donnees[$num_nom]['num_nom_retenu'] = "num_nom_retenu=".$correspondance[$infos['CD_REF']]; $j++; } elseif ($infos['CD_REF'] != '') {$k++; $donnees[$num_nom]['num_nom_retenu'] = "num_nom_retenu=''"; //$ref[$infos['CD_NOM']] = $taxref[$infos['CD_NOM']]; $ref[$infos['CD_REF']] = $infos['CD_REF']; } else { Debug::printr($infos['CD_NOM']."n'a pas de valeur pour CD_REF"); } unset($donnees[$num_nom]['CD_REF']); $donnees[$num_nom]['CD_NOM'] = 'CD_NOM='.$donnees[$num_nom]['CD_NOM']; }echo "les ".count($sup)." taxons supérieurs manquants :".implode(" ,", $sup)." \nles "."retenus ".implode(" ,", $ref); //$this->ecrireFichierCsv($ref, './retenu_absent.csv'); //$this->ajouterTaxonAbsent($abs); //$this->ecrireFichierCsv($sup, './superieur_absent.csv'); echo "$j correspondance pour nom retenu $i correspondance pour nom sup $k non pas de correspondance retenu"; return $donnees; } // rechercher dans reftax les numéros absent dans la base // modifier les tableaux ref et sup pour modifier $donnees (ajout + modif) private function ajouterTaxonAbsent($abs) { $requete = "SELECT ".implode(",", $this->noms_colonnes)." FROM taxref_v5 where CD_NOM IN (".implode(",", $abs).")"; echo $requete; } private function creerCorrespondanceRangBdntTaxref() { $rangs = explode(',', $this->manuel['rangs_bdnt_taxref']); foreach ($rangs as $rang) { list($id_bdnt, $code_taxref) = explode(':', trim($rang)); $this->rangs_bdnt_taxref[$code_taxref] = $id_bdnt; } } // +-------------------------------------------------------------------------------------------------------------------+ private function decouperNomSciTaxRef() { $requete = "SELECT num_nom, nom_sci, rang, type_epithete FROM {$this->referentiel}_taxref WHERE CD_NOM != ''"; $resultats = $this->executerRequeter($requete); foreach ($resultats as $nom) { extract($nom); $nomen =array('nom_supra_generique' => 'nom_supra_generique=""', 'genre' => 'genre=""', 'epithete_infra_generique' => 'epithete_infra_generique=""', 'epithete_sp' => 'epithete_sp=""', 'type_epithete' => 'type_epithete=""', 'epithete_infra_sp' => 'epithete_infra_sp=""', 'cultivar_groupe' => 'cultivar_groupe=""', 'cultivar' => 'cultivar=""', 'nom_commercial' => 'nom_commercial=""'); $parties_noms = explode(' ', $nom_sci); if ($rang < 220) { $nomen['nom_supra_generique'] = 'nom_supra_generique="'.$nom_sci.'"'; } elseif ($rang == 220) { $nomen['genre'] = 'genre="'.trim($nom_sci).'"'; } elseif ($rang < 290) { $nomen['genre'] = 'genre="'.$parties_noms[0].'"'; $nomen['epithete_infra_generique'] = 'epithete_infra_generique="'.$parties_noms[1].'"'; } else { $nomen = array_merge($nomen, $this->decouperEspece($parties_noms)); $hybride = $this->etreHybride($parties_noms); if (isset($parties_noms[2]) && ($hybride === false || $hybride > 2)) { $nomen = array_merge($nomen, $this->decouperSousEspece($parties_noms)); } } $update = "UPDATE {$this->referentiel}_taxref SET ".implode(' , ', $nomen)." WHERE num_nom = ".$num_nom; $resultat = $this->executerRequeter($update); } return $nomen; } private function decouperSousEspece($parties_noms) { if ($this->etreTypeSousEpithete($parties_noms[2]) == true) { $nomen['type_epithete'] = 'type_epithete="'.$parties_noms[2].'"'; $nomen['epithete_infra_sp'] = 'epithete_infra_sp="'.$parties_noms[3].'"'; } elseif (strpos($parties_noms[2], '(') === 0) { $nomen['cultivar_groupe'] = 'cultivar_groupe="'.trim($parties_noms[2], "(").'"'; } elseif (strpos($parties_noms[2], "'") === 0) { $nomen['cultivar'] = 'cultivar="'.trim($parties_noms[2], "'").'"'; } elseif (ctype_upper($parties_noms[2]) === true) { $nomen['nom_commercial'] = 'nom_commercial="'.$parties_noms[2].'"'; } else { $nomen['epithete_infra_sp'] = 'epithete_infra_sp="'.$parties_noms[2].'"'; } return $nomen; } private function etreTypeSousEpithete($chaine) { $type = false; $types_epithete = array('subsp.', 'infra-sp.', 'var.', 'subvar.', 'f.', 'subf.', 'f. sp.', 'race', 'proles'); if (in_array(utf8_encode($chaine), $types_epithete)) { $type = true; } return $type; } private function decouperEspece($parties_noms) { $nomen['genre'] = 'genre="'.$parties_noms[0].'"'; $nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[1].'"'; $hybride = $this->etreHybride($parties_noms); $chimere = array_search('+', $parties_noms); if ($hybride != false || $hybride===0) { $nomen = $this->decouperEspeceHybride($hybride, $parties_noms); } return $nomen; } private function etreHybride($parties_noms) { $hybride = array_search('x', $parties_noms); return $hybride; } private function decouperEspeceHybride($hybride, $parties_noms) { if ($hybride == 0) { $nomen['genre'] = 'genre="'.$parties_noms[0].' '.$parties_noms[1].'"'; $nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[2].'"'; } elseif ($hybride == 1 && count($parties_noms) == 4) { $nomen['genre'] = 'genre="'.$parties_noms[0].' '.$parties_noms[1].' '.$parties_noms[2].'"'; $nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[3].'"'; } elseif ($hybride == 1 && count($parties_noms) == 3) { $nomen['genre'] = 'genre="'.$parties_noms[0].'"'; $nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[1].' '.$parties_noms[2].'"'; } elseif ($hybride == 2) { $nomen['genre'] = 'genre="'.$parties_noms[0].'"'; $nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[1].' '.$parties_noms[2].' '.$parties_noms[3].'"'; } return $nomen; } // +-------------------------------------------------------------------------------------------------------------------+ private function ecrireFichierCsv(&$contenu, $fichier) { $retour = true; $fichier = fopen($fichier, "w"); fputcsv($fichier, $this->noms_colonnes, chr('9')); foreach ($contenu as $ligne) { if (fputcsv($fichier, $ligne, chr('9')) == false) { $e = "Une erreur est survenu lors de l'écriture du fichier : $fichier"; Debug::printr($e); $retour = false; } } $contenu = null; return $retour; } private function connecterPDO() { Config::charger('./configurations/bdd.ini'); try { $dsn = Config::get('bdd_type').':dbname='.Config::get('bdd_nom').';host='. Config::get('bdd_hote'); //$dsn = "mysql:dbname=referentiels;host=localhost"; $this->bdd = new PDO($dsn, Config::get('bdd_utilisateur'), Config::get('bdd_mot_de_passe')); } catch (PDOException $e) { print_r($e); echo 'La connexion à la base de donnée via PDO a échouée : ' . $e->getMessage(); } // Passe en UTF-8 la connexion à la BDD $this->bdd->exec("SET NAMES 'utf8'"); // Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché) $this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } protected function executerRequeter($requete) { $infos = null; try { $infos = $this->bdd->query($requete); if ($infos === false) { echo $requete; } } catch (PDOException $e) { echo sprintf($e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), $requete); } return $infos; } } ?>