Subversion Repositories Applications.referentiel

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
267 delphine 1
<?php
2
// Encodage : UTF-8
3
// +-------------------------------------------------------------------------------------------------------------------+
4
/**
5
* Importation d'un fichier ref-tax dans une bdnt
6
*
7
* Description : classe permettant de versionner les référentiels selon le manuel technique
8
* Utilisation : php script.php comparaison -r bdnff -a tout -f fichier.txt
9
*
10
//Auteur original :
11
* @author       Jean-Pascal MILCENT <jpm@tela-botanica.org>
12
* @copyright	Tela-Botanica 1999-2010
13
* @link			http://www.tela-botanica.org/wikini/RTaxMethodo/wakka.php?wiki=MaNuel
14
* @licence		GPL v3 & CeCILL v2
15
* @version		$Id$
16
*/
17
// +-------------------------------------------------------------------------------------------------------------------+
18
class Importation extends ScriptCommande {
19
 
20
	const SCRIPT_NOM = 'importation';
21
	const MANUEL_VERSION = '4.3';
22
 
23
	private $referentiel = null;
24
	/*public $parametres = array(
25
		'-r' => array(true, true, 'referentiel de base'),
26
		'-f' => array(true, true, 'fichier à comparer'));*/
27
	private $noms_supprimes = null;
28
	private $noms_colonnes = array();
29
	private $rangs_bdnt_taxref = null;
30
	private $statuts_bdnt_taxref = null;
31
	private $correspondance_colonnes = array("CD_NOM" => "", "CD_SUP" => "", "CD_REF" => "",
32
		"RANG" => "rang", "LB_NOM" => "nom_sci", "LB_AUTEUR" => array("auteur","annee"),
33
		"FR" => "presence",
34
		"FR-FRA" => "presence_Ga", "FR-COR" => "presence_Co", "REU" => "presence",
35
		"GUA" => "presence_Guadeloupe", "SMSB" => array("presence_Saint_Martin", "presence_Saint_Barthelemy"),
273 delphine 36
		"SM" => "presence_Saint_Martin", "SB" => "presence_Saint_Barthelemy",  "MAR" => "presence_Martinique",
267 delphine 37
		"GF" => "presence", "MAY" => "presence_Mayotte", "TAAF" => "presence_Taaf",
38
		"SPM" => "presence_Guadeloupe", "PF" => "presence_Polynesie", "NC" => "presence_Nouvelle_Caledonie",
273 delphine 39
		"BIBLIO" => "biblio_origine", "BDNGM" => "num_nom", "NUM_NOM" => "num_nom", "NOM_VERN" => "nom_francais");
267 delphine 40
 
41
	private $sans_correspondance = array(
42
			"FG_VALIDITE", "habitat", "WF", "CLI", "EPA",
43
			"EU", "WLD", "ORACLE",
44
			"DATE_CREA", "ORIGINE_CREA",
45
			"NOM_COMPLET", "NOM_COMPLET_HTML",
46
			"GENRE", "ESPECE", "SOUS_ESPECE", "ANNEE");
47
 
48
	/*public function executer() {
49
		$this->referentiel = $this->getParam('r');
50
		// Lancement du test demandé
51
		$fichier = $this->getParam('f');
52
		if (file_exists($fichier)) {
53
			$manuel_chemin = Config::get('chemin_appli').DS.'..'.DS.'configurations'.DS;
54
			$manuel_config_nom = 'referentiel_v'.self::MANUEL_VERSION.'.ini';
55
			$this->manuel = parse_ini_file($manuel_chemin.$manuel_config_nom);
56
			$this->creerCorrespondanceRangBdntTaxref();
57
			$donnees = $this->traiterFichierTaxref($fichier);
58
			Debug::printr("Fin du traitement du fichier.");
59
			$this->connecterPDO();
60
			$this->creerTableTaxref();
61
			$this->ajouterColonneCDNOM();
62
			Debug::printr("Fin de la création de la table.");
63
			$this->ajouterDonneesTaxRef($donnees);
64
			Debug::printr("Fin de l'insertion des données.");
65
			$this->creerTableComparaison();
66
			Debug::printr("Fin de la création de la table comparaison.");
67
		}
68
	}*/
69
 
70
	public function executer() {
71
		// Récupération du dernier traitement demandé
72
		$this->traitementDao = new TraitementDao();
73
		$this->traitement = $this->traitementDao->getDernierTraitement('tout', self::SCRIPT_NOM);
74
		if (isset($this->traitement)) {
75
			$this->referentiel = $this->traitement['referentiel_code']; // Récupération du nom de projet
76
			$fichier = $this->traitement['script_parametres'];
77
			if (file_exists($fichier)) {
78
				Debug::printr('Debute:'.$this->traitementDao->debuterTraitement($this->traitement['id_traitement']));
79
				// Nettoyage des traitements obsolètes
80
				$traitements_obsoletes = $this->traitementDao->getTraitementsObsoletes($this->referentiel, self::SCRIPT_NOM);
81
				if (isset($traitements_obsoletes)) {
82
					Debug::printr('Supp. obsoletes:'.$this->traitementDao->supprimer($traitements_obsoletes));
83
				}
269 delphine 84
				Debug::printr("Début du traitement du fichier.");
267 delphine 85
				$manuel_chemin = Config::get('chemin_appli').DS.'..'.DS.'configurations'.DS;
86
				$manuel_config_nom = 'referentiel_v'.self::MANUEL_VERSION.'.ini';
87
				$this->manuel = parse_ini_file($manuel_chemin.$manuel_config_nom);
88
				$this->creerCorrespondanceRangBdntTaxref();
89
				$donnees = $this->traiterFichierTaxref($fichier);
90
				Debug::printr("Fin du traitement du fichier.");
91
				$this->connecterPDO();
92
				$this->creerTableTaxref();
93
				$this->ajouterColonneCDNOM();
94
				Debug::printr("Fin de la création de la table.");
95
				$this->ajouterDonneesTaxRef($donnees);
96
				Debug::printr("Fin de l'insertion des données.");
273 delphine 97
				$this->decouperNomSciTaxRef();
267 delphine 98
				$this->creerTableComparaison();
99
				Debug::printr("Fin de la création de la table comparaison.");
100
				Debug::printr('Termine:'.$this->traitementDao->terminerTraitement($this->traitement['id_traitement']));
101
			} else {
102
				Debug::printr("Fichier introuvable".$fichier);
103
				Debug::printr('Termine:'.$this->traitementDao->terminerTraitement($this->traitement['id_traitement']));
104
			}
269 delphine 105
		} else {
106
			Debug::printr("Pas de traitement");
267 delphine 107
		}
108
	}
109
 
273 delphine 110
 
111
// +-------------------------------------------------------------------------------------------------------------------+
267 delphine 112
	private function creerTableTaxref() {
113
		$requete = "DROP TABLE IF EXISTS {$this->referentiel}_taxref; ".
114
			"CREATE TABLE  {$this->referentiel}_taxref AS SELECT * FROM {$this->referentiel};".
115
			"ALTER TABLE  {$this->referentiel}_taxref ADD PRIMARY KEY (num_nom);";
116
		$resultat = $this->executerRequeter($requete);
117
	}
273 delphine 118
 
267 delphine 119
	private function ajouterColonneCDNOM() {
120
		$requete = "ALTER TABLE  {$this->referentiel}_taxref ADD ".
273 delphine 121
			"`CD_NOM` INT( 15 ) NULL DEFAULT NULL COMMENT 'numéro correspondant dans la base taxref.';";
267 delphine 122
		$resultat = $this->executerRequeter($requete);
123
	}
273 delphine 124
 
267 delphine 125
	private function ajouterDonneesTaxRef($liste_noms) {
126
		$i = 0; $j = 0; $requete = "";
127
		foreach ($liste_noms as $nom) { $i++;
128
			$requete .= "UPDATE  {$this->referentiel}_taxref SET ".implode(' , ', $nom).
129
					" WHERE {$nom['num_nom']} ;";//echo $requete;
130
			if ($i == 1000 || ($j*1000+$i) == count($liste_noms) ) { $j++;
131
				$resultat = $this->executerRequeter($requete.'commit;');
132
				if ($resultat == null) {
133
					$resultat = $this->executerRequeter($requete.'commit;');
134
				}
135
				$i = 0; $requete = "";
136
			}
137
		}
138
	}
273 delphine 139
 
267 delphine 140
	private function creerTableComparaison() {
141
		foreach ($this->noms_colonnes as $colonne) {
142
			if (isset($this->correspondance_colonnes[$colonne]) && $this->correspondance_colonnes[$colonne] != "") {
143
				$nom_champ = $this->correspondance_colonnes[$colonne];
144
				if (is_array($nom_champ)) {
145
					foreach ($nom_champ as $nom) {
146
						$champs_tax[] = "t.{$nom} AS tax_{$nom}";
147
						$champs_tax[] = "b.{$nom} AS {$nom}";
148
						$concat[] = "IF(t.{$nom} != b.{$nom}, '{$nom}, ', '')";
149
					}
150
				} else {
151
					$champs_tax[] = "t.{$nom_champ} AS tax_{$nom_champ}";
152
					$champs_tax[] = "b.{$nom_champ} AS {$nom_champ}";
153
					$concat[] = "IF(t.{$nom_champ} != b.{$nom_champ}, '{$nom_champ}, ', '')";
154
				}
155
			}
156
		}
273 delphine 157
		date_default_timezone_set('Europe/London');
267 delphine 158
		$requete = "CREATE TABLE  {$this->referentiel}_comparaison_".date("Y_m_d_H_i_s")." AS".
159
					" SELECT CONCAT(".implode(', ', $concat).") AS difference, ".implode(', ', $champs_tax).
160
					" FROM {$this->referentiel} b, {$this->referentiel}_taxref t".
161
					" WHERE b.num_nom = t.num_nom AND (b.nom_sci != t.nom_sci or b.auteur != t.auteur or b.annee != t.annee);";
273 delphine 162
		//echo $requete;
267 delphine 163
		$resultat = $this->executerRequeter($requete);
164
	}
165
 
273 delphine 166
// +-------------------------------------------------------------------------------------------------------------------+
267 delphine 167
	private function traiterFichierTaxref($fichier) {
168
		$donnees = array();
169
		if (($pointeur = fopen($fichier, "r")) !== FALSE) {
170
			$this->noms_colonnes = fgetcsv($pointeur, 1000, chr(9));
337 delphine 171
			$num_nom = 0;//print_r($this->noms_colonnes);
267 delphine 172
			while (($ligne = fgetcsv($pointeur, 1000, chr(9))) !== FALSE) {
173
				$nombreChamps = count($ligne);
337 delphine 174
				$taxref[$ligne[0]] = $ligne;//print_r($ligne);
267 delphine 175
				for ($c=0; $c < $nombreChamps; $c++) {
176
					if (isset($this->correspondance_colonnes[$this->noms_colonnes[$c]])) {
177
						if (is_array($this->correspondance_colonnes[$this->noms_colonnes[$c]])) {
273 delphine 178
							if ($this->noms_colonnes[$c] == 'LB_AUTEUR') {
179
								if (preg_match('/(.*), +([0-9]{4})/', utf8_encode($ligne[$c]), $matches) == 1) {
180
									$nom['auteur'] = 'auteur="'.$matches[1].'"';
181
									$nom['annee'] = 'annee="'.trim($matches[2]).'"';
267 delphine 182
								} else {
273 delphine 183
									$nom['auteur'] = 'auteur="'.utf8_encode($ligne[$c]).'"';
267 delphine 184
									$nom['annee'] = 'annee=""';
185
								}
186
							} else {
187
								foreach ($this->correspondance_colonnes[$this->noms_colonnes[$c]] as $a=>$nom_colonne) {
188
									$nom[$nom_colonne] = $nom_colonne.'="'.$ligne[$c].'"';
189
								}
190
							}
191
						} elseif ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "") {
192
							$nom[$this->noms_colonnes[$c]] = $ligne[$c];
193
						} else {
194
							if ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "rang") {
273 delphine 195
								$rang = $this->rangs_bdnt_taxref[$ligne[$c]];
196
								// à remettre si on décide de prendre les rangs taxref
197
								//$nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] =
198
									//$this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.$this->rangs_bdnt_taxref[$ligne[$c]].'"';
267 delphine 199
							} elseif ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "num_nom") {
200
								$num_nom = $ligne[$c];
201
								$nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] =
202
									$this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.$ligne[$c].'"';
273 delphine 203
							} elseif ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "nom_sci") {
204
								$nom_sci = $ligne[$c];
205
								$nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] =
206
									$this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.trim($ligne[$c]).'"';
267 delphine 207
							} else  {
208
								$nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] =
337 delphine 209
									$this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.trim(utf8_encode($ligne[$c])).'"';
267 delphine 210
							}
