Subversion Repositories Applications.referentiel

Rev

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

Rev Author Line No. Line
20 jpm 1
<?php
2
// Encodage : UTF-8
3
// +-------------------------------------------------------------------------------------------------------------------+
4
/**
5
* Tests de référentiels de nomenclature et taxonomie
6
*
7
* Description : classe permettant de tester les référentiels selon le manuel technique
8
* Utilisation : php script.php tests -p bdnff -a tout
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
// +-------------------------------------------------------------------------------------------------------------------+
38 jpm 18
// TODO : supprimer l'utilisation du paramêtres 'p' et chercher les infos depuis la bdd
20 jpm 19
class Tests extends ScriptCommande {
20
 
42 jpm 21
	const SCRIPT_NOM = 'tests';
22
 
20 jpm 23
	private $projet = null;
30 jpm 24
	private $traitement = null;
20 jpm 25
 
26
	private $manuel = null;
167 jpm 27
	private $colonnes = null;
28
	private $analyses = null;
64 jpm 29
	private $noms = null;
20 jpm 30
 
30 jpm 31
	private $resultatDao = null;
32
	private $traitementDao = null;
33
	private $tableStructureDao = null;
34
	private $referentielDao = null;
35
 
20 jpm 36
	public function executer() {
150 jpm 37
		$this->manuel = parse_ini_file(Config::get('chemin_appli').DS.'..'.DS.'configurations'.DS.'referentiel_v4.1.ini');
20 jpm 38
 
30 jpm 39
		$this->resultatDao = new ResultatDao();
40
		$this->traitementDao = new TraitementDao();
97 jpm 41
		Debug::printr('Dans le script test');
30 jpm 42
		// Récupération du dernier traitement demandé
142 delphine 43
		$this->traitement = $this->traitementDao->getDernierTraitement('tout', self::SCRIPT_NOM);
42 jpm 44
		if (isset($this->traitement)) {
142 delphine 45
			$this->projet = $this->traitement['referentiel_code']; // Récupération du nom de projet
38 jpm 46
			Debug::printr($this->traitement);
47
			// Écriture de la date de début du traitement
48
			Debug::printr('Debute:'.$this->traitementDao->debuterTraitement($this->traitement['id_traitement']));
49
 
50
			// Nettoyage des traitements obsolètes
42 jpm 51
			$traitements_obsoletes = $this->traitementDao->getTraitementsObsoletes($this->projet, self::SCRIPT_NOM);
52
			if (isset($traitements_obsoletes)) {
53
				Debug::printr('Supp. obsoletes:'.$this->traitementDao->supprimer($traitements_obsoletes));
54
			}
38 jpm 55
 
165 delphine 56
			$this->tableStructureDao = new TableStructureDao();
57
			$this->referentielDao = new ReferentielDao();
58
 
38 jpm 59
			// Lancement du test demandé
60
			$cmd = $this->getParam('a');
61
	    	switch ($cmd) {
62
				case 'tout' :
63
					Debug::printr('Départ lancement test:');
165 delphine 64
					$this->recupererDonnees();
38 jpm 65
					$this->lancerTests();
66
					break;
165 delphine 67
				case 'test11' :
68
					$this->recupererDonnees();
69
					Debug::printr('Départ lancement test 11 :');
70
					$this->testerClassificationRang();
71
					break;
38 jpm 72
				default :
73
					$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
74
			}
75
			// Écriture de la date de fin du traitement
76
			Debug::printr('Termine:'.$this->traitementDao->terminerTraitement($this->traitement['id_traitement']));
97 jpm 77
		} else {
142 delphine 78
			Debug::printr("Aucun dernier traitement trouvé pour le script '".self::SCRIPT_NOM."' !");
20 jpm 79
		}
80
    }
165 delphine 81
 
82
    public function recupererDonnees() {
20 jpm 83
		// Récupération des données à tester
167 jpm 84
		$this->colonnes = $this->tableStructureDao->getColonnes($this->projet);
85
		$this->analyses = $this->tableStructureDao->getAnalyse($this->projet);
64 jpm 86
		$this->noms = $this->referentielDao->getTout($this->projet);
87
		Debug::printr('Nbre noms :'.count($this->noms));
165 delphine 88
    }
89
 
90
    public function lancerTests() {
20 jpm 91
		// Lancement des tests unitaires
64 jpm 92
		$resultats = array();
167 jpm 93
		$resultats[] = $this->testerNombreDeChamps($this->colonnes);
94
		$resultats[] = $this->testerNomDesChamps($this->colonnes);
95
		$resultats[] = $this->testerTypeDesChamps($this->colonnes);
96
		$resultats[] = $this->testerNumNomClePrimaire($this->colonnes);
20 jpm 97
 
64 jpm 98
		// Si la structure est bonne nous lançons les autres tests
99
		Debug::printr($resultats);
100
		if ($this->verifierResultats($resultats)) {
167 jpm 101
			$this->testerTailleDesChamps($this->colonnes, $this->analyses);
64 jpm 102
 
103
			$this->testerNumNomSuperieurAZero();
104
 
105
			$this->testerNumNomRetenuSuperieurAZero();
106
			$this->testerNumTaxSupEgalZeroUnique();
107
			$this->testerTaxSupPourTaxon();
108
			$this->testerExitenceTaxonSuperieur();
165 delphine 109
			$this->testerClassificationRang();
64 jpm 110
			$this->testerClassification();
111
 
112
			$this->testerRang();
113
 
114
			$this->testerNomCompletSupraGenerique();
115
			$this->testerNomCompletGenre();
116
			$this->testerNomCompletInfraGenre();
117
			$this->testerNomCompletEspece();
118
			$this->testerNomCompletInfraSpecifique();
119
 
120
			$this->testerNomSupraGeneriqueEspaces();
121
			$this->testerNomSupraGeneriqueSyntaxe();
122
			$this->testerNomSupraGeneriqueRang();
123
 
124
			$this->testerGenreEspaces();
125
			$this->testerGenreSyntaxe();
126
			$this->testerGenreRang();
127
 
128
			$this->testerEpitheteInfraGeneriqueEspaces();
129
			$this->testerEpitheteInfraGeneriqueSyntaxe();
130
			$this->testerEpitheteInfraGeneriqueRang();
131
 
132
			$this->testerEpitheteSpEspaces();
133
			$this->testerEpitheteSpSyntaxe();
134
			$this->testerEpitheteSpRang();
135
 
136
			$this->testerTypeEpitheteEspaces();
137
			$this->testerTypeEpitheteSyntaxe();
138
			$this->testerTypeEpitheteHybridite();
139
 
140
			$this->testerEpitheteInfraSpEspaces();
141
			$this->testerEpitheteInfraSpSyntaxe();
142
			$this->testerEpitheteInfraSpRang();
143
 
144
			$this->testerGroupeCultivarSyntaxe();
145
			$this->testerGroupeCultivarRang();
146
 
147
			$this->testerCultivarSyntaxe();
148
			$this->testerCultivarRang();
149
 
150
			$this->testerNomCommercialSyntaxe();
151
			$this->testerNomCommercialPresenceCultivar();
152
 
153
			$this->testerAuteurSyntaxe();
154
 
155
			$this->testerAnneeSyntaxe();
156
 
157
			$this->testerBiblioOrigineSyntaxe();
158
 
159
			$this->testerHomonymieSyntaxe();
160
			$this->testerHomonymieExistence();
161
 
162
			$this->testerBasionymeSyntaxe();
163
			$this->testerBasionymeExistence();
164
 
165
			$this->testerSynonymeProparteSyntaxe();
166
			$this->testerSynonymeProparteExistence();
167
 
168
			$this->testerSynonymeDouteuxSyntaxe();
158 delphine 169
			$this->testerSynonymeDouteuxNumNomRetenu();
64 jpm 170
 
171
			$this->testerSynonymeMalAppliqueSyntaxe();
172
 
173
			$this->testerSynonymeOrthographiqueSyntaxe();
174
			$this->testerSynonymeOrthographiqueExistence();
175
 
176
			$this->testerHybrideParent01Syntaxe();
177
			$this->testerHybrideParent01Existence();
178
			$this->testerHybrideParent02Syntaxe();
179
			$this->testerHybrideParent02Existence();
180
 
181
			$this->testerPresenceSyntaxe();
182
			$this->testerStatutOrigineSyntaxe();
183
			$this->testerStatutIntroductionSyntaxe();
184
			$this->testerStatutCultureSyntaxe();
146 delphine 185
			$this->testerExclureTaxRefSyntaxe();
64 jpm 186
		}
20 jpm 187
	}
64 jpm 188
	private function verifierResultats($resultats) {
189
		$ok = true;
190
		foreach ($resultats as $resultat) {
191
			if ($resultat == '0') {
192
				$ok = false;
193
				break;
194
			}
195
		}
196
		return $ok;
197
	}
20 jpm 198
 
199
	//+--------------------------------------------------------------------------------------------------------------+//
30 jpm 200
	// Enregistrement des résultats
201
	private function traiterResultatTest($info) {
64 jpm 202
		Debug::printr($info['nom']);
30 jpm 203
		if (isset($info['message'])) {
204
			if (is_array($info['message'])) {
31 jpm 205
				$info['message'] = $this->getVue('tests/squelettes/message_table', $info);
206
			} else {
207
				$info['message'] = $this->getVue('tests/squelettes/message_p', $info);
30 jpm 208
			}
209
		}
210
		$this->resultatDao->ajouter($this->traitement['id_traitement'], $info);
64 jpm 211
		$info = null;
30 jpm 212
	}
213
 
214
	//+--------------------------------------------------------------------------------------------------------------+//
20 jpm 215
	// TESTS
216
 
64 jpm 217
	private function testerStatutCultureSyntaxe() {
30 jpm 218
		$info = array('nom' => 'statut_culture -> syntaxe',
20 jpm 219
			'description' => "Le champ statut_culture peut contenir :\n".
164 delphine 220
								" - le symbole tiret «-» précédant une autre information non référencée...\n".
221
								" - une première lettre en majuscule indiquant le code standard attribué à ce taxon,\n".
222
								" - éventuellement suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
223
								"un code de présence spécifique au référentiel.",
20 jpm 224
			'resultat' => false);
225
 
226
		// Réalisation du test
227
		$noms_erreur = array();
64 jpm 228
		foreach ($this->noms as &$nom) {
20 jpm 229
			if ($nom['statut_culture'] != '') {
230
				if (!$this->verifierStatutCulture($nom['statut_culture'])) {
231
					$noms_erreur[] = array($nom['num_nom'], $nom['statut_culture']);
232
				}
233
			}
234
		}
235
 
236
		// Analyse des résultats
237
		if (count($noms_erreur) > 0) {
238
			$info['message']['entete'] = array('num_nom', 'statut_culture erroné');
239
			$info['message']['lignes'] = $noms_erreur;
240
		} else {
241
			$info['resultat'] = true;
242
		}
64 jpm 243
		$noms_erreur = null;
20 jpm 244
 
30 jpm 245
		$this->traiterResultatTest($info);
20 jpm 246
	}
247
 
64 jpm 248
	private function testerStatutIntroductionSyntaxe() {
30 jpm 249
		$info = array('nom' => 'statut_introduction -> syntaxe',
20 jpm 250
			'description' => "Le champ statut_introduction peut contenir :\n".
164 delphine 251
								" - le symbole tiret «-» précédant une autre information non référencée...\n".
252
								" - une première lettre en majuscule indiquant le code standard attribué à ce taxon,\n".
253
								" - éventuellement suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
254
								"un code de présence spécifique au référentiel.",
20 jpm 255
			'resultat' => false);
256
 
257
		// Réalisation du test
258
		$noms_erreur = array();
64 jpm 259
		foreach ($this->noms as &$nom) {
20 jpm 260
			if ($nom['statut_introduction'] != '') {
261
				if (!$this->verifierStatutIntroduction($nom['statut_introduction'])) {
262
					$noms_erreur[] = array($nom['num_nom'], $nom['statut_introduction']);
263
				}
264
			}
265
		}
266
 
267
		// Analyse des résultats
268
		if (count($noms_erreur) > 0) {
269
			$info['message']['entete'] = array('num_nom', 'statut_introduction erroné');
270
			$info['message']['lignes'] = $noms_erreur;
271
		} else {
272
			$info['resultat'] = true;
273
		}
64 jpm 274
		$noms_erreur = null;
20 jpm 275
 
30 jpm 276
		$this->traiterResultatTest($info);
20 jpm 277
	}
278
 
64 jpm 279
	private function testerStatutOrigineSyntaxe() {
30 jpm 280
		$info = array('nom' => 'statut_origine -> syntaxe',
20 jpm 281
			'description' => "Le champ statut_origine peut contenir :\n".
164 delphine 282
								" - le symbole tiret «-» précédant une autre information non référencée...\n".
283
								" - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
284
								" - éventuellement suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
285
								"un code de présence spécifique au référentiel.",
20 jpm 286
			'resultat' => false);
287
 
288
		// Réalisation du test
289
		$noms_erreur = array();
64 jpm 290
		foreach ($this->noms as &$nom) {
20 jpm 291
			if ($nom['statut_origine'] != '') {
292
				if (!$this->verifierStatutOrigine($nom['statut_origine'])) {
293
					$noms_erreur[] = array($nom['num_nom'], $nom['statut_origine']);
294
				}
295
			}
296
		}
297
 
298
		// Analyse des résultats
299
		if (count($noms_erreur) > 0) {
300
			$info['message']['entete'] = array('num_nom', 'statut_origine erroné');
301
			$info['message']['lignes'] = $noms_erreur;
302
		} else {
303
			$info['resultat'] = true;
304
		}
64 jpm 305
		$noms_erreur = null;
20 jpm 306
 
30 jpm 307
		$this->traiterResultatTest($info);
20 jpm 308
	}
309
 
64 jpm 310
	private function testerPresenceSyntaxe() {
30 jpm 311
		$info = array('nom' => 'presence -> syntaxe',
20 jpm 312
			'description' => "Le champ presence contient soit :\n".
164 delphine 313
								" - le symbole tiret «-» précédant une autre information non référencée...\n".
314
								" - une première lettre en majuscule indiquant le code standard attribué à ce taxon,\n".
315
								" - éventuellement suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
316
								"un code de présence spécifique au référentiel.",
20 jpm 317
			'resultat' => false);
318
 
319
		// Réalisation du test
320
		$noms_erreur = array();
64 jpm 321
		foreach ($this->noms as &$nom) {
20 jpm 322
			if ($nom['presence'] != '') {
323
				if (!$this->verifierPresence($nom['presence'])) {
324
					$noms_erreur[] = array($nom['num_nom'], $nom['presence']);
325
				}
326
			}
327
		}
328
 
329
		// Analyse des résultats
330
		if (count($noms_erreur) > 0) {
331
			$info['message']['entete'] = array('num_nom', 'presence erroné');
332
			$info['message']['lignes'] = $noms_erreur;
333
		} else {
334
			$info['resultat'] = true;
335
		}
64 jpm 336
		$noms_erreur = null;
20 jpm 337
 
30 jpm 338
		$this->traiterResultatTest($info);
20 jpm 339
	}
340
 
64 jpm 341
	private function testerHybrideParent02Existence() {
30 jpm 342
		$info = array('nom' => 'hybride_parent_02 -> existence',
164 delphine 343
			'description' => "Si le champ hybride_parent_02 contient un nombre alors il doit correspondre à une valeur ".
344
								"du champ num_nom.",
20 jpm 345
			'resultat' => false);
346
 
347
		// Réalisation du test
348
		$noms_erreur = array();
64 jpm 349
		foreach ($this->noms as &$nom) {
20 jpm 350
			if ($nom['hybride_parent_02'] != '') {
64 jpm 351
				if (!isset($this->noms[$nom['hybride_parent_02']]) && $nom['hybride_parent_02'] != '0') {
42 jpm 352
					$noms_erreur[] = array($nom['num_nom'], $this->repererEspace($nom['hybride_parent_02']));
20 jpm 353
				}
354
			}
355
		}
356
 
357
		// Analyse des résultats
358
		if (count($noms_erreur) > 0) {
359
			$info['message']['entete'] = array('num_nom', 'hybride_parent_02 introuvable');
360
			$info['message']['lignes'] = $noms_erreur;
361
		} else {
362
			$info['resultat'] = true;
363
		}
64 jpm 364
		$noms_erreur = null;
20 jpm 365
 
30 jpm 366
		$this->traiterResultatTest($info);
20 jpm 367
	}
368
 
64 jpm 369
	private function testerHybrideParent02Syntaxe() {
30 jpm 370
		$info = array('nom' => 'hybride_parent_02 -> syntaxe',
20 jpm 371
			'description' => "Le champ hybride_parent_02 contient soit :\n".
164 delphine 372
								" - une valeur vide,\n".
373
								" - un nombre.",
20 jpm 374
			'resultat' => false);
375
 
376
		// Réalisation du test
377
		$noms_erreur = array();
64 jpm 378
		foreach ($this->noms as &$nom) {
20 jpm 379
			if ($nom['hybride_parent_02'] != '') {
380
				if (!$this->verifierNombre($nom['hybride_parent_02'])) {
42 jpm 381
					$noms_erreur[] = array($nom['num_nom'], $this->repererEspace($nom['hybride_parent_02']));
20 jpm 382
				}
383
			}
384
		}
385
 
386
		// Analyse des résultats
387
		if (count($noms_erreur) > 0) {
388
			$info['message']['entete'] = array('num_nom', 'hybride_parent_02 erroné');
389
			$info['message']['lignes'] = $noms_erreur;
390
		} else {
391
			$info['resultat'] = true;
392
		}
64 jpm 393
		$noms_erreur = null;
20 jpm 394
 
30 jpm 395
		$this->traiterResultatTest($info);
20 jpm 396
	}
397
 
398
 
64 jpm 399
	private function testerHybrideParent01Existence() {
30 jpm 400
		$info = array('nom' => 'hybride_parent_01 -> existence',
164 delphine 401
			'description' => "Si le champ hybride_parent_01 contient un nombre alors il doit correspondre à une valeur ".
402
								"du champ num_nom.",
20 jpm 403
			'resultat' => false);
404
 
405
		// Réalisation du test
406
		$noms_erreur = array();
64 jpm 407
		foreach ($this->noms as &$nom) {
20 jpm 408
			if ($nom['hybride_parent_01'] != '' && $nom['hybride_parent_01'] != '0') {
64 jpm 409
				if (!isset($this->noms[$nom['hybride_parent_01']])) {
42 jpm 410
					$noms_erreur[] = array($nom['num_nom'], $this->repererEspace($nom['hybride_parent_01']));
20 jpm 411
				}
412
			}
413
		}
414
 
415
		// Analyse des résultats
416
		if (count($noms_erreur) > 0) {
417
			$info['message']['entete'] = array('num_nom', 'hybride_parent_01 introuvable');
418
			$info['message']['lignes'] = $noms_erreur;
419
		} else {
420
			$info['resultat'] = true;
421
		}
64 jpm 422
		$noms_erreur = null;
20 jpm 423
 
30 jpm 424
		$this->traiterResultatTest($info);
20 jpm 425
	}
426
 
64 jpm 427
	private function testerHybrideParent01Syntaxe() {
30 jpm 428
		$info = array('nom' => 'hybride_parent_01 -> syntaxe',
20 jpm 429
			'description' => "Le champ hybride_parent_01 contient soit :\n".
164 delphine 430
								" - une valeur vide,\n".
431
								" - un nombre.",
20 jpm 432
			'resultat' => false);
433
 
434
		// Réalisation du test
435
		$noms_erreur = array();
64 jpm 436
		foreach ($this->noms as &$nom) {
20 jpm 437
			if ($nom['hybride_parent_01'] != '') {
438
				if (!$this->verifierNombre($nom['hybride_parent_01'])) {
42 jpm 439
					$noms_erreur[] = array($nom['num_nom'], $this->repererEspace($nom['hybride_parent_01']));
20 jpm 440
				}
441
			}
442
		}
443
 
444
		// Analyse des résultats
445
		if (count($noms_erreur) > 0) {
446
			$info['message']['entete'] = array('num_nom', 'hybride_parent_01 erroné');
447
			$info['message']['lignes'] = $noms_erreur;
448
		} else {
449
			$info['resultat'] = true;
450
		}
64 jpm 451
		$noms_erreur = null;
20 jpm 452
 
30 jpm 453
		$this->traiterResultatTest($info);
20 jpm 454
	}
455
 
64 jpm 456
	private function testerSynonymeOrthographiqueExistence() {
30 jpm 457
		$info = array('nom' => 'synonyme_orthographique -> existence',
163 delphine 458
			'description' => "Si le champ synonyme_orthographique contient un nombre alors il doit correspondre ".
164 delphine 459
								"à une valeur du champ num_nom.",
20 jpm 460
			'resultat' => false);
461
 
462
		// Réalisation du test
463
		$noms_erreur = array();
64 jpm 464
		foreach ($this->noms as &$nom) {
20 jpm 465
			if ($nom['synonyme_orthographique'] != '') {
64 jpm 466
				if (!isset($this->noms[$nom['synonyme_orthographique']])) {
20 jpm 467
					$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_orthographique']);
468
				}
469
			}
470
		}
471
 
472
		// Analyse des résultats
473
		if (count($noms_erreur) > 0) {
474
			$info['message']['entete'] = array('num_nom', 'synonyme_orthographique introuvable');
475
			$info['message']['lignes'] = $noms_erreur;
476
		} else {
477
			$info['resultat'] = true;
478
		}
64 jpm 479
		$noms_erreur = null;
20 jpm 480
 
30 jpm 481
		$this->traiterResultatTest($info);
20 jpm 482
	}
483
 
64 jpm 484
	private function testerSynonymeOrthographiqueSyntaxe() {
30 jpm 485
		$info = array('nom' => 'synonyme_orthographique -> syntaxe',
20 jpm 486
			'description' => "Le champ synonyme_orthographique contient soit :\n".
164 delphine 487
								" - une valeur vide,\n".
488
								" - un nombre.",
20 jpm 489
			'resultat' => false);
490
 
491
		// Réalisation du test
492
		$noms_erreur = array();
64 jpm 493
		foreach ($this->noms as $nom) {
20 jpm 494
			if ($nom['synonyme_orthographique'] != '') {
495
				if (!$this->verifierNombre($nom['synonyme_orthographique'])) {
496
					$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_orthographique']);
497
				}
498
			}
499
		}
500
 
501
		// Analyse des résultats
502
		if (count($noms_erreur) > 0) {
503
			$info['message']['entete'] = array('num_nom', 'synonyme_orthographique erroné');
504
			$info['message']['lignes'] = $noms_erreur;
505
		} else {
506
			$info['resultat'] = true;
507
		}
64 jpm 508
		$noms_erreur = null;
20 jpm 509
 
30 jpm 510
		$this->traiterResultatTest($info);
20 jpm 511
	}
512
 
64 jpm 513
	private function testerSynonymeMalAppliqueSyntaxe() {
30 jpm 514
		$info = array('nom' => 'synonyme_mal_applique -> syntaxe',
20 jpm 515
			'description' => "Le champ synonyme_mal_applique contient soit :\n".
163 delphine 516
			" - une valeur vide,\n".
517
			" - le chiffre 1.",
20 jpm 518
			'resultat' => false);
519
 
520
		// Réalisation du test
521
		$noms_erreur = array();
64 jpm 522
		foreach ($this->noms as &$nom) {
20 jpm 523
			if ($nom['synonyme_mal_applique'] != '') {
524
				if (!$this->verifierBooleen($nom['synonyme_mal_applique'])) {
525
					$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_mal_applique']);
526
				}
527
			}
528
		}
529
 
530
		// Analyse des résultats
531
		if (count($noms_erreur) > 0) {
532
			$info['message']['entete'] = array('num_nom', 'synonyme_mal_applique erroné');
533
			$info['message']['lignes'] = $noms_erreur;
534
		} else {
535
			$info['resultat'] = true;
536
		}
64 jpm 537
		$noms_erreur = null;
20 jpm 538
 
30 jpm 539
		$this->traiterResultatTest($info);
20 jpm 540
	}
541
 
158 delphine 542
 
64 jpm 543
	private function testerSynonymeDouteuxSyntaxe() {
30 jpm 544
		$info = array('nom' => 'synonyme_douteux -> syntaxe',
20 jpm 545
			'description' => "Le champ synonyme_douteux contient soit :\n".
163 delphine 546
			" - une valeur vide,\n".
547
			" - le chiffre 1.",
20 jpm 548
			'resultat' => false);
549
 
550
		// Réalisation du test
551
		$noms_erreur = array();
64 jpm 552
		foreach ($this->noms as &$nom) {
20 jpm 553
			if ($nom['synonyme_douteux'] != '') {
554
				if (!$this->verifierBooleen($nom['synonyme_douteux'])) {
555
					$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_douteux']);
556
				}
557
			}
558
		}
559
 
560
		// Analyse des résultats
561
		if (count($noms_erreur) > 0) {
562
			$info['message']['entete'] = array('num_nom', 'synonyme_douteux erroné');
563
			$info['message']['lignes'] = $noms_erreur;
564
		} else {
565
			$info['resultat'] = true;
566
		}
64 jpm 567
		$noms_erreur = null;
20 jpm 568
 
30 jpm 569
		$this->traiterResultatTest($info);
20 jpm 570
	}
571
 
158 delphine 572
	private function testerSynonymeDouteuxNumNomRetenu() {
573
		$info = array('nom' => 'synonyme_douteux -> présence num_nom_retenu',
574
			'description' => "Si le nom est un synonyme douteux, le champs num_nom_retenu doit être vide.",
575
			'resultat' => false);
576
 
577
		// Réalisation du test
578
		$noms_erreur = array();
579
		foreach ($this->noms as &$nom) {
580
			if ($nom['synonyme_douteux'] == 1 && $nom['num_nom_retenu'] != ' ') {
581
				$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_douteux'], $nom['num_nom_retenu']);
582
			}
583
		}
584
 
585
		// Analyse des résultats
586
		if (count($noms_erreur) > 0) {
587
			$info['message']['entete'] = array('num_nom', 'synonyme_douteux', 'num_nom_retenu');
588
			$info['message']['lignes'] = $noms_erreur;
589
		} else {
590
			$info['resultat'] = true;
591
		}
592
		$noms_erreur = null;
593
		$this->traiterResultatTest($info);
594
	}
595
 
596
 
64 jpm 597
	private function testerSynonymeProparteExistence() {
30 jpm 598
		$info = array('nom' => 'synonyme_proparte -> existence',
20 jpm 599
			'description' => "Si le champ synonyme_proparte contient un ou plusieurs nombres alors chacun d'entre eux ".
164 delphine 600
								"doit correspondre à une valeur du champ num_nom.",
20 jpm 601
			'resultat' => false);
602
 
603
		// Réalisation du test
604
		$noms_erreur = array();
64 jpm 605
		foreach ($this->noms as &$nom) {
20 jpm 606
			if ($nom['synonyme_proparte'] != '') {
607
				$num_nom_a_verifier = explode(',', $nom['synonyme_proparte']);
608
				$num_nom_en_erreur = array();
609
				foreach ($num_nom_a_verifier as $num_nom) {
64 jpm 610
					if (!isset($this->noms[$num_nom])) {
20 jpm 611
						$num_nom_en_erreur[] = $num_nom;
612
					}
613
				}
614
				if (count($nbre_en_erreur) > 0) {
615
					$noms_erreur[] = array($nom['num_nom'], implode(',', $num_nom_en_erreur));
616
				}
617
			}
618
		}
619
 
620
		// Analyse des résultats
621
		if (count($noms_erreur) > 0) {
622
			$info['message']['entete'] = array('num_nom', 'synonyme_proparte introuvable');
623
			$info['message']['lignes'] = $noms_erreur;
624
		} else {
625
			$info['resultat'] = true;
626
		}
64 jpm 627
		$noms_erreur = null;
20 jpm 628
 
30 jpm 629
		$this->traiterResultatTest($info);
20 jpm 630
	}
631
 
64 jpm 632
	private function testerSynonymeProparteSyntaxe() {
30 jpm 633
		$info = array('nom' => 'synonyme_proparte -> syntaxe',
20 jpm 634
			'description' => "Le champ synonyme_proparte contient soit :\n".
163 delphine 635
			" - une valeur vide,\n".
636
			" - un nombre,\n".
637
			" - une suite de nombres séparés par des virgules.",
20 jpm 638
			'resultat' => false);
639
 
640
		// Réalisation du test
641
		$noms_erreur = array();
64 jpm 642
		foreach ($this->noms as &$nom) {
20 jpm 643
			if ($nom['synonyme_proparte'] != '') {
644
				if (!$this->verifierNombreSuite($nom['synonyme_proparte'])) {
645
					$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_proparte']);
646
				}
647
			}
648
		}
649
 
650
		// Analyse des résultats
651
		if (count($noms_erreur) > 0) {
652
			$info['message']['entete'] = array('num_nom', 'synonyme_proparte erroné');
653
			$info['message']['lignes'] = $noms_erreur;
654
		} else {
655
			$info['resultat'] = true;
656
		}
64 jpm 657
		$noms_erreur = null;
20 jpm 658
 
30 jpm 659
		$this->traiterResultatTest($info);
20 jpm 660
	}
661
 
64 jpm 662
	private function testerBasionymeExistence() {
30 jpm 663
		$info = array('nom' => 'basionyme -> existence',
20 jpm 664
			'description' => "Si le champ basionyme contient un nombre alors il doit correspondre à une valeur du champ ".
164 delphine 665
								"num_nom.",
20 jpm 666
			'resultat' => false);
667
 
668
		// Réalisation du test
669
		$noms_erreur = array();
64 jpm 670
		foreach ($this->noms as &$nom) {
20 jpm 671
			if ($nom['basionyme'] != '') {
64 jpm 672
				if (!isset($this->noms[$nom['basionyme']])) {
20 jpm 673
					$noms_erreur[] = array($nom['num_nom'], $nom['basionyme']);
674
				}
675
			}
676
		}
677
 
678
		// Analyse des résultats
679
		if (count($noms_erreur) > 0) {
680
			$info['message']['entete'] = array('num_nom', 'basionyme introuvable');
681
			$info['message']['lignes'] = $noms_erreur;
682
		} else {
683
			$info['resultat'] = true;
684
		}
64 jpm 685
		$noms_erreur = null;
20 jpm 686
 
30 jpm 687
		$this->traiterResultatTest($info);
20 jpm 688
	}
689
 
64 jpm 690
	private function testerBasionymeSyntaxe() {
30 jpm 691
		$info = array('nom' => 'basionyme -> syntaxe',
20 jpm 692
			'description' => "Le champ basionyme contient :\n".
163 delphine 693
								" - une valeur vide,\n".
694
								" - un nombre.",
20 jpm 695
			'resultat' => false);
696
 
697
		// Réalisation du test
698
		$noms_erreur = array();
64 jpm 699
		foreach ($this->noms as &$nom) {
20 jpm 700
			if ($nom['basionyme'] != '') {
701
				if (!$this->verifierNombre($nom['basionyme'])) {
702
					$noms_erreur[] = array($nom['num_nom'], $nom['basionyme']);
703
				}
704
			}
705
		}
706
 
707
		// Analyse des résultats
708
		if (count($noms_erreur) > 0) {
709
			$info['message']['entete'] = array('num_nom', 'basionyme erroné');
710
			$info['message']['lignes'] = $noms_erreur;
711
		} else {
712
			$info['resultat'] = true;
713
		}
64 jpm 714
		$noms_erreur = null;
20 jpm 715
 
30 jpm 716
		$this->traiterResultatTest($info);
20 jpm 717
	}
718
 
64 jpm 719
	private function testerHomonymieExistence() {
30 jpm 720
		$info = array('nom' => 'homonyme -> existence',
20 jpm 721
			'description' => "Si le champ homonyme contient «1» alors plusieurs noms doivent posséder la même valeur ".
164 delphine 722
								"dans le champ nom_sci.",
20 jpm 723
			'resultat' => false);
724
 
64 jpm 725
		$noms_homonymie = $this->classerNomsParNomComplet();
726
 
20 jpm 727
		// Réalisation du test
728
		$noms_erreur = array();
64 jpm 729
		foreach ($this->noms as &$nom) {
20 jpm 730
			if ($nom['homonyme'] != '0' && $nom['homonyme'] != '') {
149 jpm 731
				if ($noms_homonymie[$nom['nom_sci']] <= 1) {
732
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_sci']);
20 jpm 733
				}
734
			}
735
		}
64 jpm 736
		$noms_homonymie = null;
20 jpm 737
 
738
		// Analyse des résultats
739
		if (count($noms_erreur) > 0) {
740
			$info['message']['entete'] = array('num_nom', 'homonyme introuvable');
741
			$info['message']['lignes'] = $noms_erreur;
742
		} else {
743
			$info['resultat'] = true;
744
		}
64 jpm 745
		$noms_erreur = null;
20 jpm 746
 
30 jpm 747
		$this->traiterResultatTest($info);
20 jpm 748
	}
749
 
64 jpm 750
	private function testerHomonymieSyntaxe() {
30 jpm 751
		$info = array('nom' => 'homonyme -> syntaxe',
20 jpm 752
			'description' => "Le champ homonyme contient :\n".
163 delphine 753
				" - une valeur vide,\n".
754
				" - le chiffre 1.",
20 jpm 755
			'resultat' => false);
756
 
757
		// Réalisation du test
758
		$noms_erreur = array();
64 jpm 759
		foreach ($this->noms as &$nom) {
20 jpm 760
			if ($nom['homonyme'] != '') {
761
				if (!$this->verifierBooleen($nom['homonyme'])) {
762
					$noms_erreur[] = array($nom['num_nom'], $nom['homonyme']);
763
				}
764
			}
765
		}
766
 
767
		// Analyse des résultats
768
		if (count($noms_erreur) > 0) {
769
			$info['message']['entete'] = array('num_nom', 'homonyme erroné');
770
			$info['message']['lignes'] = $noms_erreur;
771
		} else {
772
			$info['resultat'] = true;
773
		}
64 jpm 774
		$noms_erreur = null;
20 jpm 775
 
30 jpm 776
		$this->traiterResultatTest($info);
20 jpm 777
	}
778
 
64 jpm 779
	private function testerBiblioOrigineSyntaxe() {
30 jpm 780
		$info = array('nom' => 'biblio_origine -> syntaxe',
20 jpm 781
			'description' => "Le champ biblio_origine se compose de plusieurs parties séparées par des caractères ".
782
			"précis qui sont dans l'ordre de gauche à droite :\n".
163 delphine 783
			" - éventuellement, le mot « in » suivi d'un intitulé auteur (utilisé pour indiquer l'intitulé auteur de ".
784
			"l'ouvrage dans lequel la publication est parue),\n".
785
			" - point-virgule « ; » (si l'info précédent a été renseignée),\n".
786
			" - abréviation, ou nom, de l'ouvrage ou de la revue selon le standard en vigueur dans le code du nom. ".
787
			"Cette information ne doit pas contenir de caractère virgule « , »,\n".
788
			" - virgule « , »,\n".
789
			" - informations permettant d'identifier plus précisément le document contenant le nom... ".
790
			"(par exemple, l'éditeur, le tome, le numéro d'édition, le volume...) séparées par des virgules ou d'autres ".
20 jpm 791
			"caractères sauf deux points « : ».\n".
163 delphine 792
			" - deux points « : »,\n".
793
			" - numéro(s) de la page contenant la publication du nom ou de l'ensemble de pages (première et dernière ".
794
			"pages de l'ensemble séparées par un tiret « - »). Quelques fois des numéros ou d'autres informations indiquant ".
795
			"la position du nom dans le document. Le tiret « - » doit toujours servir à séparer un ensemble.",
20 jpm 796
			'resultat' => false);
797
 
798
		// Réalisation du test
799
		$noms_erreur = array();
64 jpm 800
		foreach ($this->noms as &$nom) {
20 jpm 801
			if ($nom['biblio_origine'] != '') {
802
				if (!$this->verifierBiblioOrigine($nom['biblio_origine'])) {
803
					$biblio_traite = $this->repererEspace($nom['biblio_origine']);
804
					$noms_erreur[] = array($nom['num_nom'], $biblio_traite);
805
				}
806
			}
807
		}
808
 
809
		// Analyse des résultats
810
		if (count($noms_erreur) > 0) {
811
			$info['message']['entete'] = array('num_nom', 'biblio_origine erroné');
812
			$info['message']['lignes'] = $noms_erreur;
813
		} else {
814
			$info['resultat'] = true;
815
		}
64 jpm 816
		$noms_erreur = null;
20 jpm 817
 
30 jpm 818
		$this->traiterResultatTest($info);
20 jpm 819
	}
820
 
64 jpm 821
	private function testerAnneeSyntaxe() {
30 jpm 822
		$info = array('nom' => 'annee -> syntaxe',
20 jpm 823
			'description' => "Le champ annee doit :\n".
163 delphine 824
			" - contenir un nombre de 4 chiffres,\n".
825
			" - être supérieur ou égal à 1753.",
20 jpm 826
			'resultat' => false);
827
 
828
		// Réalisation du test
829
		$noms_erreur = array();
64 jpm 830
		foreach ($this->noms as &$nom) {
20 jpm 831
			if ($nom['annee'] != '') {
832
				if (!$this->verifierAnnee($nom['annee'])) {
833
					$noms_erreur[] = array($nom['num_nom'], $nom['annee']);
834
				}
835
			}
836
		}
837
 
838
		// Analyse des résultats
839
		if (count($noms_erreur) > 0) {
840
			$info['message']['entete'] = array('num_nom', 'annee erroné');
841
			$info['message']['lignes'] = $noms_erreur;
842
		} else {
843
			$info['resultat'] = true;
844
		}
64 jpm 845
		$noms_erreur = null;
20 jpm 846
 
30 jpm 847
		$this->traiterResultatTest($info);
20 jpm 848
	}
849
 
64 jpm 850
	private function testerAuteurSyntaxe() {
30 jpm 851
		$info = array('nom' => 'auteur -> syntaxe',
20 jpm 852
			'description' => "Le champ auteur doit :\n".
163 delphine 853
			" - contenir l'intitulé complet des noms de l'auteur, ou des auteurs, ayant publié à l'origine la combinaison latine courante.\n".
854
    		" - OU débuter par le mot « sensu » et contenir l'intitulé complet des noms de l'auteur, ou des auteurs, ".
855
			"ayant publié un nom dont la description ne correspond pas à celle de l'auteur, ou des auteurs, d'origine.\n".
20 jpm 856
			" - se composer de caractères alphabétiques (A-Z, a-z), incluant les signes diacritiques, le symbole point (.), les paires de parenthèses ( () ), les apostrophes, l'esperluette (&) et l'espace ( ).\n".
857
			" - contenir, si nécessaire, des abréviations de noms d'auteurs respectant les standards.\n".
858
			" - contenir une translittération des noms d'alphabet cyrillique, arabe, chinois... en alphabet latin.\n".
859
			" - inclure entre parenthèses l'intitulé des noms de l'auteur ou des auteurs ayant publié le basionyme.\n".
860
			" - toujours utiliser l'esperluette (&) à la place du mot « et » pour séparer les noms d'auteurs.\n".
861
			" - conformément à la recommandation 46C.2 du CINB, si une un citation comprend plus de deux auteurs, ".
862
			"elle devrait être limitée au nom du premier, suivi de « & al.».\n",
863
			'resultat' => false);
864
 
865
		// Réalisation du test
866
		$noms_erreur = array();
64 jpm 867
		foreach ($this->noms as &$nom) {
20 jpm 868
			if ($nom['auteur'] != '') {
869
				if (!$this->verifierAuteur($nom['auteur'])) {
870
					$intitule_traite = $this->repererEspace($nom['auteur']);
871
					$noms_erreur[] = array($nom['num_nom'], $intitule_traite);
872
				}
873
			}
874
		}
875
 
876
		// Analyse des résultats
877
		if (count($noms_erreur) > 0) {
878
			$info['message']['entete'] = array('num_nom', 'auteur erroné');
879
			$info['message']['lignes'] = $noms_erreur;
880
		} else {
881
			$info['resultat'] = true;
882
		}
64 jpm 883
		$noms_erreur = null;
20 jpm 884
 
30 jpm 885
		$this->traiterResultatTest($info);
20 jpm 886
	}
887
 
64 jpm 888
	private function testerNomCommercialSyntaxe() {
30 jpm 889
		$info = array('nom' => 'nom_commercial -> syntaxe',
20 jpm 890
			'description' => "Le champ nom_commercial doit contenir un nom commercial conforme aux règles du ".
891
				"Code Internationnal de Nomenclature des Plantes Cultivées (CINPC) ".
892
				"qui se compose de caractères majuscules (A-Z) incluant des signes diacritiques et des espaces.\n",
893
			'resultat' => false);
894
 
895
		// Réalisation du test
896
		$noms_erreur = array();
64 jpm 897
		foreach ($this->noms as &$nom) {
20 jpm 898
			if ($nom['nom_commercial'] != '') {
899
				if (!$this->verifierNomCommercial($nom['nom_commercial'])) {
900
					$epithete_traite = $this->repererEspace($nom['nom_commercial']);
901
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
902
				}
903
			}
904
		}
905
 
906
		// Analyse des résultats
907
		if (count($noms_erreur) > 0) {
908
			$info['message']['entete'] = array('num_nom', 'cultivar erroné');
909
			$info['message']['lignes'] = $noms_erreur;
910
		} else {
911
			$info['resultat'] = true;
912
		}
64 jpm 913
		$noms_erreur = null;
20 jpm 914
 
30 jpm 915
		$this->traiterResultatTest($info);
20 jpm 916
	}
917
 
64 jpm 918
	private function testerNomCommercialPresenceCultivar() {
30 jpm 919
		$info = array('nom' => 'nom_commercial -> groupe_cultivar OU cultivar non vide',
163 delphine 920
			'description' => "Si le champ nom_commercial contient un nom commercial alors le champ cultivar OU ".
20 jpm 921
				"cultivar_groupe ne doit pas être vide.",
922
			'resultat' => false);
923
 
924
		// Réalisation du test
925
		$noms_erreur = array();
64 jpm 926
		foreach ($this->noms as &$nom) {
927
			if ((isset($nom['nom_commercial']) && $nom['nom_commercial'] != '') && ($nom['cultivar'] == '' && $nom['cultivar_groupe'] == '')) {
149 jpm 928
				$noms_erreur[] = array($nom['num_nom'], $nom['nom_sci']);
20 jpm 929
			}
930
		}
931
 
932
		// Analyse des résultats
933
		if (count($noms_erreur) > 0) {
934
			$info['message']['entete'] = array('num_nom', 'nom_commercial sans cultivar ou cultivar_groupe');
935
			$info['message']['lignes'] = $noms_erreur;
936
		} else {
937
			$info['resultat'] = true;
938
		}
64 jpm 939
		$noms_erreur = null;
20 jpm 940
 
30 jpm 941
		$this->traiterResultatTest($info);
20 jpm 942
	}
943
 
64 jpm 944
	private function testerCultivarSyntaxe() {
30 jpm 945
		$info = array('nom' => 'cultivar -> syntaxe',
20 jpm 946
			'description' => "Le champ cultivar_groupe doit contenir :\n".
163 delphine 947
				" - un nom de cultivar conforme aux règles du Code Internationnal de Nomenclature \n".
948
				"   des Plantes Cultivées (CINPC), c.-à-d. composer de caractères alphanumériques \n".
949
				"   (A-Z,a-z et 0-9) incluant signes diacritiques et marques de ponctuations.\n".
950
				" - un nom en alphabet latin, ce qui implique une translittération des noms d'alphabet \n".
951
				"   cyrillique, arabe, chinois...\n".
952
				" - une lettre majuscule obligatoire pour le premier caractère du premier mot et pour \n".
953
				"   les autres mots importants mais pas pour les mots mineurs.\n".
20 jpm 954
				"Ne doit pas contenir :\n".
955
				" - cv., convar. ou de guillemets simples (').\n",
956
			'resultat' => false);
957
 
958
		// Réalisation du test
959
		$noms_erreur = array();
64 jpm 960
		foreach ($this->noms as &$nom) {
20 jpm 961
			if ($nom['cultivar'] != '') {
962
				if (!$this->verifierEpitheteCultivar($nom['cultivar'])) {
963
					$epithete_traite = $this->repererEspace($nom['cultivar']);
964
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
965
				}
966
			}
967
		}
968
 
969
		// Analyse des résultats
970
		if (count($noms_erreur) > 0) {
971
			$info['message']['entete'] = array('num_nom', 'cultivar erroné');
972
			$info['message']['lignes'] = $noms_erreur;
973
		} else {
974
			$info['resultat'] = true;
975
		}
64 jpm 976
		$noms_erreur = null;
20 jpm 977
 
30 jpm 978
		$this->traiterResultatTest($info);
20 jpm 979
	}
980
 
64 jpm 981
	private function testerCultivarRang() {
30 jpm 982
		$info = array('nom' => "cultivar -> rang >= {$this->manuel['rang_genre']}",
164 delphine 983
			'description' => "Si le champ cultivar n'est pas vide alors le rang du nom doit être supérieur ou égal à ".
984
								"{$this->manuel['rang_genre']}.",
20 jpm 985
			'resultat' => false);
986
 
987
		// Réalisation du test
988
		$noms_erreur = array();
64 jpm 989
		foreach ($this->noms as &$nom) {
20 jpm 990
			if ($nom['cultivar'] != '') {
991
				if ($nom['rang'] < $this->manuel['rang_genre']) {
149 jpm 992
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
20 jpm 993
				}
994
			}
995
		}
996
 
997
		// Analyse des résultats
998
		if (count($noms_erreur) > 0) {
149 jpm 999
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
20 jpm 1000
			$info['message']['lignes'] = $noms_erreur;
1001
		} else {
1002
			$info['resultat'] = true;
1003
		}
64 jpm 1004
		$noms_erreur = null;
20 jpm 1005
 
30 jpm 1006
		$this->traiterResultatTest($info);
20 jpm 1007
	}
1008
 
64 jpm 1009
	private function testerGroupeCultivarSyntaxe() {
30 jpm 1010
		$info = array('nom' => 'cultivar_groupe -> syntaxe',
20 jpm 1011
			'description' => "Le champ cultivar_groupe doit contenir un nom de groupe de cultivar conforme aux règles ".
163 delphine 1012
				"du code des plantes cultivées, c.-à-d. composer de caractères alphanumériques (A-Z,a-z et 0-9) incluant ".
20 jpm 1013
				"signes diacritiques et marques de ponctuations.\n".
1014
				"Il ne doit pas contenir le mot Groupe, l'abbréviation «gp» ou des parenthèses.\n".
163 delphine 1015
				"Il peut se terminer par l'abréviation «gx» pour distinguer les groupes des grex.",
20 jpm 1016
			'resultat' => false);
1017
 
1018
		// Réalisation du test
1019
		$noms_erreur = array();
64 jpm 1020
		foreach ($this->noms as &$nom) {
20 jpm 1021
			if ($nom['cultivar_groupe'] != '') {
1022
				if (!$this->verifierEpitheteGroupeCultivar($nom['cultivar_groupe'])) {
1023
					$epithete_traite = $this->repererEspace($nom['cultivar_groupe']);
1024
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1025
				}
1026
			}
1027
		}
1028
 
1029
		// Analyse des résultats
1030
		if (count($noms_erreur) > 0) {
1031
			$info['message']['entete'] = array('num_nom', 'cultivar_groupe erroné');
1032
			$info['message']['lignes'] = $noms_erreur;
1033
		} else {
1034
			$info['resultat'] = true;
1035
		}
64 jpm 1036
		$noms_erreur = null;
20 jpm 1037
 
30 jpm 1038
		$this->traiterResultatTest($info);
20 jpm 1039
	}
1040
 
64 jpm 1041
	private function testerGroupeCultivarRang() {
30 jpm 1042
		$info = array('nom' => "cultivar_groupe -> rang >= {$this->manuel['rang_genre']}",
164 delphine 1043
			'description' => "Si le champ cultivar_groupe n'est pas vide alors le rang du nom doit être supérieur ou ".
1044
								"égal à {$this->manuel['rang_genre']}.",
20 jpm 1045
			'resultat' => false);
1046
 
1047
		// Réalisation du test
1048
		$noms_erreur = array();
64 jpm 1049
		foreach ($this->noms as &$nom) {
20 jpm 1050
			if ($nom['cultivar_groupe'] != '') {
1051
				if ($nom['rang'] < $this->manuel['rang_genre']) {
149 jpm 1052
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
20 jpm 1053
				}
1054
			}
1055
		}
1056
 
1057
		// Analyse des résultats
1058
		if (count($noms_erreur) > 0) {
149 jpm 1059
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
20 jpm 1060
			$info['message']['lignes'] = $noms_erreur;
1061
		} else {
1062
			$info['resultat'] = true;
1063
		}
64 jpm 1064
		$noms_erreur = null;
20 jpm 1065
 
30 jpm 1066
		$this->traiterResultatTest($info);
20 jpm 1067
	}
1068
 
64 jpm 1069
	private function testerEpitheteInfraSpEspaces() {
30 jpm 1070
		$info = array('nom' => 'epithete_infra_sp -> espaces en trop',
163 delphine 1071
			'description' => "Le champ epithete_infra_sp ne doit pas contenir d'espace avant ou après le nom.\n".
1072
				"Si des espaces sont compris dans la valeur du champ, il ne doit pas en avoir plusieurs consécutifs.",
20 jpm 1073
			'resultat' => false);
1074
 
1075
		// Réalisation du test
1076
		$noms_erreur = array();
64 jpm 1077
		foreach ($this->noms as &$nom) {
20 jpm 1078
			if ($nom['epithete_infra_sp'] != '') {
1079
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_sp'])) {
1080
					$epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
1081
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1082
				}
1083
			}
1084
		}
1085
 
1086
		// Analyse des résultats
1087
		if (count($noms_erreur) > 0) {
1088
			$info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
1089
			$info['message']['lignes'] = $noms_erreur;
1090
		} else {
1091
			$info['resultat'] = true;
1092
		}
64 jpm 1093
		$noms_erreur = null;
20 jpm 1094
 
30 jpm 1095
		$this->traiterResultatTest($info);
20 jpm 1096
	}
1097
 
64 jpm 1098
	private function testerEpitheteInfraSpSyntaxe() {
30 jpm 1099
		$info = array('nom' => 'epithete_infra_sp -> syntaxe',
20 jpm 1100
			'description' => "Le champ epithete_infra_sp peut contenir :\n".
163 delphine 1101
			 	" - un mot unique composé de lettres minuscules, avec ou sans tréma (¨), et de tirets (-). \n".
164 delphine 1102
				"   Il commence par une lettre minuscule (avec ou sans tréma).\n".
1103
				"   Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
163 delphine 1104
				" - une formule d'hybridité composée d'une série de noms d'espèce ou d'infra espèce \n".
164 delphine 1105
				"   (au moins 2) séparés entre eux par la lettre x entourée de caractères espaces.",
20 jpm 1106
			'resultat' => false);
1107
 
1108
		// Réalisation du test
1109
		$noms_erreur = array();
64 jpm 1110
		foreach ($this->noms as &$nom) {
20 jpm 1111
			if ($nom['epithete_infra_sp'] != '') {
1112
				$mots = explode(' ', $nom['epithete_infra_sp']);
1113
				foreach ($mots as $mot) {
1114
					if (!(preg_match('/^[+x]$/', $mot) || $this->verifierTypeEpithete($mot)|| $this->verifierEpitheteSp($mot))) {
1115
						$epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
1116
						$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1117
					}
1118
				}
1119
			}
1120
		}
1121
 
1122
		// Analyse des résultats
1123
		if (count($noms_erreur) > 0) {
1124
			$info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
1125
			$info['message']['lignes'] = $noms_erreur;
1126
		} else {
1127
			$info['resultat'] = true;
1128
		}
64 jpm 1129
		$noms_erreur = null;
20 jpm 1130
 
30 jpm 1131
		$this->traiterResultatTest($info);
20 jpm 1132
	}
1133
 
64 jpm 1134
	private function testerEpitheteInfraSpRang() {
30 jpm 1135
		$info = array('nom' => "epithete_infra_sp -> rang > {$this->manuel['rang_sp']}",
20 jpm 1136
			'description' => "Si le champ epithete_infra_sp n'est pas vide alors le rang du nom doit être supérieur à {$this->manuel['rang_sp']}.",
1137
			'resultat' => false);
1138
 
1139
		// Réalisation du test
1140
		$noms_erreur = array();
64 jpm 1141
		foreach ($this->noms as &$nom) {
20 jpm 1142
			if ($nom['epithete_infra_sp'] != '') {
1143
				if ($nom['rang'] < $this->manuel['rang_sp']) {
149 jpm 1144
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
20 jpm 1145
				}
1146
			}
1147
		}
1148
 
1149
		// Analyse des résultats
1150
		if (count($noms_erreur) > 0) {
149 jpm 1151
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
20 jpm 1152
			$info['message']['lignes'] = $noms_erreur;
1153
		} else {
1154
			$info['resultat'] = true;
1155
		}
64 jpm 1156
		$noms_erreur = null;
20 jpm 1157
 
30 jpm 1158
		$this->traiterResultatTest($info);
20 jpm 1159
	}
1160
 
64 jpm 1161
	private function testerTypeEpitheteEspaces() {
30 jpm 1162
		$info = array('nom' => 'type_epithete -> espaces en trop',
20 jpm 1163
			'description' => "Le champ type_epithete ne doit pas contenir d'espace.",
1164
			'resultat' => false);
1165
 
1166
		// Réalisation du test
1167
		$noms_erreur = array();
64 jpm 1168
		foreach ($this->noms as &$nom) {
20 jpm 1169
			if ($nom['type_epithete'] != '') {
1170
				if (preg_match('/\s+/', $nom['type_epithete'])) {
1171
					$valeur_traitee = $this->repererEspace($nom['epithete_sp']);
1172
					$noms_erreur[] = array($nom['num_nom'], $valeur_traitee);
1173
				}
1174
			}
1175
		}
1176
 
1177
		// Analyse des résultats
1178
		if (count($noms_erreur) > 0) {
1179
			$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
1180
			$info['message']['lignes'] = $noms_erreur;
1181
		} else {
1182
			$info['resultat'] = true;
1183
		}
1184
 
30 jpm 1185
		$this->traiterResultatTest($info);
20 jpm 1186
	}
1187
 
64 jpm 1188
	private function testerTypeEpitheteSyntaxe() {
30 jpm 1189
		$info = array('nom' => 'type_epithete -> syntaxe',
163 delphine 1190
			'description' => "Le champ type_epithete doit contenir un mot unique composé de lettres minuscules, sans ".
1191
				" accents, et de tirets (-). Il commence par une lettre minuscule sans accent.",
20 jpm 1192
			'resultat' => false);
1193
 
1194
		// Réalisation du test
1195
		$noms_erreur = array();
64 jpm 1196
		foreach ($this->noms as &$nom) {
20 jpm 1197
			if ($nom['type_epithete'] != '') {
1198
				if (!$this->verifierTypeEpithete($nom['type_epithete'])) {
1199
					$noms_erreur[] = array($nom['num_nom'],  $nom['type_epithete']);
1200
				}
1201
			}
1202
		}
1203
 
1204
		// Analyse des résultats
1205
		if (count($noms_erreur) > 0) {
1206
			$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
1207
			$info['message']['lignes'] = $noms_erreur;
1208
		} else {
1209
			$info['resultat'] = true;
1210
		}
1211
 
30 jpm 1212
		$this->traiterResultatTest($info);
20 jpm 1213
	}
1214
 
64 jpm 1215
	private function testerTypeEpitheteHybridite() {
30 jpm 1216
		$info = array('nom' => 'type_epithete -> hybridité',
20 jpm 1217
			'description' => "Le champ type_epithete ne doit pas contenir de préfixe indiquant l'hybridité comme : \n".
1218
				" - «n-» \n".
1219
				" - «notho-» \n",
1220
			'resultat' => false);
1221
 
1222
		// Réalisation du test
1223
		$noms_erreur = array();
64 jpm 1224
		foreach ($this->noms as &$nom) {
20 jpm 1225
			if ($nom['type_epithete'] != '') {
1226
				if (preg_match('/^(?:n-|notho-)/', $nom['type_epithete'])) {
1227
					$noms_erreur[] = array($nom['num_nom'], $nom['type_epithete']);
1228
				}
1229
			}
1230
		}
1231
 
1232
		// Analyse des résultats
1233
		if (count($noms_erreur) > 0) {
1234
			$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
1235
			$info['message']['lignes'] = $noms_erreur;
1236
		} else {
1237
			$info['resultat'] = true;
1238
		}
1239
 
30 jpm 1240
		$this->traiterResultatTest($info);
20 jpm 1241
	}
1242
 
1243
	private function testerNombreDeChamps($colonnes) {
30 jpm 1244
		$info = array('nom' => 'Structure -> nombre de champs',
20 jpm 1245
			'description' => 'Le nombre de champs présent dans la table doit être supérieur ou égal à 35.',
1246
			'resultat' => false);
1247
 
1248
		$nbre_colonnes = count($colonnes);
30 jpm 1249
		$info['message'] = $nbre_colonnes;
20 jpm 1250
		if ($nbre_colonnes >= 35) {
1251
			$info['resultat'] = true;
1252
		}
30 jpm 1253
		$this->traiterResultatTest($info);
64 jpm 1254
		return ($info['resultat'] ? '1' : '0');
20 jpm 1255
	}
1256
 
1257
	private function testerNomDesChamps($colonnes) {
30 jpm 1258
		$info = array('nom' => 'Structure -> noms des champs',
163 delphine 1259
			'description' => 'Les noms des champs de la table contenant le référentiel doivent être conformes à ceux '.
1260
								'définis par le manuel technique.',
20 jpm 1261
			'resultat' => false);
1262
 
1263
		$champs_attendus = explode(',', $this->manuel['champs']);
1264
		$champs_presents = array();
1265
		foreach ($colonnes as $colonne) {
1266
			$champs_presents[$colonne['Field']] = $colonne;
1267
		}
1268
 
1269
		$ok = true;
1270
		$champs_manquant = array();
1271
		foreach ($champs_attendus as $champ_attendu) {
1272
			if (!isset($champs_presents[$champ_attendu])) {
1273
				$champs_manquant[] = $champ_attendu;
1274
				$ok = false;
1275
			}
1276
		}
1277
		$info['resultat'] = $ok;
1278
		if (!$ok) {
164 delphine 1279
			$info['message'] = 'Champs manquants : '.implode(', ', $champs_manquant).'.';
20 jpm 1280
		}
1281
 
30 jpm 1282
		$this->traiterResultatTest($info);
64 jpm 1283
		return ($info['resultat'] ? '1' : '0');
20 jpm 1284
	}
1285
 
1286
	private function testerTypeDesChamps($colonnes) {
30 jpm 1287
		$info = array('nom' => 'Structure -> types des champs',
163 delphine 1288
			'description' => 'Les types des champs de la table contenant le référentiel doivent être conformes à ceux '.
1289
								'définis par le manuel technique.',
20 jpm 1290
			'resultat' => false);
1291
 
1292
		$champs_attendus = explode(',', $this->manuel['champs_type']);
1293
		$champs_presents = array();
1294
		foreach ($colonnes as $colonne) {
1295
			$champs_presents[$colonne['Field']] = $colonne['Type'];
1296
		}
1297
 
1298
		// Recercherche des erreurs
1299
		$champs_erreur = array();
1300
		foreach ($champs_attendus as $champ_attendu) {
51 jpm 1301
			list($champ_attendu_nom, $champ_attendu_type_taille) = explode('=', trim($champ_attendu));
1302
			list($champ_attendu_type, $champ_attendu_taille) = explode('|', trim($champ_attendu_type_taille));
1303
 
20 jpm 1304
			if (isset($champs_presents[$champ_attendu_nom])) {
1305
				$champs_present_type = $champs_presents[$champ_attendu_nom];
1306
 
1307
				if (($champ_attendu_type == 'VARCHAR' && strstr($champs_present_type, 'varchar') === false)
1308
					|| ($champ_attendu_type == 'TEXT' && strstr($champs_present_type, 'text') === false)
1309
					|| ($champ_attendu_type == 'INT' && strstr($champs_present_type, 'int') === false)
1310
					|| ($champ_attendu_type == 'BOOL' && preg_match('/(?:bool|boolean|tinyint\(1\))/i', $champs_present_type) === false)) {
1311
					$champs_erreur[] = $champ_attendu." vaut ".$champs_present_type;
1312
				}
1313
			}
1314
		}
1315
 
1316
		// Analyse des résultats
1317
		if (count($champs_erreur) > 0) {
164 delphine 1318
			$info['message'] = "Champs n'ayant pas un type conforme : ".implode(', ', $champs_erreur).'.';
20 jpm 1319
		} else {
1320
			$info['resultat'] = true;
1321
		}
1322
 
30 jpm 1323
		$this->traiterResultatTest($info);
64 jpm 1324
		return ($info['resultat'] ? '1' : '0');
20 jpm 1325
	}
1326
 
1327
	private function testerTailleDesChamps($colonnes, $analyses) {
30 jpm 1328
		$info = array('nom' => 'Structure -> champs tronqués',
163 delphine 1329
			'description' => "Evalue le risque que des données de type texte aient pu être tronquées lors de leur insertion.\n".
45 jpm 1330
				"Un résultat de type KO ne signifie pas forcément un problème à résoudre mais attire l'attention du coordinateur ".
1331
				"sur un problème éventuel.",
20 jpm 1332
			'resultat' => false);
1333
 
1334
		$tailles_champs_maxi = array();
1335
		foreach ($colonnes as $colonne) {
1336
			if (preg_match('/^varchar\(([0-9]+)\)$/', $colonne['Type'], $match)) {
1337
				$tailles_champs_maxi[$colonne['Field']] = $match[1];
1338
			}
1339
		}
1340
 
1341
		$tailles_trouvees = array();
1342
		foreach ($analyses as $analyse) {
1343
			if (preg_match('/\.([^.]+)$/', $analyse['Field_name'], $match)) {
1344
				$tailles_trouvees[$match[1]] = $analyse['Max_length'];
1345
			}
1346
		}
1347
 
1348
		$champs_erreur = array();
1349
		$champs_attendus = explode(',', $this->manuel['champs']);
1350
		foreach ($champs_attendus as $champ_attendu) {
1351
			if (isset($tailles_champs_maxi[$champ_attendu]) && isset($tailles_trouvees[$champ_attendu])) {
1352
				if ($tailles_champs_maxi[$champ_attendu] == $tailles_trouvees[$champ_attendu]) {
1353
					$champs_erreur[] = $champ_attendu;
1354
				}
1355
			}
1356
		}
1357
 
1358
		// Analyse des résultats
1359
		if (count($champs_erreur) > 0) {
164 delphine 1360
			$info['message'] = "Champs possédant des enregistrements qui atteignent la taille maximum autorisée : ".
1361
								implode(', ', $champs_erreur).'.';
20 jpm 1362
		} else {
1363
			$info['resultat'] = true;
1364
		}
1365
 
30 jpm 1366
		$this->traiterResultatTest($info);
20 jpm 1367
	}
1368
 
1369
	private function testerNumNomClePrimaire($colonnes) {
30 jpm 1370
		$info = array('nom' => 'Structure -> num_nom est clé primaire',
20 jpm 1371
			'description' => "Vérifie que le champ num_nom est bien la clé primaire de la table.",
1372
			'resultat' => false);
1373
 
1374
		foreach ($colonnes as $colonne) {
1375
			if ($colonne['Field'] == 'num_nom' && $colonne['Key'] == 'PRI') {
1376
				$info['resultat'] = true;
1377
			}
1378
		}
1379
 
30 jpm 1380
		$this->traiterResultatTest($info);
64 jpm 1381
		return ($info['resultat'] ? '1' : '0');
20 jpm 1382
	}
1383
 
64 jpm 1384
	private function testerNumNomSuperieurAZero() {
30 jpm 1385
		$info = array('nom' => 'num_nom -> supérieur à 0',
20 jpm 1386
			'description' => "Le champ num_nom doit contenir des nombres entiers supérieurs à 0.",
1387
			'resultat' => false);
1388
 
1389
		// Réalisation du test
1390
		$noms_erreur = array();
64 jpm 1391
		foreach ($this->noms as &$nom) {
20 jpm 1392
			if ($nom['num_nom'] <= 0) {
1393
				$noms_erreur[] = $nom['num_nom'];
1394
			}
1395
		}
1396
 
1397
		// Analyse des résultats
1398
		if (count($noms_erreur) > 0) {
164 delphine 1399
			$info['message'] = count($noms_erreur)." enregistrements contiennent dans le champ num_nom une valeur ".
1400
								"inférieure ou égale à 0.";
20 jpm 1401
		} else {
1402
			$info['resultat'] = true;
1403
		}
1404
 
30 jpm 1405
		$this->traiterResultatTest($info);
20 jpm 1406
	}
1407
 
64 jpm 1408
	private function testerNumNomRetenuSuperieurAZero() {
30 jpm 1409
		$info = array('nom' => 'num_nom_retenu -> supérieur à 0',
42 jpm 1410
			'description' => "Le champ num_nom_retenu doit contenir des nombres entiers supérieurs à 0 ou être vide.",
20 jpm 1411
			'resultat' => false);
1412
 
1413
		// Réalisation du test
1414
		$noms_erreur = array();
64 jpm 1415
		foreach ($this->noms as &$nom) {
42 jpm 1416
			if ($nom['num_nom_retenu'] != '' && $nom['num_nom_retenu'] <= 0) {
20 jpm 1417
				$noms_erreur[] = $nom['num_nom'];
1418
			}
1419
		}
1420
 
1421
		// Analyse des résultats
1422
		if (count($noms_erreur) > 0) {
164 delphine 1423
			$info['message'] = count($noms_erreur)." enregistrements dont le champ num_nom_retenu est inférieur ou égal à 0 : ".
1424
								implode(', ', $noms_erreur).'.';
20 jpm 1425
		} else {
1426
			$info['resultat'] = true;
1427
		}
1428
 
30 jpm 1429
		$this->traiterResultatTest($info);
20 jpm 1430
	}
1431
 
64 jpm 1432
	private function testerNumTaxSupEgalZeroUnique() {
30 jpm 1433
		$info = array('nom' => 'num_tax_sup -> égal à 0 unique',
164 delphine 1434
			'description' => "Un seul enregistrement doit posséder la valeur 0 dans le champ num_tax_sup. Il correspond ".
1435
								"au premier taxon de la classification.",
20 jpm 1436
			'resultat' => false);
1437
 
1438
		// Réalisation du test
1439
		$noms_erreur = array();
64 jpm 1440
		foreach ($this->noms as &$nom) {
20 jpm 1441
			if (preg_match('/^0$/', $nom['num_tax_sup'])) {
1442
				$noms_erreur[] = $nom['num_nom'];
1443
			}
1444
		}
1445
 
1446
		// Analyse des résultats
1447
		if (count($noms_erreur) > 1) {
164 delphine 1448
			$info['message'] = count($noms_erreur)." enregistrements ont une valeur de 0 dans le champ num_tax_sup : ".
1449
								implode(', ', $noms_erreur).'.';
20 jpm 1450
		} else {
1451
			$info['resultat'] = true;
1452
		}
1453
 
30 jpm 1454
		$this->traiterResultatTest($info);
20 jpm 1455
	}
1456
 
64 jpm 1457
	private function testerTaxSupPourTaxon() {
30 jpm 1458
		$info = array('nom' => 'Classification -> uniquement pour les taxons',
164 delphine 1459
			'description' => "Seuls les enregistrements représentant un taxon doivent posséder une valeur dans le champ ".
1460
				"num_tax_sup.\n Si num_nom_retenu est différent de num_nom (= nom synonyme) alors num_tax_sup doit être vide.",
20 jpm 1461
			'resultat' => false);
1462
 
1463
		// Réalisation du test
1464
		$noms_erreur = array();
64 jpm 1465
		foreach ($this->noms as &$nom) {
43 jpm 1466
			if ($nom['num_nom_retenu'] != $nom['num_nom'] && $nom['num_tax_sup'] != '') {
20 jpm 1467
				$noms_erreur[] = $nom['num_nom'];
1468
			}
1469
		}
1470
 
1471
		// Analyse des résultats
1472
		if (count($noms_erreur) > 0) {
164 delphine 1473
			$info['message'] = count($noms_erreur)." enregistrements ne sont pas des taxons et possèdent une ".
1474
								"valeur dans num_tax_sup : ".implode(', ', $noms_erreur).'.';
20 jpm 1475
		} else {
1476
			$info['resultat'] = true;
1477
		}
1478
 
30 jpm 1479
		$this->traiterResultatTest($info);
20 jpm 1480
	}
1481
 
64 jpm 1482
	private function testerExitenceTaxonSuperieur() {
30 jpm 1483
		$info = array('nom' => 'Classification -> existence du taxon supérieur',
164 delphine 1484
			'description' => "Chaque enregistrement représentant un taxon doit posséder un taxon supérieur sauf ".
1485
								"la racine de la classification.",
20 jpm 1486
			'resultat' => false);
1487
 
1488
		// Réalisation du test
1489
		$noms_erreur = array();
64 jpm 1490
		foreach ($this->noms as &$nom) {
20 jpm 1491
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
64 jpm 1492
				if ($nom['num_tax_sup'] != 0 && !isset($this->noms[$nom['num_tax_sup']])) {
20 jpm 1493
					$noms_erreur[] = $nom['num_nom'];
1494
				}
1495
			}
1496
		}
1497
 
1498
		// Analyse des résultats
1499
		if (count($noms_erreur) > 0) {
164 delphine 1500
			$info['message'] = count($noms_erreur)." enregistrements dont le taxon supérieur n'existe pas : ".
1501
								implode(', ', $noms_erreur).'.';
20 jpm 1502
		} else {
1503
			$info['resultat'] = true;
1504
		}
1505
 
30 jpm 1506
		$this->traiterResultatTest($info);
20 jpm 1507
	}
1508
 
64 jpm 1509
	private function testerClassificationRang() {
30 jpm 1510
		$info = array('nom' => 'Classification -> taxon supérieur avec rang inférieur',
164 delphine 1511
			'description' => "Pour chaque enregistrement représentant un taxon, le taxon supérieur doit avoir ".
165 delphine 1512
								"un rang inférieur au taxon courant (à l'exception des noms ayant le rang de Clade).",
20 jpm 1513
			'resultat' => false);
1514
 
1515
		// Réalisation du test
1516
		$noms_erreur = array();
64 jpm 1517
		foreach ($this->noms as &$nom) {
20 jpm 1518
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
64 jpm 1519
				if (isset($this->noms[$nom['num_tax_sup']])) {
1520
					$nom_sup = $this->noms[$nom['num_tax_sup']];
165 delphine 1521
					if ($nom_sup['rang'] >= $nom['rang']) {
1522
						// Prise en compte de l'exception des clades
1523
						if (! ($nom_sup['rang'] == 70 && $nom['rang'] == 70)) {
1524
							$noms_erreur[] = $nom['num_nom'];
1525
						}
20 jpm 1526
					}
1527
				}
1528
			}
1529
		}
1530
 
1531
		// Analyse des résultats
1532
		if (count($noms_erreur) > 0) {
1533
			$info['message'] = count($noms_erreur)." enregistrements avec un problème : ".implode(', ', $noms_erreur).'.';
1534
		} else {
1535
			$info['resultat'] = true;
1536
		}
1537
 
30 jpm 1538
		$this->traiterResultatTest($info);
20 jpm 1539
	}
1540
 
64 jpm 1541
	private function testerClassification() {
30 jpm 1542
		$info = array('nom' => 'Classification -> racine liée à chaque noeud',
164 delphine 1543
			'description' => "Pour chaque enregistrement, la classification doit pouvoir être remontée ".
1544
								"jusqu'à un nom unique possédant une valeur num_tax_sup de 0.",
20 jpm 1545
			'resultat' => false);
1546
 
1547
		// Réalisation du test
1548
		$noms_erreur = array();
161 jpm 1549
		$this->noms_ok = array();
64 jpm 1550
		foreach ($this->noms as &$nom) {
20 jpm 1551
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
161 jpm 1552
				if (isset($this->noms_ok[$nom['num_tax_sup']])) {
1553
					$this->noms_ok[$nom['num_nom']] = true;
160 jpm 1554
				} else {
161 jpm 1555
					$this->detection_boucle_infini = array();
160 jpm 1556
					$classif_ok = $this->remonterClassif($nom);
161 jpm 1557
					unset($this->detection_boucle_infini);
1558
 
160 jpm 1559
					if ($classif_ok === false) {
1560
						$noms_erreur[] = $nom['num_nom'];
1561
					} else {
161 jpm 1562
						$this->noms_ok[$nom['num_nom']] = $classif_ok;
160 jpm 1563
					}
161 jpm 1564
				}
20 jpm 1565
			}
1566
		}
161 jpm 1567
		unset($this->noms_ok);
20 jpm 1568
 
1569
		// Analyse des résultats
1570
		if (count($noms_erreur) > 0) {
164 delphine 1571
			$info['message'] = count($noms_erreur)." taxons dont la classification n'est pas bonne : ".
1572
								implode(', ', $noms_erreur).'.';
20 jpm 1573
		} else {
1574
			$info['resultat'] = true;
1575
		}
1576
 
30 jpm 1577
		$this->traiterResultatTest($info);
20 jpm 1578
	}
1579
 
161 jpm 1580
	private function remonterClassif(&$nom) {
1581
		$this->detection_boucle_infini[$nom['num_nom']] = true;
160 jpm 1582
		if (preg_match('/^[0-9]*$/', $nom['num_tax_sup'])) {
161 jpm 1583
			if (isset($this->noms_ok[$nom['num_tax_sup']])) {
1584
				$this->noms_ok[$nom['num_nom']] = true;
64 jpm 1585
				return true;
161 jpm 1586
			} else if (!isset($this->noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] == '0') {
1587
				$this->noms_ok[$nom['num_nom']] = true;
1588
				return true;
64 jpm 1589
			} else if (!isset($this->noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] != '0') {
1590
				return false;
161 jpm 1591
			} else if (isset($this->detection_boucle_infini[$nom['num_tax_sup']])) {
1592
				return false;
64 jpm 1593
			} else {
161 jpm 1594
				$retour = $this->remonterClassif($this->noms[$nom['num_tax_sup']]);
1595
				if ($retour === true) {
1596
					$this->noms_ok[$nom['num_tax_sup']] = true;
1597
				}
1598
				return $retour;
64 jpm 1599
			}
1600
		} else {
20 jpm 1601
			return false;
1602
		}
1603
	}
1604
 
64 jpm 1605
	private function testerRang() {
30 jpm 1606
		$info = array('nom' => 'rang',
163 delphine 1607
			'description' => "Le rang doit correspondre à une valeur numérique définie dans le manuel.",
20 jpm 1608
			'resultat' => false);
1609
 
1610
		$rangs = array_flip(explode(',', $this->manuel['rangs']));
1611
 
1612
		// Réalisation du test
1613
		$noms_erreur = array();
64 jpm 1614
		foreach ($this->noms as &$nom) {
20 jpm 1615
			if (!isset($rangs[$nom['rang']])) {
1616
				$noms_erreur[] = $nom['num_nom'];
1617
			}
1618
		}
1619
 
1620
		// Analyse des résultats
1621
		if (count($noms_erreur) > 0) {
1622
			$info['message'] = count($noms_erreur)." noms dont le rang n'est pas bon : ".implode(', ', $noms_erreur).'.';
1623
		} else {
1624
			$info['resultat'] = true;
1625
		}
1626
 
30 jpm 1627
		$this->traiterResultatTest($info);
20 jpm 1628
	}
1629
 
64 jpm 1630
	private function testerNomCompletSupraGenerique() {
149 jpm 1631
		$info = array('nom' => 'nom_sci -> noms supra-génériques',
164 delphine 1632
			'description' => "Si le rang est < à {$this->manuel['rang_genre']}, le nom_sci doit correspondre à la valeur ".
1633
								"du champ nom_supra_generique. Les valeurs des champs cultivar_groupe, cultivar et ".
1634
								"nom_commercial peuvent s'y ajouter.",
20 jpm 1635
			'resultat' => false);
1636
 
1637
		// Réalisation du test
1638
		$noms_erreur = array();
64 jpm 1639
		foreach ($this->noms as &$nom) {
20 jpm 1640
			if ($nom['rang'] < $this->manuel['rang_genre']) {
1641
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
149 jpm 1642
				$nom_sci_ideal = $this->formaterStyleNomGenre($nom['nom_supra_generique']);
1643
				$nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1644
				if ($nom['nom_sci'] != $nom_sci_ideal) {
1645
					$nom_sci_traite = $this->repererEspace($nom['nom_sci']);
1646
					$noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
20 jpm 1647
				}
1648
			}
1649
		}
1650
 
1651
		// Analyse des résultats
1652
		if (count($noms_erreur) > 0) {
149 jpm 1653
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
20 jpm 1654
			$info['message']['lignes'] = $noms_erreur;
1655
		} else {
1656
			$info['resultat'] = true;
1657
		}
1658
 
30 jpm 1659
		$this->traiterResultatTest($info);
20 jpm 1660
	}
1661
 
64 jpm 1662
	private function testerNomCompletGenre() {
149 jpm 1663
		$info = array('nom' => 'nom_sci -> noms de genres',
163 delphine 1664
			'description' => "Si le rang est = à {$this->manuel['rang_genre']}, le nom_sci doit correspondre à la valeur du champ genre. ".
20 jpm 1665
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
1666
			'resultat' => false);
1667
 
1668
		// Réalisation du test
1669
		$noms_erreur = array();
64 jpm 1670
		foreach ($this->noms as &$nom) {
20 jpm 1671
			if ($nom['rang'] == $this->manuel['rang_genre']) {
1672
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
149 jpm 1673
				$nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
1674
				$nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1675
				if ($nom['nom_sci'] != $nom_sci_ideal) {
1676
					$nom_sci_traite = $this->repererEspace($nom['nom_sci']);
1677
					$noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
20 jpm 1678
				}
1679
			}
1680
		}
1681
 
1682
		// Analyse des résultats
1683
		if (count($noms_erreur) > 0) {
149 jpm 1684
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
20 jpm 1685
			$info['message']['lignes'] = $noms_erreur;
1686
		} else {
1687
			$info['resultat'] = true;
1688
		}
1689
 
30 jpm 1690
		$this->traiterResultatTest($info);
20 jpm 1691
	}
1692
 
64 jpm 1693
	private function testerNomCompletInfraGenre() {
149 jpm 1694
		$info = array('nom' => 'nom_sci -> noms infra-génériques',
163 delphine 1695
			'description' => "Si le rang est > à {$this->manuel['rang_genre']} et < à {$this->manuel['rang_sp']},".
1696
			" le nom_sci doit correspondre à une des formules suivantes : \n".
20 jpm 1697
			" genre + ' ' + type_epithete + ' ' + epithete_infra_generique \n".
1698
			" genre + ' ' + epithete_infra_generique + ' ' + type_epithete=agg. \n".
1699
			"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
1700
			'resultat' => false);
1701
 
1702
		// Réalisation du test
1703
		$noms_erreur = array();
64 jpm 1704
		foreach ($this->noms as &$nom) {
20 jpm 1705
			if ($nom['rang'] > $this->manuel['rang_genre'] && $nom['rang'] < $this->manuel['rang_sp']) {
1706
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
149 jpm 1707
				$nom_sci_ideal = '';
20 jpm 1708
				if ($nom['type_epithete'] == 'agg.') {
149 jpm 1709
					$nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
1710
					$nom_sci_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
1711
					$nom_sci_ideal .= ' '.$nom['type_epithete'];
20 jpm 1712
				} else {
149 jpm 1713
					$nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
1714
					$nom_sci_ideal .= ' '.$nom['type_epithete'];
1715
					$nom_sci_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
20 jpm 1716
				}
149 jpm 1717
				$nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1718
				if ($nom['nom_sci'] != $nom_sci_ideal) {
1719
					$nom_sci_traite = $this->repererEspace($nom['nom_sci']);
1720
					$noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
20 jpm 1721
				}
1722
			}
1723
		}
1724
 
1725
		// Analyse des résultats
1726
		if (count($noms_erreur) > 0) {
149 jpm 1727
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
20 jpm 1728
			$info['message']['lignes'] = $noms_erreur;
1729
		} else {
1730
			$info['resultat'] = true;
1731
		}
64 jpm 1732
		$noms_erreur = null;
20 jpm 1733
 
30 jpm 1734
		$this->traiterResultatTest($info);
20 jpm 1735
	}
1736
 
64 jpm 1737
	private function testerNomCompletEspece() {
149 jpm 1738
		$info = array('nom' => "nom_sci -> noms d'espèce",
163 delphine 1739
			'description' => "Si le rang est = à {$this->manuel['rang_sp']}, le nom_sci doit correspondre à la formule : \n".
20 jpm 1740
				" genre + ' ' + epithete_sp \n".
1741
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
1742
			'resultat' => false);
1743
 
1744
		// Réalisation du test
1745
		$noms_erreur = array();
64 jpm 1746
		foreach ($this->noms as &$nom) {
20 jpm 1747
			if ($nom['rang'] == $this->manuel['rang_sp']) {
1748
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
149 jpm 1749
				$nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
1750
				$nom_sci_ideal .= ' '.strtolower($nom['epithete_sp']);
1751
				$nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1752
				if ($nom['nom_sci'] != $nom_sci_ideal) {
1753
					$nom_sci_traite = $this->repererEspace($nom['nom_sci']);
1754
					$noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
20 jpm 1755
				}
1756
			}
1757
		}
1758
 
1759
		// Analyse des résultats
1760
		if (count($noms_erreur) > 0) {
149 jpm 1761
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
20 jpm 1762
			$info['message']['lignes'] = $noms_erreur;
1763
		} else {
1764
			$info['resultat'] = true;
1765
		}
64 jpm 1766
		$noms_erreur = null;
20 jpm 1767
 
30 jpm 1768
		$this->traiterResultatTest($info);
20 jpm 1769
	}
1770
 
64 jpm 1771
	private function testerNomCompletInfraSpecifique() {
149 jpm 1772
		$info = array('nom' => 'nom_sci -> noms infra-spécifiques',
163 delphine 1773
			'description' => "Si le rang est > à {$this->manuel['rang_sp']}, le nom_sci doit correspondre à la formule : \n".
20 jpm 1774
				" genre + ' ' + epithete_sp + ' ' + type_epithete + ' ' + epithete_infra_generique\n".
1775
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
1776
			'resultat' => false);
1777
 
1778
		// Réalisation du test
1779
		$noms_erreur = array();
64 jpm 1780
		foreach ($this->noms as &$nom) {
20 jpm 1781
			if ($nom['rang'] > $this->manuel['rang_sp']) {
1782
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
149 jpm 1783
				$nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
1784
				$nom_sci_ideal .= ' '.strtolower($nom['epithete_sp']);
1785
				$nom_sci_ideal .= ' '.strtolower($nom['type_epithete']);
1786
				$nom_sci_ideal .= ' '.strtolower($nom['epithete_infra_sp']);
1787
				$nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1788
				if ($nom['nom_sci'] != $nom_sci_ideal) {
1789
					$nom_sci_traite = $this->repererEspace($nom['nom_sci']);
1790
					$noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
20 jpm 1791
				}
1792
			}
1793
		}
1794
 
1795
		// Analyse des résultats
1796
		if (count($noms_erreur) > 0) {
149 jpm 1797
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
20 jpm 1798
			$info['message']['lignes'] = $noms_erreur;
1799
		} else {
1800
			$info['resultat'] = true;
1801
		}
64 jpm 1802
		$noms_erreur = null;
20 jpm 1803
 
30 jpm 1804
		$this->traiterResultatTest($info);
20 jpm 1805
	}
1806
 
64 jpm 1807
	private function testerNomSupraGeneriqueEspaces() {
30 jpm 1808
		$info = array('nom' => 'nom_supra_generique -> espaces en trop',
163 delphine 1809
			'description' => "Le champ nom_supra_generique ne doit pas contenir d'espace avant ou après le nom.",
20 jpm 1810
			'resultat' => false);
1811
 
1812
		// Réalisation du test
1813
		$noms_erreur = array();
64 jpm 1814
		foreach ($this->noms as &$nom) {
20 jpm 1815
			if ($nom['nom_supra_generique'] != '') {
1816
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s+$)/', $nom['nom_supra_generique'])) {
1817
					$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
1818
					$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
1819
				}
1820
			}
1821
		}
1822
 
1823
		// Analyse des résultats
1824
		if (count($noms_erreur) > 0) {
1825
			$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
1826
			$info['message']['lignes'] = $noms_erreur;
1827
		} else {
1828
			$info['resultat'] = true;
1829
		}
64 jpm 1830
		$noms_erreur = null;
20 jpm 1831
 
30 jpm 1832
		$this->traiterResultatTest($info);
20 jpm 1833
	}
1834
 
64 jpm 1835
	private function testerNomSupraGeneriqueSyntaxe() {
30 jpm 1836
		$info = array('nom' => 'nom_supra_generique -> syntaxe',
163 delphine 1837
			'description' => "Le champ nom_supra_generique contient un mot composé de lettres minuscules, avec ou ".
1838
				"sans tréma (¨), et de tirets (-). \n".
20 jpm 1839
				"La première lettre (avec ou sans tréma) du mot doit être en majuscule.",
1840
			'resultat' => false);
1841
 
1842
		// Réalisation du test
1843
		$noms_erreur = array();
64 jpm 1844
		foreach ($this->noms as &$nom) {
20 jpm 1845
			if ($nom['nom_supra_generique'] != '') {
1846
				if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+$/', $nom['nom_supra_generique'])) {
1847
					$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
1848
					$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
1849
				}
1850
			}
1851
		}
1852
 
1853
		// Analyse des résultats
1854
		if (count($noms_erreur) > 0) {
1855
			$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
1856
			$info['message']['lignes'] = $noms_erreur;
1857
		} else {
1858
			$info['resultat'] = true;
1859
		}
64 jpm 1860
		$noms_erreur = null;
20 jpm 1861
 
30 jpm 1862
		$this->traiterResultatTest($info);
20 jpm 1863
	}
1864
 
64 jpm 1865
	private function testerNomSupraGeneriqueRang() {
30 jpm 1866
		$info = array('nom' => "nom_supra_generique -> rang < {$this->manuel['rang_genre']}",
20 jpm 1867
			'description' => "Si le champ nom_supra_generique n'est pas vide alors le rang du nom doit être inférieur à {$this->manuel['rang_genre']}.",
1868
			'resultat' => false);
1869
 
1870
		// Réalisation du test
1871
		$noms_erreur = array();
64 jpm 1872
		foreach ($this->noms as &$nom) {
20 jpm 1873
			if ($nom['nom_supra_generique'] != '') {
1874
				if ($nom['rang'] >= $this->manuel['rang_genre']) {
149 jpm 1875
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
20 jpm 1876
				}
1877
			}
1878
		}
1879
 
1880
		// Analyse des résultats
1881
		if (count($noms_erreur) > 0) {
149 jpm 1882
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
20 jpm 1883
			$info['message']['lignes'] = $noms_erreur;
1884
		} else {
1885
			$info['resultat'] = true;
1886
		}
64 jpm 1887
		$noms_erreur = null;
20 jpm 1888
 
30 jpm 1889
		$this->traiterResultatTest($info);
20 jpm 1890
	}
1891
 
64 jpm 1892
	private function testerGenreEspaces() {
30 jpm 1893
		$info = array('nom' => 'genre -> espaces en trop',
163 delphine 1894
			'description' => "Le champ genre ne doit pas contenir d'espace avant ou après le nom.\n".
1895
				"Si des espaces sont compris dans la valeur du champ, il ne doit pas en avoir plusieurs consécutifs.",
20 jpm 1896
			'resultat' => false);
1897
 
1898
		// Réalisation du test
1899
		$noms_erreur = array();
64 jpm 1900
		foreach ($this->noms as &$nom) {
20 jpm 1901
			if ($nom['genre'] != '') {
1902
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['genre'])) {
1903
					$nom_traite = $this->repererEspace($nom['genre']);
1904
					$noms_erreur[] = array($nom['num_nom'], $nom_traite);
1905
				}
1906
			}
1907
		}
1908
 
1909
		// Analyse des résultats
1910
		if (count($noms_erreur) > 0) {
1911
			$info['message']['entete'] = array('num_nom', 'genre erroné');
1912
			$info['message']['lignes'] = $noms_erreur;
1913
		} else {
1914
			$info['resultat'] = true;
1915
		}
64 jpm 1916
		$noms_erreur = null;
20 jpm 1917
 
30 jpm 1918
		$this->traiterResultatTest($info);
20 jpm 1919
	}
1920
 
64 jpm 1921
	private function testerGenreSyntaxe() {
30 jpm 1922
		$info = array('nom' => 'genre -> syntaxe',
20 jpm 1923
			'description' => "Le champ genre peut contenir :\n".
163 delphine 1924
			 	" - un mot unique composé de lettres minuscules, avec ou sans tréma (¨), et de tirets (-). \n".
164 delphine 1925
				"   Il commence par une lettre majuscule (avec ou sans tréma) et peut être précédé par \n".
163 delphine 1926
				"   le signe + ou la lettre x suivi d'un espace.\n".
164 delphine 1927
				" - une formule d'hybridité composée d'une série de noms de genre (au moins 2) séparés\n".
1928
				"   entre eux par la lettre x entourée de caractères espaces.",
20 jpm 1929
			'resultat' => false);
1930
 
1931
		// Réalisation du test
1932
		$noms_erreur = array();
64 jpm 1933
		foreach ($this->noms as &$nom) {
20 jpm 1934
			if ($nom['genre'] != '') {
1935
				$mots = explode(' ', $nom['genre']);
1936
				foreach ($mots as $mot) {
1937
					if (!(preg_match('/^[+x]$/', $mot) || $this->verifierEpitheteGenre($mot))) {
1938
						$nom_traite = $this->repererEspace($nom['genre']);
1939
						$noms_erreur[] = array($nom['num_nom'], $nom_traite);
1940
					}
1941
				}
1942
			}
1943
		}
1944
 
1945
		// Analyse des résultats
1946
		if (count($noms_erreur) > 0) {
1947
			$info['message']['entete'] = array('num_nom', 'genre erroné');
1948
			$info['message']['lignes'] = $noms_erreur;
1949
		} else {
1950
			$info['resultat'] = true;
1951
		}
64 jpm 1952
		$noms_erreur = null;
20 jpm 1953
 
30 jpm 1954
		$this->traiterResultatTest($info);
20 jpm 1955
	}
1956
 
64 jpm 1957
	private function testerGenreRang() {
30 jpm 1958
		$info = array('nom' => "genre -> rang >= {$this->manuel['rang_genre']}",
20 jpm 1959
			'description' => "Si le champ genre n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_genre']}.",
1960
			'resultat' => false);
1961
 
1962
		// Réalisation du test
1963
		$noms_erreur = array();
64 jpm 1964
		foreach ($this->noms as &$nom) {
20 jpm 1965
			if ($nom['genre'] != '') {
1966
				if ($nom['rang'] < $this->manuel['rang_genre']) {
149 jpm 1967
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
20 jpm 1968
				}
1969
			}
1970
		}
1971
 
1972
		// Analyse des résultats
1973
		if (count($noms_erreur) > 0) {
149 jpm 1974
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
20 jpm 1975
			$info['message']['lignes'] = $noms_erreur;
1976
		} else {
1977
			$info['resultat'] = true;
1978
		}
64 jpm 1979
		$noms_erreur = null;
20 jpm 1980
 
30 jpm 1981
		$this->traiterResultatTest($info);
20 jpm 1982
	}
1983
 
64 jpm 1984
	private function testerEpitheteInfraGeneriqueSyntaxe() {
30 jpm 1985
		$info = array('nom' => 'epithete_infra_generique -> syntaxe',
163 delphine 1986
			'description' => "Le champ epithete_infra_generique est composé de lettres minuscules, avec ou sans tréma (¨), et de tirets (-). \n".
20 jpm 1987
				"La première lettre (avec ou sans tréma) doit être en majuscule.",
1988
			'resultat' => false);
1989
 
1990
		// Réalisation du test
1991
		$noms_erreur = array();
64 jpm 1992
		foreach ($this->noms as &$nom) {
20 jpm 1993
			if ($nom['epithete_infra_generique'] != '') {
1994
				if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+/', $nom['epithete_infra_generique'])) {
1995
					$epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
1996
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1997
				}
1998
			}
1999
		}
2000
 
2001
		// Analyse des résultats
2002
		if (count($noms_erreur) > 0) {
2003
			$info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
2004
			$info['message']['lignes'] = $noms_erreur;
2005
		} else {
2006
			$info['resultat'] = true;
2007
		}
64 jpm 2008
		$noms_erreur = null;
20 jpm 2009
 
30 jpm 2010
		$this->traiterResultatTest($info);
20 jpm 2011
	}
2012
 
64 jpm 2013
	private function testerEpitheteInfraGeneriqueRang() {
30 jpm 2014
		$info = array('nom' => "epithete_infra_generique -> {$this->manuel['rang_genre']} < rang < {$this->manuel['rang_sp']}",
163 delphine 2015
			'description' => "Si le champ epithete_infra_generique n'est pas vide alors le rang du nom doit être compris ".
20 jpm 2016
				"entre {$this->manuel['rang_genre']} et {$this->manuel['rang_sp']}.",
2017
			'resultat' => false);
2018
 
2019
		// Réalisation du test
2020
		$noms_erreur = array();
64 jpm 2021
		foreach ($this->noms as &$nom) {
20 jpm 2022
			if ($nom['epithete_infra_generique'] != '') {
2023
				if ($nom['rang'] <= $this->manuel['rang_genre'] || $nom['rang'] >= $this->manuel['rang_sp']) {
149 jpm 2024
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
20 jpm 2025
				}
2026
			}
2027
		}
2028
 
2029
		// Analyse des résultats
2030
		if (count($noms_erreur) > 0) {
149 jpm 2031
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
20 jpm 2032
			$info['message']['lignes'] = $noms_erreur;
2033
		} else {
2034
			$info['resultat'] = true;
2035
		}
64 jpm 2036
		$noms_erreur = null;
20 jpm 2037
 
30 jpm 2038
		$this->traiterResultatTest($info);
20 jpm 2039
	}
2040
 
64 jpm 2041
	private function testerEpitheteInfraGeneriqueEspaces() {
30 jpm 2042
		$info = array('nom' => 'epithete_infra_generique -> espaces en trop',
163 delphine 2043
			'description' => "Le champ epithete_infra_generique ne doit pas contenir d'espace avant ou après sa valeur.",
20 jpm 2044
			'resultat' => false);
2045
 
2046
		// Réalisation du test
2047
		$noms_erreur = array();
64 jpm 2048
		foreach ($this->noms as &$nom) {
20 jpm 2049
			if ($nom['epithete_infra_generique'] != '') {
2050
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_generique'])) {
2051
					$epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
2052
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
2053
				}
2054
			}
2055
		}
2056
 
2057
		// Analyse des résultats
2058
		if (count($noms_erreur) > 0) {
2059
			$info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
2060
			$info['message']['lignes'] = $noms_erreur;
2061
		} else {
2062
			$info['resultat'] = true;
2063
		}
64 jpm 2064
		$noms_erreur = null;
20 jpm 2065
 
30 jpm 2066
		$this->traiterResultatTest($info);
20 jpm 2067
	}
2068
 
64 jpm 2069
	private function testerEpitheteSpEspaces() {
30 jpm 2070
		$info = array('nom' => 'epithete_sp -> espaces en trop',
163 delphine 2071
			'description' => "Le champ epithete_sp ne doit pas contenir d'espace avant ou après le nom.\n".
2072
				"Si des espaces sont compris dans la valeur du champ, il ne doit pas en avoir plusieurs consécutifs.",
20 jpm 2073
			'resultat' => false);
2074
 
2075
		// Réalisation du test
2076
		$noms_erreur = array();
64 jpm 2077
		foreach ($this->noms as &$nom) {
20 jpm 2078
			if ($nom['epithete_sp'] != '') {
2079
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_sp'])) {
2080
					$epithete_traite = $this->repererEspace($nom['epithete_sp']);
2081
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
2082
				}
2083
			}
2084
		}
2085
 
2086
		// Analyse des résultats
2087
		if (count($noms_erreur) > 0) {
2088
			$info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
2089
			$info['message']['lignes'] = $noms_erreur;
2090
		} else {
2091
			$info['resultat'] = true;
2092
		}
64 jpm 2093
		$noms_erreur = null;
20 jpm 2094
 
30 jpm 2095
		$this->traiterResultatTest($info);
20 jpm 2096
	}
2097
 
64 jpm 2098
	private function testerEpitheteSpSyntaxe() {
30 jpm 2099
		$info = array('nom' => 'epithete_sp -> syntaxe',
20 jpm 2100
			'description' => "Le champ epithete_sp peut contenir :\n".
2101
			 	" - un mot unique composé de lettres minuscules [a-z] incluant les caractères [ëï-]. \n".
164 delphine 2102
				"   Il commence par une lettre minuscule [a-zëï].\n".
2103
				"   Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
163 delphine 2104
				" - un mot contenant sp. suivi d'un ou plusieurs caractères numériques (1-9) \n".
2105
				"   ou d'un seul caractère majuscule (A-Z) \n".
2106
				" - une formule d'hybridité composée d'une série de noms d'espèce (au moins 2) \n".
164 delphine 2107
				"   séparés entre eux par la lettre x entourée de caractères espaces.",
20 jpm 2108
			'resultat' => false);
2109
 
2110
		// Réalisation du test
2111
		$noms_erreur = array();
64 jpm 2112
		foreach ($this->noms as &$nom) {
20 jpm 2113
			if ($nom['epithete_sp'] != '') {
2114
				$mots = explode(' ', $nom['epithete_sp']);
2115
				foreach ($mots as $mot) {
2116
					if (!(preg_match('/^[+x]$/', $mot) || $this->verifierEpitheteSp($mot))) {
2117
						$epithete_traite = $this->repererEspace($nom['epithete_sp']);
2118
						$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
2119
					}
2120
				}
2121
			}
2122
		}
2123
 
2124
		// Analyse des résultats
2125
		if (count($noms_erreur) > 0) {
2126
			$info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
2127
			$info['message']['lignes'] = $noms_erreur;
2128
		} else {
2129
			$info['resultat'] = true;
2130
		}
64 jpm 2131
		$noms_erreur = null;
20 jpm 2132
 
30 jpm 2133
		$this->traiterResultatTest($info);
20 jpm 2134
	}
2135
 
64 jpm 2136
	private function testerEpitheteSpRang() {
30 jpm 2137
		$info = array('nom' => "epithete_sp -> rang >= {$this->manuel['rang_sp']}",
20 jpm 2138
			'description' => "Si le champ epithete_sp n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_sp']}.",
2139
			'resultat' => false);
2140
 
2141
		// Réalisation du test
2142
		$noms_erreur = array();
64 jpm 2143
		foreach ($this->noms as &$nom) {
20 jpm 2144
			if ($nom['epithete_sp'] != '') {
2145
				if ($nom['rang'] < $this->manuel['rang_sp']) {
149 jpm 2146
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
20 jpm 2147
				}
2148
			}
2149
		}
2150
 
2151
		// Analyse des résultats
2152
		if (count($noms_erreur) > 0) {
149 jpm 2153
			$info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
20 jpm 2154
			$info['message']['lignes'] = $noms_erreur;
2155
		} else {
2156
			$info['resultat'] = true;
2157
		}
64 jpm 2158
		$noms_erreur = null;
20 jpm 2159
 
30 jpm 2160
		$this->traiterResultatTest($info);
20 jpm 2161
	}
2162
 
146 delphine 2163
 
2164
	private function testerExclureTaxRefSyntaxe() {
2165
		$info = array('nom' => 'exclure_taxref -> syntaxe',
2166
			'description' => "Le champ exclure_taxref contient soit :\n".
2167
			" - une valeur vide.\n".
2168
			" - une valeur null.\n".
2169
			" - le chiffre 0.\n".
2170
			" - le chiffre 1",
2171
			'resultat' => false);
2172
 
2173
		// Réalisation du test
2174
		$noms_erreur = array();
2175
		foreach ($this->noms as &$nom) {
2176
			if ($nom['exclure_taxref'] != '' && $nom['exclure_taxref'] != null) {
2177
				if (!$this->verifierBooleen($nom['exclure_taxref'])) {
2178
					$noms_erreur[] = array($nom['num_nom'], $nom['exclure_taxref']);
2179
				}
2180
			}
2181
		}
2182
 
2183
		// Analyse des résultats
2184
		if (count($noms_erreur) > 0) {
2185
			$info['message']['entete'] = array('num_nom', 'exclure_taxref erroné');
2186
			$info['message']['lignes'] = $noms_erreur;
2187
		} else {
2188
			$info['resultat'] = true;
2189
		}
2190
		$noms_erreur = null;
2191
 
2192
		$this->traiterResultatTest($info);
2193
	}
20 jpm 2194
	//+--------------------------------------------------------------------------------------------------------------+//
2195
	// MÉTHODES COMMUNES aux TESTS
2196
 
64 jpm 2197
	private function verifierPresence(&$valeur) {
20 jpm 2198
		$codes = $this->manuel['codes_presence'];
2199
		$ok = $this->verifierStatuts($valeur, $codes);
2200
		return $ok;
2201
	}
2202
 
64 jpm 2203
	private function verifierStatutOrigine(&$valeur) {
20 jpm 2204
		$codes = $this->manuel['codes_statuts_origine'];
2205
		$ok = $this->verifierStatuts($valeur, $codes);
2206
		return $ok;
2207
	}
2208
 
64 jpm 2209
	private function verifierStatutIntroduction(&$valeur) {
20 jpm 2210
		$codes = $this->manuel['codes_statuts_introduction'];
2211
		$ok = $this->verifierStatuts($valeur, $codes);
2212
		return $ok;
2213
	}
2214
 
64 jpm 2215
	private function verifierStatutCulture(&$valeur) {
20 jpm 2216
		$codes = $this->manuel['codes_statuts_culture'];
2217
		$ok = $this->verifierStatuts($valeur, $codes);
2218
		return $ok;
2219
	}
2220
 
64 jpm 2221
	private function verifierStatuts(&$valeur, &$codes) {
20 jpm 2222
		$ok = true;
2223
		if (!preg_match("/^(?:|-|[$codes](?:-[A-Z])?)$/", $valeur)) {
2224
			$ok = false;
2225
		}
2226
		return $ok;
2227
	}
2228
 
64 jpm 2229
	private function verifierBooleen(&$valeur) {
20 jpm 2230
		$ok = true;
2231
		if (!preg_match('/^1$/', $valeur)) {
2232
			$ok = false;
2233
		}
2234
		return $ok;
2235
	}
2236
 
64 jpm 2237
	private function verifierNombre(&$valeur) {
20 jpm 2238
		$ok = true;
2239
		if (!preg_match('/^[0-9]+$/', $valeur)) {
2240
			$ok = false;
2241
		}
2242
		return $ok;
2243
	}
2244
 
64 jpm 2245
	private function verifierNombreSuite(&$valeur) {
20 jpm 2246
		$ok = true;
2247
		if (!preg_match('/^(?:[0-9]+,)*[0-9]+$/', $valeur)) {
2248
			$ok = false;
2249
		}
2250
		return $ok;
2251
	}
2252
 
64 jpm 2253
	private function verifierTypeEpithete(&$type) {
20 jpm 2254
		$ok = false;
2255
		$rejetes = $this->manuel['type_epithete_rejetes'];
2256
		if (preg_replace("/^(?:$rejetes)$/", '', $type) == '') {
2257
			$ok = false;
2258
		} else if (preg_match('/^[a-z][-a-z]*[.]?$/', $type)) {
2259
			$ok = true;
2260
		}
2261
		return $ok;
2262
	}
2263
 
64 jpm 2264
	private function verifierBiblioOrigine(&$intitule) {
20 jpm 2265
		$ok = true;
2266
		if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $intitule)) {
2267
			$ok = false;// Contient des espaces en trop
2268
		} else if (!preg_match('/^(?:in [^;]+[;]|)[^,]+?(?:[,][^:]+|)(?:[:].+|)$/', $intitule)) {
2269
			$ok = false;
2270
		} else if (preg_match('/(?:(?:^|[,:])\s*(?:[:,]|$))/', $intitule)) {
2271
			$ok = false;// Contient une mauvaise suite de caractères
2272
		}
2273
		return $ok;
2274
	}
2275
 
64 jpm 2276
	private function verifierAnnee(&$annee) {
20 jpm 2277
		$ok = true;
2278
		if (!preg_match('/^[0-9]{4}$/', $annee)) {
2279
			$ok = false;
2280
		} else if ($annee < 1753) {
2281
			$ok = false;
2282
		}
2283
		return $ok;
2284
	}
2285
 
64 jpm 2286
	private function verifierAuteur(&$intitule) {
20 jpm 2287
		$ok = true;
2288
		$acceptes = $this->manuel['auteur_acceptes'];
2289
		if (!preg_match("/^(?:$acceptes)$/", $intitule)) {
2290
			if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $intitule)) {
2291
				$ok = false;// Contient des espaces en trop
2292
			} else {
2293
				$mots_rejetes = $this->manuel['auteur_mots_rejetes'];
2294
				$mots = explode(' ', $intitule);
2295
				foreach ($mots as $position => $mot) {
2296
					if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
2297
						$ok = false;// Mot rejeté
2298
					} else if (preg_match("/^(?:(?:\p{L}|[.'\(\)-])+|[&])$/u", $mot)) {
2299
						continue;// Mot de l'intitulé auteur
2300
					} else {
2301
						$ok = false;
2302
					}
2303
				}
2304
			}
2305
		}
2306
		return $ok;
2307
	}
2308
 
64 jpm 2309
	private function verifierNomCommercial(&$epithete) {
20 jpm 2310
		$ok = false;
2311
		if (preg_match("/^[[:upper:][:punct:][:digit:][:space:]]+$/", $epithete)) {
2312
			$ok = true;
2313
		}
2314
		return $ok;
2315
	}
2316
 
64 jpm 2317
	private function verifierEpitheteCultivar(&$epithete) {
20 jpm 2318
		$ok = true;
2319
		$acceptes = $this->manuel['cultivar_acceptes'];
2320
		if (!preg_match("/^(?:$acceptes)$/", $epithete)) {
2321
			if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $epithete)) {
2322
				$ok = false;// Contient des espaces en trop
2323
			} else {
2324
				$mots_rejetes = $this->manuel['cultivar_mots_rejetes'];
2325
				$mots_mineurs = $this->manuel['mots_mineurs'];
2326
				$mots = explode(' ', $epithete);
2327
				foreach ($mots as $position => $mot) {
2328
					if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
2329
						$ok = false;// Mot rejeté
2330
					} else if ($position > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot)) {
2331
						continue;// Mot mineur en minuscule qui n'est pas en 1ère position
2332
					} else {
2333
						$mots_tiret = explode('-', $mot);
2334
						foreach ($mots_tiret as $position_tiret => $mot_tiret) {
2335
							if ($position_tiret > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot_tiret)) {
2336
								continue;// Mot-tiret mineur en minuscule qui n'est pas en 1ère position
2337
							} else if (preg_match('/^[[:upper:]][[:lower:]]+$/', $mot_tiret)) {
2338
								continue;//Mot (ou 'mot-tiret') avec lettre initiale majuscule
2339
							} else if ($position_tiret == count($mots_tiret) && preg_match('/^[:upper:][:lower:]+[:punct:]?$/', $mot_tiret)) {
2340
								continue;//Dernier mot (ou 'mot-tiret') avec lettre initiale majuscule, suivi d'un éventuel signe de ponctuation
2341
							} else {
2342
								$ok = false;
2343
							}
2344
						}
2345
					}
2346
				}
2347
			}
2348
		}
2349
		return $ok;
2350
	}
2351
 
64 jpm 2352
	private function verifierEpitheteGroupeCultivar(&$epithete) {
20 jpm 2353
		$ok = true;
2354
		$acceptes = $this->manuel['cultivar_gp_acceptes'];
2355
		if (!preg_match("/^(?:$acceptes)$/", $epithete)) {
2356
			if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $epithete)) {
2357
				$ok = false;// Contient des espaces en trop
2358
			} else {
2359
				$mots_acceptes = $this->manuel['cultivar_gp_mots_acceptes'];
2360
				$mots_rejetes = $this->manuel['cultivar_gp_mots_rejetes'];
2361
				$mots_mineurs = $this->manuel['mots_mineurs'];
2362
				$mots = explode(' ', $epithete);
2363
				foreach ($mots as $position => $mot) {
2364
					if (preg_match("/^(?:$mots_acceptes)$/i", $mot)) {
2365
						continue;// Mot accepté
2366
					} else if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
2367
						$ok = false;// Mot rejeté
2368
					} else if ($position > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot)) {
2369
						continue;// Mot mineur en minuscule qui n'est pas en 1ère position
2370
					} else {
2371
						$mots_tiret = explode('-', $mot);
2372
						foreach ($mots_tiret as $position_tiret => $mot_tiret) {
2373
							if ($position_tiret > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot_tiret)) {
2374
								continue;// Mot-tiret mineur en minuscule qui n'est pas en 1ère position dans le mot
2375
							} else if (preg_match('/^[[:upper:]][[:lower:]]+$/', $mot_tiret)) {
2376
								continue;// Mot (ou 'mot-tiret') avec lettre initiale majuscule
2377
							} else if ($position_tiret == count($mots_tiret) && preg_match('/^[:upper:][:lower:]+[:punct:]?$/', $mot_tiret)) {
2378
								continue;// Dernier mot (ou 'mot-tiret') avec lettre initiale majuscule, suivi d'un éventuel signe de ponctuation
2379
							} else {
2380
								$ok = false;
2381
							}
2382
						}
2383
					}
2384
				}
2385
			}
2386
		}
2387
		return $ok;
2388
	}
2389
 
64 jpm 2390
	private function verifierEpitheteSp(&$epithete) {
20 jpm 2391
		$ok = false;
2392
		if (preg_match('/^[a-zëï][-a-zëï]+$/', $epithete)) {
2393
			$ok = true;
2394
		} else if (preg_match('/^sp\.(?:[A-Z]|[1-9][0-9]*)$/', $epithete)) {
2395
			$ok = true;
2396
		}
2397
		return $ok;
2398
	}
2399
 
64 jpm 2400
	private function verifierEpitheteGenre(&$epithete) {
20 jpm 2401
		$ok = false;
2402
		if (preg_match('/^[A-ZËÏ](?:[-a-zëï]+|[a-zëï]+-[A-ZËÏ][a-zëï]+)$/', $epithete)) {
2403
			$ok = true;
2404
		}
2405
		return $ok;
2406
	}
2407
 
64 jpm 2408
	private function formaterStyleNomGenre(&$genre) {
20 jpm 2409
		$genre_fmt = '';
2410
		if (preg_match('/^\s*([x+])\s+(.+)$/i', $genre, $match)) {
2411
			$genre_fmt = strtolower($match[1]).' '.ucfirst(strtolower($match[2]));
2412
		} else {
2413
			$genre_fmt = ucfirst(strtolower($genre));
2414
		}
2415
		return $genre_fmt;
2416
	}
2417
 
149 jpm 2418
	private function repererEspace($nom_sci) {
2419
		$nom_sci = str_replace(' ', '<span class="espace">&nbsp;</span>', $nom_sci);
2420
		return $nom_sci;
20 jpm 2421
	}
2422
 
64 jpm 2423
	private function construireSuffixeNomPltCultivee(&$nom) {
20 jpm 2424
		$suffixe = array();
2425
		$suffixe[] = $this->construireNomCultivarGroupe($nom);
2426
		$suffixe[] = $this->construireNomCommercial($nom);
2427
		$suffixe[] = $this->construireNomCultivar($nom);
2428
		$suffixe = array_filter($suffixe);
2429
		return implode(' ', $suffixe);
2430
	}
2431
 
64 jpm 2432
	private function construireNomCultivarGroupe(&$nom) {
20 jpm 2433
		$nom_groupe_cultivar = '';
2434
		if ($nom['cultivar_groupe'] != '') {
2435
			if (preg_match('/ gx$/', $nom['cultivar_groupe'])) {
2436
				$nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].')';
2437
			} else {
2438
				$nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].' Gp)';
2439
			}
2440
		}
2441
		return $nom_groupe_cultivar;
2442
	}
2443
 
64 jpm 2444
	private function construireNomCommercial(&$nom) {
20 jpm 2445
		$nom_commercial = '';
2446
		if ($nom['nom_commercial'] != '') {
2447
			$nom_commercial =  strtoupper($nom['nom_commercial']);
2448
		}
2449
		return $nom_commercial;
2450
	}
2451
 
64 jpm 2452
	private function construireNomCultivar(&$nom) {
20 jpm 2453
		$nom_cultivar = '';
2454
		if ($nom['cultivar'] != '') {
2455
			$nom_cultivar =  "'".$nom['cultivar']."'";
2456
		}
2457
		return $nom_cultivar;
2458
	}
2459
 
64 jpm 2460
	private function classerNomsParNomComplet() {
20 jpm 2461
		$noms_classes = array();
64 jpm 2462
		foreach ($this->noms as &$nom) {
149 jpm 2463
			if (!isset($noms_classes[$nom['nom_sci']])) {
2464
				$noms_classes[$nom['nom_sci']] = 1;
20 jpm 2465
			} else {
149 jpm 2466
				$noms_classes[$nom['nom_sci']]++;
20 jpm 2467
			}
2468
		}
2469
		return $noms_classes;
2470
	}
2471
 
2472
}
2473
?>