Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 416 | Rev 439 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
370 mathilde 1
<?php
2
/** Exemple lancement:
3
 * /opt/lampp/bin/php -d memory_limit=3500M ~/web/eflore-projets/scripts/cli.php baseflor -a chargerTous
4
*/
5
class Baseflor extends EfloreScript {
433 jpm 6
 
370 mathilde 7
	private $table = null;
433 jpm 8
	private $fichierDonnees = '';
9
	private $log = '';
10
	private $nb_erreurs;
370 mathilde 11
	private $erreurs_ligne;
12
	private $ligne_num;
13
	private $colonne_valeur;
14
	private $colonne_num;
433 jpm 15
	private $type_bio = array();
16
	private $ss_type_bio = array();
17
	private $signes_seuls = array();// basés sur valeurs trouvées (--> pas de légende !)
18
	private $signes_nn_seuls = array();// basés sur valeurs trouvées (--> pas de légende !)
19
	private $intervalles = array();
20
	private $motifs = array();
370 mathilde 21
 
22
	public function executer() {
23
		try {
24
			$this->initialiserProjet('baseflor');
25
			$cmd = $this->getParametre('a');
433 jpm 26
			switch ($cmd) {
27
				case 'chargerStructureSql' :
28
					$this->chargerStructureSql();
370 mathilde 29
					break;
433 jpm 30
				case 'chargerMetadonnees':
31
					$this->chargerMetadonnees();
370 mathilde 32
					break;
433 jpm 33
				case 'chargerOntologies' :
34
					$this->chargerOntologies();
35
					break;
36
				case 'verifierDonnees' :
37
					$this->verifFichier();
38
					break;
39
				case 'chargerDonnees' :
40
					$this->chargerDonnees();
41
					break;
370 mathilde 42
				case 'genererChamps' :
433 jpm 43
					 $this->genererChamps();
370 mathilde 44
					 break;
433 jpm 45
				case 'chargerTous':
46
					$this->chargerStructureSql();
416 mathilde 47
					$this->chargerMetadonnees();
433 jpm 48
					$this->chargerOntologies();
49
					$this->chargerDonnees();
50
					$this->genererChamps();
416 mathilde 51
					break;
433 jpm 52
				case 'supprimerTous' :
53
					$this->supprimerTous();
54
					break;
370 mathilde 55
				default :
56
					throw new Exception("Erreur : la commande '$cmd' n'existe pas!");
57
			}
58
		} catch (Exception $e) {
59
			$this->traiterErreur($e->getMessage());
60
		}
433 jpm 61
	}
370 mathilde 62
 
433 jpm 63
	private function genererChamps(){
64
		$this->initialiserGenerationChamps();
65
		$this->ajouterChamps();
66
		$this->analyserChampsExistant();
67
	}
370 mathilde 68
 
433 jpm 69
	private function initialiserGenerationChamps() {
70
		$this->table = Config::get('tables.donnees');
71
	}
370 mathilde 72
 
433 jpm 73
	private function ajouterChamps() {
74
		$this->preparerTablePrChpsBDNT();
75
		$this->preparerTablePrChpsNumTaxon();
76
		$this->preparerTablePrChpsNumNomen();
77
	}
78
 
79
	private function preparerTablePrChpsBDNT() {
80
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'BDNT' ";
81
		$resultat = $this->getBdd()->recuperer($requete);
82
		if ($resultat === false) {
83
			$requete = 	"ALTER TABLE {$this->table} ".
84
					'ADD BDNT VARCHAR( 6 ) '.
85
					'CHARACTER SET utf8 COLLATE utf8_general_ci '.
86
					'NOT NULL AFTER catminat_code ';
87
			$this->getBdd()->requeter($requete);
88
		}
89
	}
90
 
91
	private function preparerTablePrChpsNumTaxon() {
92
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'num_taxon' ";
93
		$resultat = $this->getBdd()->recuperer($requete);
94
		if ($resultat === false) {
95
			$requete = "ALTER TABLE {$this->table} ".
96
					'ADD num_taxon INT( 10 ) NOT NULL '.
97
					'AFTER catminat_code';
98
			$this->getBdd()->requeter($requete);
99
		}
100
	}
101
 
102
	private function preparerTablePrChpsNumNomen() {
103
		$requete = "SHOW COLUMNS FROM {$this->table} LIKE 'num_nomen' ";
104
		$resultat = $this->getBdd()->recuperer($requete);
105
		if ($resultat === false) {
106
			$requete = "ALTER TABLE {$this->table} ".
107
					'ADD num_nomen INT( 10 ) NOT NULL '.
108
					'AFTER catminat_code';
109
			$this->getBdd()->requeter($requete);
110
		}
111
	}
370 mathilde 112
 
433 jpm 113
	private function analyserChampsExistant() {
114
		$resultats = $this->recupererTuplesNumsOriginels();
115
		foreach ($resultats as $chps) {
116
			$cle = $chps['cle'];
117
			$nno = $chps['num_nomen_originel'];
118
			$nto = $chps['num_taxon_originel'];
370 mathilde 119
 
433 jpm 120
			$valeurs = array();
121
			$valeurs["BDNT"] = $this->genererChpsBDNT($nno, $nto);
122
			$valeurs["num_taxon"] = $this->genererChpsNumTaxon($nto);
123
			$valeurs["num_nomen"] = $this->genererChpsNumNomen($nno);
370 mathilde 124
 
433 jpm 125
			$this->remplirChamps($cle, $valeurs);
370 mathilde 126
 
433 jpm 127
			$this->afficherAvancement("Insertion des valeurs dans la base en cours");
128
		}
129
		echo "\n";
130
	}
131
 
132
	private function recupererTuplesNumsOriginels(){
133
		$requete = "SELECT cle, num_taxon_originel, num_nomen_originel FROM {$this->table} ";
134
		$resultat = $this->getBdd()->recupererTous($requete);
135
		return $resultat;
136
	}
137
 
138
	private function genererChpsBDNT($nno, $nto) {
139
		$bdnt = '';
140
		if (preg_match("/^([AB])[0-9]+$/", $nno, $retour) || preg_match("/^([AB])[0-9]+$/", $nto, $retour)){
141
			if ($retour[1]=='A') {
142
				$bdnt = "BDAFX";
143
			} else {
144
				$bdnt = "BDBFX";
145
			}
146
		} elseif (($nno == 'nc') && ($nto == 'nc')) {
147
			$bdnt = "nc";
148
		} else {
149
			$bdnt = "BDTFX";
150
		}
151
		return $bdnt;
152
	}
153
 
154
	private function genererChpsNumTaxon($nto){
155
		$num_taxon = '';
156
		if (preg_match("/^[AB]([0-9]+)$/", $nto, $retour)) {
157
			$num_taxon = intval($retour[1]);
158
		} elseif($nto == 'nc') {
159
			$num_taxon = 0;
160
		} else {
161
			$num_taxon = intval($nto);
162
		}
163
		return $num_taxon;
164
	}
165
 
166
	private function genererChpsNumNomen($nno) {
167
		$num_nomen = '';
168
		if (preg_match("/^[AB]([0-9]+)$/", $nno, $retour)) {
169
			$num_nomen = intval($retour[1]);
170
		} elseif ($nno == 'nc') {
171
			$num_nomen = 0;
172
		} else {
173
			$num_nomen = intval($nno);
174
		}
175
		return $num_nomen;
176
	}
177
 
178
	 private function remplirChamps($cle, $valeurs) {
179
		foreach ($valeurs as $nomChamp => $valeurChamp) {
180
			$valeurChamp = $this->getBdd()->proteger($valeurChamp);
181
			$requete = "UPDATE {$this->table} SET $nomChamp = $valeurChamp WHERE cle = $cle ";
182
			$resultat = $this->getBdd()->requeter($requete);
183
			if ($resultat === false) {
184
				throw new Exception("Erreur d'insertion pour le tuple clé = $cle");
185
			}
186
		}
187
	}
188
 
189
	//+------------------------------------------------------------------------------------------------------+
190
	// chargements, suppression, exécution
191
 
192
	protected function chargerMetadonnees() {
193
		$contenuSql = $this->recupererContenu(Config::get('chemins.metadonnees'));
194
		$this->executerScripSql($contenuSql);
195
	}
196
 
197
	private function chargerOntologies() {
198
		$chemin = Config::get('chemins.ontologies');
199
		$table = Config::get('tables.ontologies');
200
		$requete = "LOAD DATA INFILE '$chemin' ".
201
			"REPLACE INTO TABLE $table ".
202
			'CHARACTER SET utf8 '.
203
			'FIELDS '.
204
			"	TERMINATED BY '\t' ".
205
			"	ENCLOSED BY '' ".
206
			"	ESCAPED BY '\\\' "
207
			;
208
		$this->getBdd()->requeter($requete);
209
	}
210
 
211
	protected function chargerStructureSql() {
212
		$contenuSql = $this->recupererContenu(Config::get('chemins.structureSql'));
213
		$this->executerScripSql($contenuSql);
214
	}
215
 
216
	protected function executerScripSql($sql) {
217
		$requetes = Outils::extraireRequetes($sql);
218
		foreach ($requetes as $requete) {
219
			$this->getBdd()->requeter($requete);
220
		}
221
	}
222
 
223
	private function chargerDonnees() {
224
		$this->verifFichier();
225
		if ($this->nb_erreurs > 0) {
226
			$e = "Je ne peux pas charger les données car le fichier comporte des erreurs.".
227
					"Voir le fichier baseflor_verif.txt\n";
228
			throw new Exception($e);
229
		}
230
 
231
		$table = Config::get('tables.donnees');
232
		$requete = "LOAD DATA INFILE '".Config::get('chemins.donnees')."' ".
233
			"REPLACE INTO TABLE $table ".
234
			'CHARACTER SET utf8 '.
235
			'FIELDS '.
236
			"	TERMINATED BY '\t' ".
237
			"	ENCLOSED BY '' ".
238
			"	ESCAPED BY '\\\'";
239
		$this->getBdd()->requeter($requete);
240
	}
241
 
242
	private function supprimerTous() {
243
		$requete = "DROP TABLE IF EXISTS baseflor_meta, baseflor_ontologies, baseflor_v2012_03_19";
244
		$this->getBdd()->requeter($requete);
245
	}
246
 
247
	//+------------------------------------------------------------------------------------------------------+
248
	// vérifications de données
249
 
250
	//verifie la cohérence des valeurs des colonnes
251
	private function verifFichier(){
252
		$this->initialiserParametresVerif();
253
 
254
		$lignes = file($this->fichierDonnees, FILE_IGNORE_NEW_LINES);
255
		if ($lignes != false) {
256
			$this->ajouterAuLog("!!! REGARDEZ LES COLONNES DANS NUMERO_COLONNES_IMPORTANT.TXT.");
257
			foreach ($lignes as $this->ligne_num => $ligne) {
258
				$this->verifierErreursLigne($ligne);
259
				$this->afficherAvancement("Vérification des lignes");
260
			}
261
			echo "\n";
262
		} else {
263
			$this->traiterErreur("Le fichier {$this->fichierDonnees} ne peut pas être ouvert.");
264
		}
265
 
266
		if ($this->nb_erreurs == 0) {
267
			$this->ajouterAuLog("Il n'y a pas d'erreurs.");
268
		}
269
		$this->traiterInfo($this->nb_erreurs." erreurs");
270
 
271
		$this->ecrireFichierLog();
272
	}
273
 
274
	//vérifie par colonnes les erreurs d'une ligne
275
	private function verifierErreursLigne($ligne){
276
		$this->erreurs_ligne = array();
277
		$colonnes = explode("\t", $ligne);
278
		if (isset($colonnes)) {
279
			foreach ($colonnes as $this->colonne_num => $this->colonne_valeur) {
280
				if (( $this->colonne_num > 0 && $this->colonne_num < 15 )
281
						|| $this->colonne_num == 16
282
						|| ($this->colonne_num > 18 && $this->colonne_num < 23)
283
						|| $this->colonne_num > 39) {
284
					$this->verifierColonne();
285
				} elseif ($this->colonne_num == 15) {
286
					$this->verifierTypeBio();
287
				} elseif ($this->colonne_num >= 23 && $this->colonne_num <= 32) {
288
					$this->verifierIntervalles($this->colonne_valeur);
289
				} elseif ($this->colonne_num >= 33 && $this->colonne_num < 41) {
290
					$this->verifierValeursIndic();
291
				}
292
			}
293
		} else {
294
			$message = "Ligne {$this->ligne_num} : pas de tabulation";
295
			$this->ajouterAuLog($message);
296
		}
297
 
298
		$this->controlerErreursLigne();
299
	}
300
 
301
	private function verifierColonne(){
302
		$motif = $this->motifs[$this->colonne_num];
303
		if (preg_match($motif, $this->colonne_valeur) == 0 && $this->verifierSiVide() == false){
304
			$this->erreurs_ligne[$this->colonne_num] = $this->colonne_valeur;
305
		}
306
	}
307
 
308
	private function verifierSiVide(){
309
		$vide = ($this->colonne_valeur  == '') ? true : false;
310
		return $vide;
311
	}
312
 
313
	private function verifierTypeBio(){
314
		if (preg_match("/(.+)\((.+)\)$/", $this->colonne_valeur, $retour) == 1) {
315
			$this->verifierTypeEtSsType($retour[1]);
316
			$this->verifierTypeEtSsType($retour[2]);
317
		} else {
318
			$this->verifierTypeEtSsType($this->colonne_valeur);
319
		}
320
	}
321
 
322
	private function verifierTypeEtSsType($chaine_a_verif){
323
		if (preg_match("/^([a-zA-Zé]+)\-(.+)$|^([a-zA-Zé]+[^\-])$/", $chaine_a_verif, $retour) == 1) {
324
			$type = (isset($retour[3])) ? $retour[3] : $retour[1];
325
			$this->verifierType($type);
326
 
327
			$sousType = $retour[2];
328
			$this->verifierSousType($sousType);
329
		}
330
	}
331
 
332
	private function verifierType($type) {
333
		if (in_array($type, $this->type_bio) == false) {
334
			$this->erreurs_ligne[$this->colonne_num] = $this->colonne_valeur;
335
		}
336
	}
337
 
338
	private function verifierSousType($sousType) {
339
		if ($sousType != ''){
340
			$ss_type = explode('-', $sousType);
341
			foreach ($ss_type as $sst) {
342
				if (in_array($sst, $this->ss_type_bio) == false) {
343
					$this->erreurs_ligne[$this->colonne_num] = $this->colonne_valeur;
344
				}
345
			}
346
		}
347
	}
348
 
349
	private function verifierIntervalles($valeur){
350
		if ($valeur != '') {
351
			list($min, $max) = explode('-', $this->intervalles[$this->colonne_num]);
352
			if ($valeur < $min || $valeur > $max){
353
				$this->erreurs_ligne[$this->colonne_num] = $this->colonne_valeur;
354
			}
355
		}
356
	}
357
 
358
	private function verifierValeursIndic(){
359
		if (preg_match("/^([^0-9])*([0-9]+)([^0-9])*$/", $this->colonne_valeur, $retour) == 1){
360
			$this->verifierIntervalles($retour[2]);
361
			if (isset($retour[3]) && in_array($retour[3], $this->signes_nn_seuls) == false){
362
				$this->erreurs_ligne[$this->colonne_num] = $this->colonne_valeur;
363
			}
364
			if ($retour[1] != '-' && $retour[1] != ''){
365
				$this->erreurs_ligne[$this->colonne_num] = $this->colonne_valeur;
366
			}
367
		} elseif (in_array( $this->colonne_valeur, $this->signes_seuls) == false && $this->verifierSiVide() == false) {
368
			$this->erreurs_ligne[$this->colonne_num] = $this->colonne_valeur;
369
		}
370
	}
371
 
372
	private function controlerErreursLigne() {
373
		$nbreErreursLigne = count($this->erreurs_ligne);
374
		$this->nb_erreurs += $nbreErreursLigne;
375
		if ($nbreErreursLigne != 0) {
376
			$this->ajouterAuLog("Erreurs sur la ligne {$this->ligne_num}");
377
			$ligneLog = '';
378
			foreach ($this->erreurs_ligne as $cle => $v){
379
				$ligneLog .= "colonne $cle : $v - ";
380
			}
381
			$this->ajouterAuLog($ligneLog);
382
		}
383
	}
384
 
385
	//+------------------------------------------------------------------------------------------------------+
386
	// Chargement Paramètres
387
 
388
	private function initialiserParametresVerif() {
389
		$this->nb_erreurs = 0;
390
		$this->fichierDonnees = Config::get('chemins.donnees');
391
		$this->type_bio = $this->getParametreTableau('Parametres.typesBio');
392
		$this->ss_type_bio = $this->getParametreTableau('Parametres.sousTypesBio');
393
		$this->signes_seuls = $this->getParametreTableau('Parametres.signesSeuls');
394
		$this->signes_nn_seuls = $this->getParametreTableau('Parametres.signesNonSeuls');
395
		$this->intervalles = $this->inverserTableau($this->getParametreTableau('Parametres.intervalles'));
396
		$this->motifs = $this->inverserTableau($this->getParametreTableau('Parametres.motifs'));
397
	}
398
 
399
	private function getParametreTableau($cle) {
400
		$tableau = array();
401
		$parametre = Config::get($cle);
402
		if (empty($parametre) === false) {
403
			$tableauPartiel = explode(',', $parametre);
404
			$tableauPartiel = array_map('trim', $tableauPartiel);
405
			foreach ($tableauPartiel as $champ) {
406
				if (strpos($champ, '=') !== false && strlen($champ) >= 3) {
407
					list($cle, $val) = explode('=', $champ);
408
					$tableau[trim($cle)] = trim($val);
409
				} else {
410
					$tableau[] = trim($champ);
411
				}
412
			}
413
		}
414
		return $tableau;
415
	}
416
 
417
	private function inverserTableau($tableau) {
418
		$inverse = array();
419
		foreach ($tableau as $cle => $valeurs) {
420
			$valeurs = explode(';', $valeurs);
421
			foreach ($valeurs as $valeur) {
422
				$inverse[$valeur] = $cle;
423
			}
424
		}
425
		return $inverse;
426
	}
427
 
428
	//+------------------------------------------------------------------------------------------------------+
429
	// Gestion du Log
430
 
431
	private function ajouterAuLog($txt) {
432
		$this->log .= "$txt\n";
433
	}
434
 
435
	private function ecrireFichierLog() {
436
		$fichierLog = dirname(__FILE__).'/log/verification.log';
437
		file_put_contents($fichierLog, $this->log);
438
	}
370 mathilde 439
}
440
?>