211
						}
212
					}
213
				}
214
				$nom['exclure_taxref'] = 'exclure_taxref="0"';
215
				$donnees[$num_nom] = $nom;
216
				$correspondance_taxref_bdnt[$nom['CD_NOM']] = $num_nom;
217
			}
218
			fclose($pointeur);
219
			$donnees = $this->changerNumerotation($donnees, $correspondance_taxref_bdnt, $taxref);
220
		}
221
		return $donnees;
222
	}
223
 
224
	private function changerNumerotation($donnees, $correspondance, $taxref) {
225
		$i=0;$j=0;$k=0;
226
		foreach ($donnees as $num_nom=>$infos) {
227
			if (isset($correspondance[$infos['CD_SUP']])) {
228
				$donnees[$num_nom]['num_tax_sup'] = "num_tax_sup=".$correspondance[$infos['CD_SUP']];
229
				$i++;
230
			} elseif ($infos['CD_SUP'] != '') {
231
				$donnees[$num_nom]['num_tax_sup'] = "num_tax_sup=''";
273 delphine 232
				//$sup[$infos['CD_NOM']] = $taxref[$infos['CD_NOM']];
233
				$sup[$infos['CD_SUP']] = $infos['CD_SUP'];
267 delphine 234
			}
235
			unset($donnees[$num_nom]['CD_SUP']);
236
			if (isset($correspondance[$infos['CD_REF']])) {
237
				$donnees[$num_nom]['num_nom_retenu'] = "num_nom_retenu=".$correspondance[$infos['CD_REF']];
238
				$j++;
239
			} elseif ($infos['CD_REF'] != '') {$k++;
240
				$donnees[$num_nom]['num_nom_retenu'] = "num_nom_retenu=''";
273 delphine 241
				//$ref[$infos['CD_NOM']] = $taxref[$infos['CD_NOM']];
242
				$ref[$infos['CD_REF']] = $infos['CD_REF'];
267 delphine 243
			} else {
244
				Debug::printr($infos['CD_NOM']."n'a pas de valeur pour CD_REF");
245
			}
246
			unset($donnees[$num_nom]['CD_REF']);
273 delphine 247
			$donnees[$num_nom]['CD_NOM'] = 'CD_NOM='.$donnees[$num_nom]['CD_NOM'];
337 delphine 248
		}echo "les ".count($sup)." taxons supérieurs manquants :".implode(" ,", $sup)." \nles "."retenus ".implode(" ,", $ref);
269 delphine 249
		//$this->ecrireFichierCsv($ref, './retenu_absent.csv');
273 delphine 250
		//$this->ajouterTaxonAbsent($abs);
269 delphine 251
		//$this->ecrireFichierCsv($sup, './superieur_absent.csv');
267 delphine 252
		echo "$j correspondance pour nom retenu $i correspondance pour nom sup $k non pas de correspondance retenu";
253
		return $donnees;
254
	}
