Subversion Repositories eFlore/Projets.eflore-projets

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1021 mathias 1
<?php
2
//declare(encoding='UTF-8');
3
/**
4
 * Exemple de lancement du script : :
5
 * /opt/lampp/bin/php cli.php bdtao -a chargerTous
6
 *
7
 * Base de données des Trachéophytes (trachéo...quoi ?? C'est le truc avec le stylo Bic ?)
8
 * d'Afrique de l'Ouest (et Centrale mais faut pas le dire)
9
 *
10
 * @category	php 5.2
11
 * @package		eFlore/Scripts
12
 * @author		Mathias CHOUET <mathias@tela-botanica.org>
13
 * @copyright	Copyright (c) 2014, Tela Botanica (accueil@tela-botanica.org)
14
 * @license		http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
15
 * @license		http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
16
 */
17
class Bdtao extends EfloreScript {
18
 
19
	private $table = null;
20
	private $tableMeta = null;
21
	private $pasInsertion = 1000;
22
	private $departInsertion = 0;
23
 
24
	protected $parametres_autorises = array();
25
 
26
	// Entêtes du nouveau fichier Rtax à produire
27
	protected $entetesRtax = array("num_nom","num_nom_retenu","num_tax_sup","rang","nom_sci",
28
		"nom_supra_generique","genre","epithete_infra_generique","epithete_sp",
29
		"type_epithete","epithete_infra_sp","cultivar_groupe","cultivar","nom_commercial",
30
		"auteur","annee","biblio_origine","notes","nom_addendum","homonyme","num_type",
31
		"num_basionyme","synonyme_proparte","synonyme_douteux","synonyme_mal_applique",
32
		"synonyme_orthographique","orthographe_originelle","hybride_parent_01",
33
		"hybride_parent_01_notes","hybride_parent_02","hybride_parent_02_notes",
34
		"nom_francais","presence","statut_origine ","statut_introduction","statut_culture","exclure_taxref");
35
 
36
	public function initialiserProjet($projetNom) {
37
		parent::initialiserProjet($projetNom);
38
		$this->table = Config::get("bdtao");
39
		$this->tableMeta = Config::get("bdtaoMeta");
40
	}
41
 
42
	public function executer() {
43
		try {
44
			$this->initialiserProjet('bdtao');
45
 
46
			// Lancement de l'action demandée
47
			$cmd = $this->getParametre('a');
48
			switch ($cmd) {
49
				case 'tout' :
50
					$ok = $this->productionCsvPourReferentiels();
51
					if ($ok === true) {
52
						$this->integrationEFlore();
53
					}
54
					break;
55
				case 'ref' : // partie 1 : "referentiels"
56
					$this->productionCsvPourReferentiels();
57
					break;
58
				case 'eflore' : // partie 2 : "eFlore"
59
					$this->integrationEFlore();
60
					break;
61
				case 'nettoyage' :
62
					$this->nettoyage();
63
					break;
64
				case 'chargerStructureSql' :
65
					//$this->creerStructure();
66
					$this->chargerStructureSql();
67
					break;
68
				case 'verifierEtGenererCsvRtax' :
69
					$this->verifierEtGenererCsvRtax();
70
					break;
71
				case 'chargerCsvRtax' :
72
					$this->chargerCsvRtax();
73
					break;
74
				case 'changerRangs' :
75
					$this->changerRangs();
76
					break;
77
				case 'completerNumNomRetenu' :
78
					$this->completerNumNomRetenu();
79
					break;
80
				case 'supprimerNumTaxSupPourSynonymes' :
81
					$this->supprimerNumTaxSupPourSynonymes();
82
					break;
83
				case 'subspAutonymes' :
84
					$this->subspAutonymes();
85
					break;
86
				case 'genererNomSupraGenerique' :
87
					$this->genererNomSupraGenerique();
88
					break;
89
				case 'genererEpitheteInfraGenerique' :
90
					$this->genererEpitheteInfraGenerique();
91
					break;
92
				case 'exporterCSVModifie' :
93
					$this->exporterCSVModifie();
94
					break;
95
				case 'genererChpNumTax' :
96
					$this->genererChpNumTax();
97
					break;
98
				case 'genererNomSciHtml' :
99
					$this->genererChpNomSciHtml();
100
					break;
101
				case 'genererChpNomComplet' :
102
					$this->genererChpNomComplet();
103
					break;
104
				case 'genererChpFamille' :
105
					$this->genererChpFamille();
106
					break;
107
				case 'genererChpHierarchie' :
108
					$this->genererChpHierarchie();
109
					break;
110
				default :
111
					throw new Exception("Erreur : la commande '$cmd' n'existe pas!");
112
			}
113
		} catch (Exception $e) {
114
			$this->traiterErreur($e->getMessage());
115
		}
116
	}
117
 
118
	// Lance la première moitié du boulot, et s'arrête lorsque le fichier CSV
119
	// au format Rtax est rempli avec les données amendées - il est prêt à rentrer dans Rtxß.
120
	// Retourne true si tout s'est bien passé, false sinon
121
	protected function productionCsvPourReferentiels() {
122
		$retour = false;
123
		$this->nettoyage();
124
		$this->chargerStructureSql();
125
		$verifOk = $this->verifierEtGenererCsvRtax();
126
		if ($verifOk === true) {
127
			$chgtOk = $this->chargerCsvRtax();
128
			if ($chgtOk) {
129
				$this->changerRangs();
130
				$this->completerNumNomRetenu();
131
				$this->supprimerNumTaxSupPourSynonymes();
132
				$this->subspAutonymes();
133
				$this->genererNomSupraGenerique();
134
				$this->genererEpitheteInfraGenerique();
135
				$this->exporterCSVModifie();
136
				$retour = true;
137
			}
138
		}
139
		return $retour;
140
	}
141
 
142
	// Lance la seconde moitié du boulot, et s'arrête lorsque le référentiel
143
	// est inséré dans la base eFlore.
144
	// Retourne true si tout s'est bien passé, false sinon
145
	protected function integrationEFlore() {
146
		$retour = false;
147
		$this->genererChpNumTax();
148
		$this->genererChpNomSciHtml();
149
		$this->genererChpFamille();
150
		$this->genererChpNomComplet();
151
		$this->genererChpHierarchie();
152
		$retour = true;
153
		return $retour;
154
	}
155
 
156
	// -------------- partie Rtax -------------
157
 
158
	// Dézingue tout le bousin
159
	protected function nettoyage() {
160
		echo "---- suppression des tables\n";
161
		$req = "DROP TABLE IF EXISTS `" . $this->table . "`";
162
		$this->getBdd()->requeter($req);
163
		$req = "DROP TABLE IF EXISTS `" . $this->tableMeta . "`;";
164
		$this->getBdd()->requeter($req);
165
	}
166
 
167
	// Analyse le fichier CSV fourni par le CJBG, le vérifie et écrit un CSV minimal au format Rtax
168
	function verifierEtGenererCsvRtax() {
169
		$cheminCsvRtax = Config::get('chemins.csvRtax');
170
		$cheminCsvCjbg = Config::get('chemins.csvCjbg');
171
		$retour = false;
172
		echo "---- vérification CSV CJBG [$cheminCsvCjbg] et génération CSV Rtax\n";
173
 
174
		// Correspondances de colonnes pour le remplissage à minima du fichier CSV Rtax
175
		// Clefs: CJBG
176
		// Valeurs: Rtax
177
		$entetesCjbgVersRtax = array(
178
		    "id_name" => "num_nom",
179
		    "presence" => "presence",
180
		    "statut_introduction" => "statut_introduction",
181
		    "statut_origine" => "statut_origine",
182
		    "nom_addendum" => "nom_addendum",
183
		    "BASIONYME" => "num_basyonyme",
184
		    "NO_RANG" => "rang",
185
		    "auteur" => "auteur",
186
		    "ANNEE" => "annee",
187
		    "type_epithete" => "type_epithete",
188
		    "SYN_mal_applique" => "synonyme_mal_applique",
189
		    "nom_sci" => "nom_sci",
190
		    "num_tax_sup" => "num_tax_sup",
191
		    "num_nom_retenu" => "num_nom_retenu",
192
		    "genre" => "genre",
193
		    "NOTES" => "notes",
194
		    "epithete_sp" => "epithete_sp",
195
		    "epithete_infra_sp" => "epithete_infra_sp",
196
			// champs additionnels
197
		    "NOM_STANDARD2" => false,
198
		    "STATUT_SYN" => false, // @TODO convertir
199
		    "hybride_parents" => false, // toujours "x" => ??
200
		    "FAM APG3" => false,
201
		    "auth_genre" => false,
202
		    "auth_esp" => false
203
		);
204
 
205
		$analyseOK = true;
206
		$numLigne = 1;
207
		$idNames = array();
208
		// lecture CSV d'origine
209
		$csv = fopen($cheminCsvCjbg, "r");
210
		$donneesTransformees = array();
211
		if ($csv) {
212
			$entetes = fgetcsv($csv);
213
			//echo "Entetes: " . print_r($entetes, true) . "\n";
214
			while(($ligne = fgetcsv($csv)) !== false) {
215
				$numLigne++;
216
				$nouvelleLigne = array();
217
				if (isset($idNames[$ligne[0]])) {
218
					echo "Entrée dupliquée pour id_name [" . $ligne[0] . "]\n";
219
					$analyseOK = false;
220
				} else if (! is_numeric($ligne[0])) {
221
					echo "Ligne $numLigne : la clef [" . $ligne[0] . "] n'est pas un entier\n";
222
					$analyseOK = false;
223
				} else if ($ligne[0] == 0) {
224
					echo "Ligne $numLigne : la clef [" . $ligne[0] . "] vaut zéro\n";
225
					$analyseOK = false;
226
				} else {
227
					$idNames[$ligne[0]] = $ligne[13]; // stockage du nom retenu
228
					foreach ($ligne as $idx => $col) {
229
						$entete = $entetes[$idx];
230
						$ert = $entetesCjbgVersRtax[$entete];
231
						if (strpos($col, "\n") > -1) {
232
							echo "Info: la colonne $ert de la ligne $numLigne contient des retours chariot. Conversion en espaces.\n";
233
							$col = str_replace("\n", " ", $col);
234
						}
235
						$nouvelleLigne[$ert] = $col;
236
					}
237
					$donneesTransformees[] = $nouvelleLigne;
238
				}
239
			}
240
		} else {
241
			echo "Erreur lors de l'ouverture du fichier\n";
242
		}
243
 
244
		// Vérifications:
245
		// - existence des num_nom_retenu et num_tax_sup mentionnés
246
		// - réduction des chaînes de synonymie
247
		$nnrManquants = array();
248
		$ntsManquants = array();
249
		$chaineSyn = array();
250
		foreach ($donneesTransformees as $ligne) {
251
			$taxSup = $ligne['num_tax_sup'];
252
			$nomRet = $ligne['num_nom_retenu'];
253
			$numNom = $ligne['num_nom'];
254
			// Si un nom est retenu, son taxon supérieur doit être mentionné et exister
255
			if (($numNom == $nomRet) && $taxSup && (! isset($idNames[$taxSup])) && (! isset($ntsManquants[$taxSup]))) {
256
				$ntsManquants[$taxSup] = true;
257
			}
258
			// Si un nom retenu est mentionné, il doit exister et être un nom retenu
259
			if ($nomRet) {
260
				if (isset($idNames[$nomRet])) {
261
					/*$nrnr = $idNames[$nomRet];
262
					echo "Test pour nn $numNom, nr $nomRet, " . $nrnr . "\n";
263
					if ($nomRet && $nrnr != $nomRet) {
264
						if (! isset($chaineSyn[$nomRet])) {
265
							$chaineSyn[$nomRet] = true;
266
						}
267
					}*/
268
				} else {
269
					if (! isset($nnrManquants[$nomRet])) {
270
						$nnrManquants[$nomRet] = true;
271
					}
272
				}
273
			}
274
		}
275
		if (count($nnrManquants) > 0) {
276
			echo count($nnrManquants) . " Nom(s) retenu(s) absent(s):\n";
277
			echo "(" . implode(",", array_keys($nnrManquants)) . ")\n";
278
		}
279
		if (count($ntsManquants) > 0) {
280
			echo count($ntsManquants) . " Taxon(s) supérieur(s) absent(s):\n";
281
			echo "(" . implode(",", array_keys($ntsManquants)) . ")\n";
282
		}
283
		/*if (count($chaineSyn) > 0) {
284
			echo count($chaineSyn) . " Synonymes ne sont pas des noms retenus:\n";
285
			//echo "(" . implode(",", array_keys($chaineSyn)) . ")\n";
286
		}*/
287
 
288
		if ($analyseOK === true) {
289
			// Production CSV de destination
290
			$csvDestination = '';
291
			$csvDestination .= implode($this->entetesRtax, ',') . "\n";
292
			$tailleLigne = count($this->entetesRtax);
293
			foreach ($donneesTransformees as $dt) {
294
				//$ligne = array();
295
				$ligneCsv = '';
296
				$i = 0;
297
				foreach ($this->entetesRtax as $e) {
298
					/*if (isset($dt[$e])) {
299
						$ligne[] = $dt[$e];
300
					} else {
301
						$ligne[] = '';
302
					}*/
303
					if (isset($dt[$e]) && ($dt[$e] !== '')) {
304
						$ligneCsv .= '"' . $dt[$e] . '"';
305
					}
306
					if ($i < $tailleLigne) {
307
						$ligneCsv .= ',';
308
					}
309
					$i++;
310
				}
311
				$ligneCsv .= "\n";
312
				//$ligneCsv = '"' . implode($ligne, '","') . '"' . "\n"; // met des double guillemets sur les champs vides et /i
313
				$csvDestination .= $ligneCsv;
314
			}
1022 mathias 315
			// @TODO créer le répertoire dans /tmp et donner les droits 777
1021 mathias 316
			file_put_contents($cheminCsvRtax, $csvDestination);
317
			$retour = true;
318
		} else {
319
			echo "L'analyse a mis en évidence des erreurs. Interruption.\n";
320
		}
321
 
322
		return $retour;
323
	}
324
 
325
	// Charge le CSV minimal au format TexRaf
326
	protected function chargerCsvRtax() {
327
		$cheminCsvRtax = Config::get('chemins.csvRtax');
328
		echo "---- chargement du fichier CSV Rtax [$cheminCsvRtax]\n";
329
		$req = "LOAD DATA INFILE '" . $cheminCsvRtax . "' INTO TABLE " . $this->table
330
			. " FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n' IGNORE 1 LINES";
331
		$retour = $this->getBdd()->requeter($req);
332
		return $retour;
333
	}
334
 
335
	// Convertit les rangs du format chaispasquoi au format RexTaf
336
	protected function changerRangs() {
337
		echo "---- conversion des rangs\n";
338
		$rangs = array(
339
			"0" => "10",
340
			"1" => "20",
341
			"2" => "50",
342
			"3" => "53",
343
			"4" => "80",
344
			"5" => "140",
345
			"6" => "180",
346
			"7" => "190",
347
			"8" => "200",
348
			"9" => "220",
349
			"10" => "230",
350
			"11" => "240",
351
			"12" => "250",
352
			"13" => "260",
353
			"14" => "280",
354
			"15" => "290",
355
			"16" => "320",
356
			"17" => "340",
357
			"18" => "350",
358
			"19" => "360",
359
			"20" => "370",
360
			"26" => "440"
361
		);
362
		foreach ($rangs as $src => $dest) {
363
			echo "rang $src => rang $dest\n";
364
			$req = "UPDATE " . $this->table . " SET rang=$dest WHERE rang=$src;";
365
			$this->getBdd()->requeter($req);
366
		}
367
	}
368
 
369
	// Copie num_nom dans num_nom_retenu lorsque ce dernier est vide
370
	protected function completerNumNomRetenu() {
371
		echo "---- complétion des num_nom_retenu\n";
372
		$req = "UPDATE " . $this->table . " SET num_nom_retenu = num_nom WHERE num_nom_retenu='';";
373
		$this->getBdd()->requeter($req);
374
	}
375
 
376
	// Supprime le num_tax_sup pour les synonymes
377
	// et le met à 1 s'il est égal au num_nom
378
	protected function supprimerNumTaxSupPourSynonymes() {
379
		echo "---- suppression de num_tax_sup pour les synonymes et mise à 1 si égal à num_nom\n";
380
		$req = "UPDATE " . $this->table . " SET num_tax_sup = '' WHERE num_nom != num_nom_retenu;";
381
		$this->getBdd()->requeter($req);
382
		$req = "UPDATE " . $this->table . " SET num_tax_sup = 1 WHERE num_nom = num_tax_sup;";
383
		$this->getBdd()->requeter($req);
384
	}
385
 
386
	// Pour chaque subsp. autonyme, inscrit l'epithete_infra_sp
387
	protected function subspAutonymes() {
388
		echo "---- inscription de l'épithète infraspécifique des subsp. autonymes\n";
389
		$req = "SELECT num_nom, nom_sci, epithete_infra_sp FROM " . $this->table . " WHERE nom_sci LIKE '%subsp.%'";
390
		$res = $this->getBdd()->recupererTous($req);
391
 
392
		$nbres = count($res);
393
		$cpt = 0;
394
		$ok = 0;
395
		$ids = array();
396
		foreach ($res as $subsp) {
397
			$ns = $subsp['nom_sci'];
398
			$pos = strpos($ns, 'subsp.');
399
			$gsp = substr($ns, 0, $pos - 1);
400
			$sp = substr($gsp, strrpos($gsp, ' ') + 1);
401
			$sub = substr($ns, $pos + 8);
402
			if ($sub == $sp) {
403
				$cpt++;
404
				// @TODO
405
				// 1) récupérer l'auteur
406
				// 2) intégrer l'auteur avant "subsp." dans le nom_sci
407
				//echo "[$sp] || [$sub] || [" . $subsp['epithete_infra_sp'] . "]\n";
408
				if ($sub == $subsp['epithete_infra_sp']) {
409
					$ok++;
410
				} else {
411
					$reqMod = "UPDATE " . $this->table . " SET epithete_infra_sp='"
412
						. $sub . "' WHERE num_nom=" . $subsp['num_nom'];
413
					$this->getBdd()->requeter($reqMod);
414
				}
415
			}
416
		}
417
		echo "subsp.: $nbres\n";
418
		echo "Autonymes: $cpt dont $ok déjà inscrites\n";
419
	}
420
 
421
	// Copie le nom scientifique dans le nom supra générique pour les taxons de rang
422
	// supérieur au genre
423
	protected function genererNomSupraGenerique() {
424
		echo "---- complétion des noms supragénériques\n";
425
		$req = "UPDATE " . $this->table . " SET nom_supra_generique = nom_sci WHERE rang < 220";
426
		$res = $this->getBdd()->requeter($req);
427
	}
428
 
429
	// Copie le nom scientifique dans l'épithète infra générique pour les taxons de rang
430
	// entre genre et espèce
431
	protected function genererEpitheteInfraGenerique() {
432
		echo "---- complétion des épithètes infragénériques\n";
433
		$req = "UPDATE " . $this->table . " SET epithete_infra_generique = nom_sci WHERE rang > 220 AND rang < 290";
434
		$res = $this->getBdd()->requeter($req);
435
	}
436
 
437
	protected function exporterCSVModifie() {
438
		$cheminFichierCsvRtaxModifie = Config::get('chemins.csvRtaxModifie');
439
		echo "---- export du CSV Rtax modifié [$cheminFichierCsvRtaxModifie]\n";
440
		if (file_exists($cheminFichierCsvRtaxModifie)) {
441
			unlink($cheminFichierCsvRtaxModifie);
442
		}
443
		$req = "SELECT '" . implode("','", $this->entetesRtax) . "'"
444
			. " UNION ALL "
445
			. " SELECT * FROM " . $this->table . " INTO OUTFILE '" . $cheminFichierCsvRtaxModifie . "'"
446
			. " FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n'";
447
		$res = $this->getBdd()->requeter($req);
448
		// Remplacement des cases vides par '' aulieu de '""' (peut faire foirer l'import par la suite)
449
		exec("sed -i 's/\"\"//g' " . $cheminFichierCsvRtaxModifie);
450
	}
451
 
452
	// -------------- partie eFlore ------------- copiée depuis le script Bdtfx
453
 
454
	private function genererChpNomSciHtml() {
455
		echo "---- génération des noms scientifiques en HTML \n";
456
		$this->preparerTablePrChpNomSciHtml();
457
		$generateur = new GenerateurNomSciHtml();
458
		$nbreTotal = $this->recupererNbTotalTuples();
459
		$erreurs = array();
460
		$this->departInsertion = 0;
461
		while ($this->departInsertion < $nbreTotal) {
462
			$resultat = $this->recupererTuplesPrChpNomSciHtml();
463
 
464
			try {
465
				$nomsSciEnHtml = $generateur->generer($resultat);
466
			} catch (Exception $e) {
467
				$erreurs[] = $e->getMessage();
468
			}
469
 
470
			$this->remplirChpNomSciHtm($nomsSciEnHtml);
471
			$this->departInsertion += $this->pasInsertion;
472
			$this->afficherAvancement("Insertion des noms scientifique au format HTML dans la base par paquet de {$this->pasInsertion} en cours");
473
		}
474
		echo "\n";
475
 
476
		if (count($erreurs) > 0) {
477
			echo 'Erreurs lors de la génération HTML des noms scientifiques:\n' . print_r($erreurs, true) . "\n";
478
		}
479
	}
480
 
481
	private function preparerTablePrChpNomSciHtml() {
482
		echo "---- ajout de la colonne nom_sci_html \n";
483
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'nom_sci_html' ";
484
		$resultat = $this->getBdd()->recuperer($requete);
485
		if ($resultat === false) {
486
			$requete = 	"ALTER TABLE {$this->table} ".
487
				'ADD nom_sci_html VARCHAR( 500 ) '.
488
				'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ';
489
			$this->getBdd()->requeter($requete);
490
		}
491
	}
492
 
493
	private function recupererNbTotalTuples(){
494
		$requete = "SELECT count(*) AS nb FROM {$this->table} ";
495
		$resultat = $this->getBdd()->recuperer($requete);
496
		return $resultat['nb'];
497
	}
498
 
499
	private function recupererTuplesPrChpNomSciHtml() {
500
		$requete = 'SELECT 	num_nom, rang, nom_sci, nom_supra_generique, genre, epithete_infra_generique, '.
501
			'	epithete_sp, type_epithete, epithete_infra_sp,cultivar_groupe, '.
502
			'	nom_commercial, cultivar '.
503
			"FROM {$this->table} ".
504
			"LIMIT {$this->departInsertion},{$this->pasInsertion} ";
505
		$resultat = $this->getBdd()->recupererTous($requete);
506
		return $resultat;
507
	}
508
 
509
	private function remplirChpNomSciHtm($nomsSciHtm) {
510
		foreach ($nomsSciHtm as $id => $html) {
511
			$html = $this->getBdd()->proteger($html);
512
			$requete = "UPDATE {$this->table} SET nom_sci_html = $html WHERE num_nom = $id ";
513
			$resultat = $this->getBdd()->requeter($requete);
514
			if ($resultat === false) {
515
				throw new Exception("Erreur d'insertion pour le tuple $id");
516
			}
517
		}
518
	}
519
 
520
	// Attention c'est over-lent !
521
	private function genererChpNumTax() {
522
		$this->preparerTablePrChpNumTax();
523
		$erreurs = array();
524
		$this->departInsertion = 0;
525
		$dernier_num_tax = 0;
526
 
527
		$requete = 'SELECT num_nom '.
528
					'FROM '.$this->table.' '.
529
					'WHERE num_nom = num_nom_retenu AND num_nom_retenu != 0 '.
530
					'ORDER by num_nom_retenu ASC ';
531
 
532
		$resultat = $this->getBdd()->recupererTous($requete);
533
		foreach ($resultat as $taxon) {
534
			$dernier_num_tax++;
535
			$requete_maj = 'UPDATE '.$this->table.' '.
536
							'SET num_taxonomique = '.$dernier_num_tax.' '.
537
							'WHERE num_nom_retenu = '.$taxon['num_nom'];
538
			$this->getBdd()->requeter($requete_maj);
539
			$this->pasInsertion++;
540
			$this->afficherAvancement("Insertion des num tax, ".count($resultat)." num tax a traiter");
541
		}
542
		echo "\n";
543
		if (count($erreurs) > 0) {
544
			echo 'Erreurs lors de la génération des numéros taxonomiques' . print_r($erreurs, true) . "\n";
545
		}
546
	}
547
 
548
	private function preparerTablePrChpNumTax() {
549
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'num_taxonomique' ";
550
		$resultat = $this->getBdd()->recuperer($requete);
551
		if ($resultat === false) {
552
			$requete = 	"ALTER TABLE {$this->table} ".
553
						'ADD num_taxonomique INT( 9 ) ';
554
			$this->getBdd()->requeter($requete);
555
		}
556
	}
557
 
558
	private function genererChpNomComplet() {
559
		$this->preparerTablePrChpNomComplet();
560
		$this->remplirChpNomComplet();
561
	}
562
 
563
	private function preparerTablePrChpNomComplet() {
564
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'nom_complet' ";
565
		$resultat = $this->getBdd()->recuperer($requete);
566
		if ($resultat === false) {
567
			$requete = 	"ALTER TABLE {$this->table} ".
568
					'ADD nom_complet VARCHAR( 500 ) '.
569
					'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ';
570
			$this->getBdd()->requeter($requete);
571
		}
572
	}
573
 
574
	private function remplirChpNomComplet() {
575
		echo "---- Attribution du champ nom complet au taxons :\n";
576
		$requete = "UPDATE {$this->table} SET nom_complet = CONCAT(nom_sci,' ',auteur)";
577
		$resultat = $this->getBdd()->requeter($requete);
578
		if ($resultat === false) {
579
			echo "Erreur de génération du champ nom complet\n";
580
		} else {
581
			echo "OK\n";
582
		}
583
	}
584
 
585
	private function genererChpFamille() {
586
		$this->preparerTablePrChpFamille();
587
		$resultats = $this->recupererTuplesPrChpFamille();
588
		$noms = array();
589
		$introuvables = array();
590
		$introuvablesSyno = array();
591
		foreach ($resultats as $id => $nom) {
592
			$nn = $nom['num_nom'];
593
			$nnr = $nom['num_nom_retenu'];
594
			$nts = $nom['num_tax_sup'];
595
			$rg = $nom['rang'];
596
			if ($nnr != '') {
597
				if ($rg == '180') {
598
					$noms[$nn] = $nom['nom_sci'];
599
				} else {
600
					if ($nn == $nnr) {// nom retenu
601
						if (isset($noms[$nts])) {
602
							$noms[$nn] = $noms[$nts];
603
						} else {
604
							$introuvables[] = $nn;
605
						}
606
					} else {// nom synonyme
607
						if (isset($noms[$nnr])) {
608
							$noms[$nn] = $noms[$nnr];
609
						} else {
610
							$introuvablesSyno[] = $nom;
611
						}
612
					}
613
				}
614
			}
615
			unset($resultats[$id]);
616
			$this->afficherAvancement("Attribution de leur famille aux noms en cours");
617
		}
618
		echo "\n";
619
 
620
		foreach ($introuvablesSyno as $id => $nom) {
621
			$nn = $nom['num_nom'];
622
			$nnr = $nom['num_nom_retenu'];
623
			if (isset($noms[$nnr])) {
624
				$noms[$nn] = $noms[$nnr];
625
			} else {
626
				$introuvables[] = $nn;
627
			}
628
			unset($introuvablesSyno[$id]);
629
			$this->afficherAvancement("Attribution de leur famille aux synonymes en cours");
630
		}
631
		echo "\n";
632
 
633
		if (count($introuvables) > 0) {
634
			echo count($introuvables) . ' familles sont introuvables : ' . implode(',', $introuvables) . "\n";
635
		}
636
		$this->remplirChpFamille($noms);
637
	}
638
 
639
	private function preparerTablePrChpFamille() {
640
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'famille' ";
641
		$resultat = $this->getBdd()->recuperer($requete);
642
		if ($resultat === false) {
643
			$requete = 	"ALTER TABLE {$this->table} ".
644
				'ADD famille VARCHAR(255) '.
645
				'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ';
646
			$this->getBdd()->requeter($requete);
647
		}
648
	}
649
 
650
	private function recupererTuplesPrChpFamille() {
651
		$requete = 'SELECT num_nom, num_nom_retenu, num_tax_sup, rang, nom_sci '.
652
			"FROM {$this->table} ".
653
			"WHERE rang >= 180 ".
654
			"ORDER BY rang ASC, num_tax_sup ASC, num_nom_retenu DESC ";
655
		$resultat = $this->getBdd()->recupererTous($requete);
656
		return $resultat;
657
	}
658
 
659
	private function remplirChpFamille($noms) {
660
		foreach ($noms as $id => $famille) {
661
			$famille = $this->getBdd()->proteger($famille);
662
			$requete = "UPDATE {$this->table} SET famille = $famille WHERE num_nom = $id ";
663
			$resultat = $this->getBdd()->requeter($requete);
664
			if ($resultat === false) {
665
				throw new Exception("Erreur d'insertion pour le tuple $id");
666
			}
667
			$this->afficherAvancement("Insertion des noms de famille dans la base en cours");
668
		}
669
		echo "\n";
670
	}
671
 
672
	private function genererChpHierarchie() {
673
		$this->preparerTablePrChpHierarchie();
674
		$table = Config::get('tables.isfan');
675
 
676
		$requete = "UPDATE {$this->table} SET hierarchie = NULL ";
677
		$mise_a_jour = $this->getBdd()->requeter($requete);
678
 
679
		$requete_hierarchie = "SELECT num_nom, num_nom_retenu, num_tax_sup FROM " . $this->table . " ORDER BY rang DESC";
680
 
681
		$resultat = $this->getBdd()->recupererTous($requete_hierarchie);
682
		$num_nom_a_num_sup = array();
683
		foreach($resultat as &$taxon) {
684
			$num_nom_a_num_sup[$taxon['num_nom']] = $taxon['num_tax_sup'];
685
		}
686
		$chemin_taxo = "";
687
		foreach($resultat as &$taxon) {
688
			$chemin_taxo = $this->traiterHierarchieNumTaxSup($taxon['num_nom_retenu'], $num_nom_a_num_sup).'-';
689
			$requete = "UPDATE {$this->table} SET hierarchie = ".$this->getBdd()->proteger($chemin_taxo)." WHERE num_nom = ".$taxon['num_nom']." ";
690
			$mise_a_jour = $this->getBdd()->requeter($requete);
691
			$this->afficherAvancement("Insertion de la hierarchie taxonomique en cours");
692
		}
693
		echo "\n";
694
	}
695
 
696
	private function traiterHierarchieNumTaxSup($num_nom_retenu, &$num_nom_a_num_sup) {
697
		$chaine_hierarchie = "";
698
		if(isset($num_nom_a_num_sup[$num_nom_retenu])) {
699
			$num_tax_sup = $num_nom_a_num_sup[$num_nom_retenu];
700
			$chaine_hierarchie = '-'.$num_tax_sup;
701
			if($num_tax_sup != 0 && $num_tax_sup != '') {
702
				$chaine_hierarchie = $this->traiterHierarchieNumTaxSup($num_tax_sup, $num_nom_a_num_sup).$chaine_hierarchie;
703
			}
704
		}
705
		return $chaine_hierarchie;
706
	}
707
 
708
	private function preparerTablePrChpHierarchie() {
709
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'hierarchie' ";
710
		$resultat = $this->getBdd()->recuperer($requete);
711
		if ($resultat === false) {
712
			$requete = 	"ALTER TABLE {$this->table} ".
713
						'ADD hierarchie VARCHAR(1000) '.
714
						'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ';
715
			$this->getBdd()->requeter($requete);
716
		}
717
	}
718
}
719
?>