Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 880 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
706 aurelien 1
<?php
2
//declare(encoding='UTF-8');
3
/**
4
 * Exemple de lancement du script : :
5
 * /opt/lampp/bin/php cli.php isfan -a chargerTous
6
 *
7
 * @category	php 5.2
8
 * @package		eFlore/Scripts
9
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
10
 * @copyright	Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org)
11
 * @license		http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
12
 * @license		http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
13
 * @version		$Id$
14
 */
15
class Isfan extends EfloreScript {
16
 
17
	private $table = null;
18
	private $pasInsertion = 1000;
19
	private $departInsertion = 0;
20
 
21
	protected $parametres_autorises = array(
22
		'-t' => array(false, false, 'Permet de tester le script sur un jeu réduit de données (indiquer le nombre de lignes).'));
23
 
24
	public function executer() {
25
		try {
26
			$this->initialiserProjet('isfan');
27
 
28
			// Lancement de l'action demandée
29
			$cmd = $this->getParametre('a');
30
			switch ($cmd) {
31
				case 'chargerTous' :
32
					$this->chargerStructureSql();
33
					$this->chargerisfan();
34
					$this->genererChpNumTax();
35
					$this->genererChpNomSciHtml();
36
					$this->genererChpFamille();
37
					$this->genererChpNomComplet();
38
					$this->genererChpHierarchie();
39
					break;
40
				case 'chargerStructureSql' :
41
					$this->chargerStructureSql();
42
					break;
43
				case 'chargerIsfan' :
44
					$this->chargerIsfan();
45
					break;
46
				case 'genererChpNumTax' :
47
					$this->genererChpNumTax();
48
					break;
49
				case 'genererChpNomSciHtml' :
50
					$this->genererChpNomSciHtml();
51
					break;
52
				case 'genererChpNomComplet' :
53
					$this->initialiserGenerationChamps();
54
					$this->genererChpNomComplet();
55
					break;
56
				case 'genererChpFamille' :
57
					$this->genererChpFamille();
58
					break;
59
				case 'genererChpHierarchie' :
60
					$this->genererChpHierarchie();
61
					break;
62
				case 'supprimerTous' :
63
					$this->supprimerTous();
64
					break;
65
				default :
66
					throw new Exception("Erreur : la commande '$cmd' n'existe pas!");
67
			}
68
		} catch (Exception $e) {
69
			$this->traiterErreur($e->getMessage());
70
		}
71
	}
72
 
73
	private function chargerIsfan() {
716 aurelien 74
		$chemin = Config::get('chemins.bdt');
706 aurelien 75
		$table = Config::get('tables.isfan');
76
		$requete = "LOAD DATA INFILE '$chemin' ".
77
				"REPLACE INTO TABLE $table ".
78
				'CHARACTER SET utf8 '.
79
				'FIELDS '.
80
				"	TERMINATED BY '\t' ".
81
				"	ENCLOSED BY '' ".
82
				"	ESCAPED BY '\\\' ".
83
				'IGNORE 1 LINES';
84
		$this->getBdd()->requeter($requete);
85
	}
86
 
87
	private function genererChpNumTax() {
88
		$this->initialiserGenerationChamps();
89
		$this->preparerTablePrChpNumTax();
90
		$erreurs = array();
91
		$this->departInsertion = 0;
92
		$dernier_num_tax = 0;
93
 
94
		$requete = 'SELECT num_nom '.
95
					'FROM '.$this->table.' '.
96
					'WHERE num_nom = num_nom_retenu AND num_nom_retenu != 0 '.
97
					'ORDER by num_nom_retenu ASC ';
98
 
99
		$resultat = $this->getBdd()->recupererTous($requete);
100
		foreach ($resultat as $taxon) {
101
			$dernier_num_tax++;
102
			$requete_maj = 'UPDATE '.$this->table.' '.
103
							'SET num_taxonomique = '.$dernier_num_tax.' '.
104
							'WHERE num_nom_retenu = '.$taxon['num_nom'];
105
			$this->getBdd()->requeter($requete_maj);
106
			$this->pasInsertion++;
107
			$this->afficherAvancement("Insertion des num tax, ".count($resultat)." num tax a traiter");
108
		}
109
		echo "\n";
110
		$this->creerFichierLog('Erreurs lors de la génération des numéros taxonomiques', $erreurs, 'erreurs_num_tax');
111
	}
112
 
113
	private function preparerTablePrChpNumTax() {
114
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'num_taxonomique' ";
115
		$resultat = $this->getBdd()->recuperer($requete);
116
		if ($resultat === false) {
117
			$requete = 	"ALTER TABLE {$this->table} ".
118
						'ADD num_taxonomique INT( 9 ) ';
119
			$this->getBdd()->requeter($requete);
120
		}
121
	}
122
 
123
	private function genererChpNomSciHtml() {
124
		$this->initialiserGenerationChamps();
125
		$this->preparerTablePrChpNomSciHtml();
126
		$generateur = new GenerateurNomSciHtml();
127
		$nbreTotal = $this->recupererNbTotalTuples();
128
		$erreurs = array();
129
		$this->departInsertion = 0;
130
		while ($this->departInsertion < $nbreTotal) {
131
			$resultat = $this->recupererTuplesPrChpNomSciHtml();
132
 
133
			try {
134
				$nomsSciEnHtml = $generateur->generer($resultat);
135
			} catch (Exception $e) {
136
				$erreurs[] = $e->getMessage();
137
			}
138
 
139
			$this->remplirChpNomSciHtm($nomsSciEnHtml);
140
			$this->departInsertion += $this->pasInsertion;
141
			$this->afficherAvancement("Insertion des noms scientifique au format HTML dans la base par paquet de {$this->pasInsertion} en cours");
142
			if ($this->stopperLaBoucle($this->getParametre('t'))) break;
143
		}
144
		echo "\n";
145
 
146
		$this->creerFichierLog('Erreurs lors de la génération HTML des noms scientifiques', $erreurs, 'erreurs_noms_sci_html');
147
	}
148
 
149
	private function initialiserGenerationChamps() {
150
		$this->table = Config::get('tables.isfan');
151
	}
152
 
153
	private function preparerTablePrChpNomSciHtml() {
154
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'nom_sci_html' ";
155
		$resultat = $this->getBdd()->recuperer($requete);
156
		if ($resultat === false) {
157
			$requete = 	"ALTER TABLE {$this->table} ".
158
					'ADD nom_sci_html VARCHAR( 500 ) '.
159
					'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ';
160
			$this->getBdd()->requeter($requete);
161
		}
162
	}
163
 
164
	private function recupererNbTotalTuples(){
165
		$requete = "SELECT count(*) AS nb FROM {$this->table} ";
166
		$resultat = $this->getBdd()->recuperer($requete);
167
		return $resultat['nb'];
168
	}
169
 
170
	private function recupererTuplesPrChpNomSciHtml() {
171
		$requete = 'SELECT 	num_nom, rang, genre, '.
172
				'	epithete_sp, type_epithete, epithete_infra_sp '.
173
				"FROM {$this->table} ".
174
				"LIMIT {$this->departInsertion},{$this->pasInsertion} ";
175
		$resultat = $this->getBdd()->recupererTous($requete);
176
		return $resultat;
177
	}
178
 
179
	private function remplirChpNomSciHtm($nomsSciHtm) {
180
		foreach ($nomsSciHtm as $id => $html) {
181
			$html = $this->getBdd()->proteger($html);
182
			$requete = "UPDATE {$this->table} SET nom_sci_html = $html WHERE num_nom = $id ";
183
			$resultat = $this->getBdd()->requeter($requete);
184
			if ($resultat === false) {
185
				throw new Exception("Erreur d'insertion pour le tuple $id");
186
			}
187
		}
188
	}
189
 
190
	private function genererChpNomComplet() {
191
		$this->preparerTablePrChpNomComplet();
192
		$this->remplirChpNomComplet();
193
	}
194
 
195
	private function preparerTablePrChpNomComplet() {
196
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'nom_complet' ";
197
		$resultat = $this->getBdd()->recuperer($requete);
198
		if ($resultat === false) {
199
			$requete = 	"ALTER TABLE {$this->table} ".
200
						'ADD nom_complet VARCHAR( 500 ) '.
201
						'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ';
202
			$this->getBdd()->requeter($requete);
203
		}
204
	}
205
 
206
	private function remplirChpNomComplet() {
207
		echo "Attribution du champ nom complet au taxons : ";
208
		$requete = "UPDATE {$this->table} SET nom_complet = CONCAT(nom_sci,' ',auteur)";
209
		$resultat = $this->getBdd()->requeter($requete);
210
		if ($resultat === false) {
211
			echo "KO\n";
212
			throw new Exception("Erreur de génération du champ nom complet");
213
		} else {
214
			echo "OK\n";
215
		}
216
	}
217
 
218
	private function genererChpFamille() {
219
		$this->initialiserGenerationChamps();
220
		$this->preparerTablePrChpFamille();
221
		$resultats = $this->recupererTuplesPrChpFamille();
222
		$noms = array();
223
		$introuvables = array();
224
		$introuvablesSyno = array();
225
		foreach ($resultats as $id => $nom) {
226
			$nn = $nom['num_nom'];
227
			$nnr = $nom['num_nom_retenu'];
228
			$nts = $nom['num_tax_sup'];
229
			$rg = $nom['rang'];
230
			if ($nnr != '') {
231
				if ($rg == '180') {
232
					$noms[$nn] = $nom['nom_sci'];
233
				} else {
234
					if ($nn == $nnr) {// nom retenu
235
						if (isset($noms[$nts])) {
236
							$noms[$nn] = $noms[$nts];
237
						} else {
238
							$introuvables[] = $nn;
239
						}
240
					} else {// nom synonyme
241
						if (isset($noms[$nnr])) {
242
							$noms[$nn] = $noms[$nnr];
243
						} else {
244
							$introuvablesSyno[] = $nom;
245
						}
246
					}
247
				}
248
			}
249
			unset($resultats[$id]);
250
			$this->afficherAvancement("Attribution de leur famille aux noms en cours");
251
			if ($this->stopperLaBoucle($this->getParametre('t'))) break;
252
		}
253
		echo "\n";
254
 
255
		foreach ($introuvablesSyno as $id => $nom) {
256
			$nn = $nom['num_nom'];
257
			$nnr = $nom['num_nom_retenu'];
258
			if (isset($noms[$nnr])) {
259
				$noms[$nn] = $noms[$nnr];
260
			} else {
261
				$introuvables[] = $nn;
262
			}
263
			unset($introuvablesSyno[$id]);
264
			$this->afficherAvancement("Attribution de leur famille aux synonymes en cours");
265
		}
266
		echo "\n";
267
 
268
		$msg = 'Plusieurs familles sont introuvables';
269
		$this->creerFichierLog($msg, $introuvables, 'famille_introuvable');
270
 
271
		$this->remplirChpFamille($noms);
272
	}
273
 
274
	private function preparerTablePrChpFamille() {
275
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'famille' ";
276
		$resultat = $this->getBdd()->recuperer($requete);
277
		if ($resultat === false) {
278
			$requete = 	"ALTER TABLE {$this->table} ".
279
				'ADD famille VARCHAR(255) '.
280
				'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ';
281
			$this->getBdd()->requeter($requete);
282
		}
283
	}
284
 
285
	private function recupererTuplesPrChpFamille() {
286
		$requete = 'SELECT num_nom, num_nom_retenu, num_tax_sup, rang, nom_sci '.
287
			"FROM {$this->table} ".
288
			"WHERE rang >= 180 ".
289
			"ORDER BY rang ASC, num_tax_sup ASC, num_nom_retenu DESC ";
290
		$resultat = $this->getBdd()->recupererTous($requete);
291
		return $resultat;
292
	}
293
 
294
	private function remplirChpFamille($noms) {
295
		foreach ($noms as $id => $famille) {
296
			$famille = $this->getBdd()->proteger($famille);
297
			$requete = "UPDATE {$this->table} SET famille = $famille WHERE num_nom = $id ";
298
			$resultat = $this->getBdd()->requeter($requete);
299
			if ($resultat === false) {
300
				throw new Exception("Erreur d'insertion pour le tuple $id");
301
			}
302
			$this->afficherAvancement("Insertion des noms de famille dans la base en cours");
303
		}
304
		echo "\n";
305
	}
306
 
307
	private function genererChpHierarchie() {
308
		$this->initialiserGenerationChamps();
309
		$this->preparerTablePrChpHierarchie();
310
		$table = Config::get('tables.isfan');
311
 
312
		$requete = "UPDATE $table SET hierarchie = NULL ";
313
		$mise_a_jour = $this->getBdd()->requeter($requete);
314
 
315
		$requete_hierarchie = "SELECT num_nom, num_nom_retenu, num_tax_sup FROM ".$table." ORDER BY rang DESC";
316
 
317
		$resultat = $this->getBdd()->recupererTous($requete_hierarchie);
318
		$num_nom_a_num_sup = array();
319
		foreach($resultat as &$taxon) {
320
			$num_nom_a_num_sup[$taxon['num_nom']] = $taxon['num_tax_sup'];
321
		}
322
		$chemin_taxo = "";
323
		foreach($resultat as &$taxon) {
324
			$chemin_taxo = $this->traiterHierarchieNumTaxSup($taxon['num_nom_retenu'], $num_nom_a_num_sup).'-';
325
			$requete = "UPDATE $table SET hierarchie = ".$this->getBdd()->proteger($chemin_taxo)." WHERE num_nom = ".$taxon['num_nom']." ";
326
			$mise_a_jour = $this->getBdd()->requeter($requete);
327
			$this->afficherAvancement("Insertion de la hierarchie taxonomique en cours");
328
		}
329
		echo "\n";
330
	}
331
 
332
	private function traiterHierarchieNumTaxSup($num_nom_retenu, &$num_nom_a_num_sup) {
333
		$chaine_hierarchie = "";
334
		if(isset($num_nom_a_num_sup[$num_nom_retenu])) {
335
			$num_tax_sup = $num_nom_a_num_sup[$num_nom_retenu];
336
			$chaine_hierarchie = '-'.$num_tax_sup;
337
			if($num_tax_sup != 0 && $num_tax_sup != '') {
338
				$chaine_hierarchie = $this->traiterHierarchieNumTaxSup($num_tax_sup, $num_nom_a_num_sup).$chaine_hierarchie;
339
			}
340
		}
341
		return $chaine_hierarchie;
342
	}
343
 
344
	private function preparerTablePrChpHierarchie() {
345
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'hierarchie' ";
346
		$resultat = $this->getBdd()->recuperer($requete);
347
		if ($resultat === false) {
348
			$requete = 	"ALTER TABLE {$this->table} ".
349
						'ADD hierarchie VARCHAR(1000) '.
350
						'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ';
351
			$this->getBdd()->requeter($requete);
352
		}
353
	}
354
 
355
	private function genererDonneesTestMultiVersion() {
356
		$contenuSql = $this->recupererContenu(Config::get('chemins.structureSqlTest'));
357
		$this->executerScripSql($contenuSql);
358
 
359
		$table = Config::get('tables.isfan');
360
		$tableTest = Config::get('tables.isfanTest');
361
		$requete = "INSERT INTO $tableTest SELECT * FROM $table";
362
		$this->getBdd()->requeter($requete);
363
	}
364
 
365
	private function supprimerDonneesTestMultiVersion() {
366
		$tableMeta = Config::get('tables.isfanMeta');
367
		$requete = "DELETE FROM $tableMeta WHERE guid = 'urn:lsid:tela-botanica.org:isfan:1.00'";
368
		$this->getBdd()->requeter($requete);
369
 
370
		$tableTest = Config::get('tables.isfanTest');
371
		$requete = "DROP TABLE IF EXISTS $tableTest";
372
		$this->getBdd()->requeter($requete);
373
	}
374
	private function supprimerTous() {
375
		$requete = "DROP TABLE IF EXISTS isfan_meta, isfan_v0_01, isfan_v1_00";
376
		$this->getBdd()->requeter($requete);
377
	}
378
 
379
	private function creerFichierLog($message, $lignes, $nomFichier) {
380
		$lignesNbre = count($lignes);
381
		if ($lignesNbre != 0) {
382
			echo "$message. Voir le log de $lignesNbre lignes :\n";
383
 
384
			$logContenu = implode(", \n", $lignes);
385
			$logFichier = realpath(dirname(__FILE__))."/log/$nomFichier.log";
386
			echo $logFichier."\n";
387
			file_put_contents($logFichier, $logContenu);
388
		}
389
	}
390
}
391
?>