255
 
273 delphine 256
	// rechercher dans reftax les numéros absent dans la base
257
	// modifier les tableaux ref et sup pour modifier $donnees (ajout + modif)
258
	private function ajouterTaxonAbsent($abs) {
259
		$requete = "SELECT ".implode(",", $this->noms_colonnes)." FROM taxref_v5 where CD_NOM IN (".implode(",", $abs).")";
260
		echo $requete;
261
	}
262
 
263
	private function creerCorrespondanceRangBdntTaxref() {
264
		$rangs = explode(',', $this->manuel['rangs_bdnt_taxref']);
265
		foreach ($rangs as $rang) {
266
			list($id_bdnt, $code_taxref) = explode(':', trim($rang));
267
			$this->rangs_bdnt_taxref[$code_taxref] = $id_bdnt;
268
		}
269
	}
270
 
271
// +-------------------------------------------------------------------------------------------------------------------+
272
	private function decouperNomSciTaxRef() {
273
		$requete = "SELECT num_nom, nom_sci, rang, type_epithete FROM {$this->referentiel}_taxref WHERE CD_NOM != ''";
274
		$resultats = $this->executerRequeter($requete);
275
		foreach ($resultats as $nom) {
276
			extract($nom);
277
			$nomen =array('nom_supra_generique' => 'nom_supra_generique=""', 'genre' => 'genre=""',
278
				'epithete_infra_generique' => 'epithete_infra_generique=""', 'epithete_sp' => 'epithete_sp=""',
279
				'type_epithete' => 'type_epithete=""', 'epithete_infra_sp' => 'epithete_infra_sp=""',
280
				'cultivar_groupe' => 'cultivar_groupe=""', 'cultivar' => 'cultivar=""', 'nom_commercial' => 'nom_commercial=""');
281
			$parties_noms = explode(' ', $nom_sci);
282
			if ($rang < 220) {
283
				$nomen['nom_supra_generique'] = 'nom_supra_generique="'.$nom_sci.'"';
284
			} elseif ($rang == 220) {
285
				$nomen['genre'] = 'genre="'.trim($nom_sci).'"';
286
			} elseif ($rang < 290) {
287
				$nomen['genre'] = 'genre="'.$parties_noms[0].'"';
288
				$nomen['epithete_infra_generique'] = 'epithete_infra_generique="'.$parties_noms[1].'"';
289
			} else {
290
				$nomen = array_merge($nomen, $this->decouperEspece($parties_noms));
291
				$hybride = $this->etreHybride($parties_noms);
292
				if (isset($parties_noms[2]) && ($hybride === false || $hybride > 2)) {
293
					$nomen = array_merge($nomen, $this->decouperSousEspece($parties_noms));
294
				}
295
			}
296
			$update = "UPDATE {$this->referentiel}_taxref SET ".implode(' , ', $nomen)." WHERE num_nom = ".$num_nom;
297
			$resultat = $this->executerRequeter($update);
298
		}
299
		return $nomen;
300
	}
301
 
302
	private function decouperSousEspece($parties_noms) {
303
		if ($this->etreTypeSousEpithete($parties_noms[2]) == true) {
304
			$nomen['type_epithete'] = 'type_epithete="'.$parties_noms[2].'"';
305
			$nomen['epithete_infra_sp'] = 'epithete_infra_sp="'.$parties_noms[3].'"';
306
		} elseif (strpos($parties_noms[2], '(') === 0) {
307
			$nomen['cultivar_groupe'] = 'cultivar_groupe="'.trim($parties_noms[2], "(").'"';
308
		} elseif (strpos($parties_noms[2], "'") === 0) {
309
			$nomen['cultivar'] = 'cultivar="'.trim($parties_noms[2], "'").'"';
310
		} elseif (ctype_upper($parties_noms[2]) === true) {
311
			$nomen['nom_commercial'] = 'nom_commercial="'.$parties_noms[2].'"';
312
		} else {
313
			$nomen['epithete_infra_sp'] = 'epithete_infra_sp="'.$parties_noms[2].'"';
314
		}
315
		return $nomen;
316
	}
317
 
318
	private function etreTypeSousEpithete($chaine) {
319
		$type = false;
320
		$types_epithete = array('subsp.', 'infra-sp.', 'var.', 'subvar.', 'f.', 'subf.', 'f. sp.', 'race', 'proles');
321
		if (in_array(utf8_encode($chaine), $types_epithete)) {
322
			$type = true;
323
		}
324
		return $type;
325
	}
326
 
327
	private function decouperEspece($parties_noms) {
328
		$nomen['genre'] = 'genre="'.$parties_noms[0].'"';
329
		$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[1].'"';
330
		$hybride = $this->etreHybride($parties_noms);
331
		$chimere = array_search('+', $parties_noms);
332
		if ($hybride != false || $hybride===0) {
333
			$nomen = $this->decouperEspeceHybride($hybride, $parties_noms);
334
		}
335
		return $nomen;
336
	}
337
 
338
	private function etreHybride($parties_noms) {
339
		$hybride = array_search('x', $parties_noms);
340
		return $hybride;
341
	}
342
 
343
	private function decouperEspeceHybride($hybride, $parties_noms) {
344
		if ($hybride == 0) {
345
			$nomen['genre'] = 'genre="'.$parties_noms[0].' '.$parties_noms[1].'"';
346
			$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[2].'"';
347
		} elseif ($hybride == 1 && count($parties_noms) == 4) {
348
			$nomen['genre'] = 'genre="'.$parties_noms[0].' '.$parties_noms[1].' '.$parties_noms[2].'"';
349
			$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[3].'"';
350
		} elseif ($hybride == 1 && count($parties_noms) == 3) {
351
			$nomen['genre'] = 'genre="'.$parties_noms[0].'"';
352
			$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[1].' '.$parties_noms[2].'"';
353
		} elseif ($hybride == 2) {
354
			$nomen['genre'] = 'genre="'.$parties_noms[0].'"';
355
			$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[1].' '.$parties_noms[2].' '.$parties_noms[3].'"';
356
		}
357
		return $nomen;
358
	}
359
 
360
// +-------------------------------------------------------------------------------------------------------------------+
267 delphine 361
	private function ecrireFichierCsv(&$contenu, $fichier) {
362
		$retour = true;
363
		$fichier = fopen($fichier, "w");
364
		fputcsv($fichier, $this->noms_colonnes, chr('9'));
365
		foreach ($contenu as $ligne) {
366
			if (fputcsv($fichier, $ligne, chr('9')) == false) {
367
				$e = "Une erreur est survenu lors de l'écriture du fichier : $fichier";
368
				Debug::printr($e);
369
				$retour = false;
370
			}
371
		}
372
		$contenu = null;
373
		return $retour;
374
	}
375
 
376
 
377
	private function connecterPDO() {
378
		Config::charger('./configurations/bdd.ini');
379
		try {
269 delphine 380
			$dsn = Config::get('bdd_type').':dbname='.Config::get('bdd_nom').';host='.
381
				Config::get('bdd_hote');
273 delphine 382
			//$dsn = "mysql:dbname=referentiels;host=localhost";
269 delphine 383
			$this->bdd = new PDO($dsn, Config::get('bdd_utilisateur'), Config::get('bdd_mot_de_passe'));
267 delphine 384
		} catch (PDOException $e) {
385
			print_r($e);
386
			echo 'La connexion à la base de donnée via PDO a échouée : ' . $e->getMessage();
387
		}
388
		// Passe en UTF-8 la connexion à la BDD
389
		$this->bdd->exec("SET NAMES 'utf8'");
390
		// Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché)
391
		$this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
392
	}
393
 
394
	protected function executerRequeter($requete) {
395
		$infos = null;
396
		try {
397
			$infos = $this->bdd->query($requete);
398
			if ($infos === false) {
399
				echo $requete;
400
			}
401
		} catch (PDOException $e) {
273 delphine 402
			echo sprintf($e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), $requete);
267 delphine 403
		}
404
		return $infos;
405
	}
406
}
407
?>