Subversion Repositories Applications.referentiel

Rev

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

Rev Author Line No. Line
6 jpm 1
<?php
2
// declare(encoding='UTF-8');
3
/**
4
 * Classe Controleur du module Test.
5
 *
6
 * @package		Referentiel
7
 * @category	Php5.2
8
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
9
 * @copyright	2010 Tela-Botanica
10
 * @license		http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
11
 * @license		http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
12
 * @version		SVN: $Id$
13
 */
14
class Test extends AppliControleur {
15
 
16
	private $projet = null;
17
	private $tableStructureDao = null;
18
	private $referentielDao = null;
19
	private $manuel = null;
20
 
21
	public function __construct()  {
22
		parent::__construct();
23
 
24
		// Récupération de paramêtres
25
		if (isset($_GET['projet'])) { // code du projet courrant
26
			$this->projet = $_GET['projet'];
27
		}
28
		// Parser le fichier ini contenant certains règles liées à la version du manuel
29
		$this->manuel = parse_ini_file(Config::get('dossier_configurations').DS.Config::get('manuel'));
30
 
31
		// Chargement des DAO nécessaires
32
		$this->tableStructureDao = $this->getModele('TableStructureDao');
33
		$this->referentielDao = $this->getModele('ReferentielDao');
34
	}
35
 
36
	//+----------------------------------------------------------------------------------------------------------------+
37
	// Méthodes
38
	/**
39
	 * Fonction d'affichage par défaut, elle appelle la liste des administrateurs
40
	 */
41
	public function executerActionParDefaut() {
42
		return $this->lancerTest();
43
	}
44
 
45
	public function lancerTest() {
46
		$donnees = array();
47
 
48
		// Récupération des données à tester
49
		$colonnes = $this->tableStructureDao->getColonnes($this->projet);
50
		$analyses = $this->tableStructureDao->getAnalyse($this->projet);
51
		$noms = $this->referentielDao->getTout($this->projet);
13 jpm 52
		$noms = $this->classerNomsParNumNom($noms);
53
		$noms_homonymie = $this->classerNomsParNomComplet($noms);
6 jpm 54
 
55
		// Lancement des tests unitaires
12 jpm 56
		/*
6 jpm 57
		$donnees['tests'][] = $this->testerNombreDeChamps($colonnes);
58
		$donnees['tests'][] = $this->testerNomDesChamps($colonnes);
59
		$donnees['tests'][] = $this->testerTypeDesChamps($colonnes);
60
		$donnees['tests'][] = $this->testerTailleDesChamps($colonnes, $analyses);
61
		$donnees['tests'][] = $this->testerNumNomClePrimaire($colonnes);
12 jpm 62
 
6 jpm 63
		$donnees['tests'][] = $this->testerNumNomSuperieurAZero($noms);
12 jpm 64
 
6 jpm 65
		$donnees['tests'][] = $this->testerNumNomRetenuSuperieurAZero($noms);
66
		$donnees['tests'][] = $this->testerNumTaxSupEgalZeroUnique($noms);
67
		$donnees['tests'][] = $this->testerTaxSupPourTaxon($noms);
68
		$donnees['tests'][] = $this->testerExitenceTaxonSuperieur($noms);
69
		$donnees['tests'][] = $this->testerClassificationRang($noms);
70
		$donnees['tests'][] = $this->testerClassification($noms);
12 jpm 71
 
6 jpm 72
		$donnees['tests'][] = $this->testerRang($noms);
12 jpm 73
 
6 jpm 74
		$donnees['tests'][] = $this->testerNomCompletSupraGenerique($noms);
75
		$donnees['tests'][] = $this->testerNomCompletGenre($noms);
76
		$donnees['tests'][] = $this->testerNomCompletInfraGenre($noms);
77
		$donnees['tests'][] = $this->testerNomCompletEspece($noms);
78
		$donnees['tests'][] = $this->testerNomCompletInfraSpecifique($noms);
12 jpm 79
 
6 jpm 80
		$donnees['tests'][] = $this->testerNomSupraGeneriqueEspaces($noms);
12 jpm 81
		$donnees['tests'][] = $this->testerNomSupraGeneriqueSyntaxe($noms);
82
		$donnees['tests'][] = $this->testerNomSupraGeneriqueRang($noms);
6 jpm 83
 
12 jpm 84
		$donnees['tests'][] = $this->testerGenreEspaces($noms);
85
		$donnees['tests'][] = $this->testerGenreSyntaxe($noms);
86
		$donnees['tests'][] = $this->testerGenreRang($noms);
87
 
88
		$donnees['tests'][] = $this->testerEpitheteInfraGeneriqueEspaces($noms);
89
		$donnees['tests'][] = $this->testerEpitheteInfraGeneriqueSyntaxe($noms);
90
		$donnees['tests'][] = $this->testerEpitheteInfraGeneriqueRang($noms);
91
 
92
		$donnees['tests'][] = $this->testerEpitheteSpEspaces($noms);
93
		$donnees['tests'][] = $this->testerEpitheteSpSyntaxe($noms);
94
		$donnees['tests'][] = $this->testerEpitheteSpRang($noms);
95
 
96
		$donnees['tests'][] = $this->testerTypeEpitheteEspaces($noms);
97
		$donnees['tests'][] = $this->testerTypeEpitheteSyntaxe($noms);
98
		$donnees['tests'][] = $this->testerTypeEpitheteHybridite($noms);
99
 
100
		$donnees['tests'][] = $this->testerEpitheteInfraSpEspaces($noms);
101
		$donnees['tests'][] = $this->testerEpitheteInfraSpSyntaxe($noms);
102
		$donnees['tests'][] = $this->testerEpitheteInfraSpRang($noms);
13 jpm 103
 
12 jpm 104
		$donnees['tests'][] = $this->testerGroupeCultivarSyntaxe($noms);
13 jpm 105
		$donnees['tests'][] = $this->testerGroupeCultivarRang($noms);
12 jpm 106
 
13 jpm 107
		$donnees['tests'][] = $this->testerCultivarSyntaxe($noms);
108
		$donnees['tests'][] = $this->testerCultivarRang($noms);
109
 
110
		$donnees['tests'][] = $this->testerNomCommercialSyntaxe($noms);
111
		$donnees['tests'][] = $this->testerNomCommercialPresenceCultivar($noms);
112
 
113
		$donnees['tests'][] = $this->testerAuteurSyntaxe($noms);
114
 
115
		$donnees['tests'][] = $this->testerAnneeSyntaxe($noms);
116
 
117
		$donnees['tests'][] = $this->testerBiblioOrigineSyntaxe($noms);
118
 
119
		$donnees['tests'][] = $this->testerHomonymieSyntaxe($noms);
120
		$donnees['tests'][] = $this->testerHomonymieExistence($noms, $noms_homonymie);
121
 
122
		$donnees['tests'][] = $this->testerBasionymeSyntaxe($noms);
123
		$donnees['tests'][] = $this->testerBasionymeExistence($noms);
124
 
125
		$donnees['tests'][] = $this->testerSynonymeProparteSyntaxe($noms);
126
		$donnees['tests'][] = $this->testerSynonymeProparteExistence($noms);
127
		*/
128
 
129
		$donnees['tests'][] = $this->testerSynonymeDouteuxSyntaxe($noms);
130
		$donnees['tests'][] = $this->testerSynonymeMalAppliqueSyntaxe($noms);
131
 
6 jpm 132
		//Debug::printr($this->manuel);
133
		$this->setSortie(self::RENDU_CORPS, $this->getVue('test', $donnees));
134
	}
135
 
12 jpm 136
	//+--------------------------------------------------------------------------------------------------------------+//
137
	// TESTS
13 jpm 138
 
139
	private function testerSynonymeMalAppliqueSyntaxe($noms) {
140
		$info = array('titre' => 'synonyme_mal_applique -> syntaxe',
141
			'description' => "Le champ synonyme_mal_applique contient soit :\n".
142
			" - une valeur vide.\n".
143
			" - le chiffre 1",
144
			'resultat' => false);
145
 
146
		// Réalisation du test
147
		$noms_erreur = array();
148
		foreach ($noms as $nom) {
149
			if ($nom['synonyme_mal_applique'] != '') {
150
				if (!$this->verifierBooleen($nom['synonyme_mal_applique'])) {
151
					$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_mal_applique']);
152
				}
153
			}
154
		}
155
 
156
		// Analyse des résultats
157
		if (count($noms_erreur) > 0) {
158
			$info['message']['entete'] = array('num_nom', 'synonyme_mal_applique erroné');
159
			$info['message']['lignes'] = $noms_erreur;
160
		} else {
161
			$info['resultat'] = true;
162
		}
163
 
164
		return $info;
165
	}
166
 
167
	private function testerSynonymeDouteuxSyntaxe($noms) {
168
		$info = array('titre' => 'synonyme_douteux -> syntaxe',
169
			'description' => "Le champ synonyme_douteux contient soit :\n".
170
			" - une valeur vide.\n".
171
			" - le chiffre 1",
172
			'resultat' => false);
173
 
174
		// Réalisation du test
175
		$noms_erreur = array();
176
		foreach ($noms as $nom) {
177
			if ($nom['synonyme_douteux'] != '') {
178
				if (!$this->verifierBooleen($nom['synonyme_douteux'])) {
179
					$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_douteux']);
180
				}
181
			}
182
		}
183
 
184
		// Analyse des résultats
185
		if (count($noms_erreur) > 0) {
186
			$info['message']['entete'] = array('num_nom', 'synonyme_douteux erroné');
187
			$info['message']['lignes'] = $noms_erreur;
188
		} else {
189
			$info['resultat'] = true;
190
		}
191
 
192
		return $info;
193
	}
194
 
195
	private function testerSynonymeProparteExistence($noms) {
196
		$info = array('titre' => 'synonyme_proparte -> existence',
197
			'description' => "Si le champ synonyme_proparte contient un ou plusieurs nombres alors chacun d'entre eux ".
198
			"doit correspondre à une valeur du champ num_nom.",
199
			'resultat' => false);
200
 
201
		// Réalisation du test
202
		$noms_erreur = array();
203
		foreach ($noms as $nom) {
204
			if ($nom['synonyme_proparte'] != '') {
205
				$num_nom_a_verifier = explode(',', $nom['synonyme_proparte']);
206
				$num_nom_en_erreur = array();
207
				foreach ($num_nom_a_verifier as $num_nom) {
208
					if (!isset($noms[$num_nom])) {
209
						$num_nom_en_erreur[] = $num_nom;
210
					}
211
				}
212
				if (count($nbre_en_erreur) > 0) {
213
					$noms_erreur[] = array($nom['num_nom'], implode(',', $num_nom_en_erreur));
214
				}
215
			}
216
		}
217
 
218
		// Analyse des résultats
219
		if (count($noms_erreur) > 0) {
220
			$info['message']['entete'] = array('num_nom', 'synonyme_proparte introuvable');
221
			$info['message']['lignes'] = $noms_erreur;
222
		} else {
223
			$info['resultat'] = true;
224
		}
225
 
226
		return $info;
227
	}
228
 
229
	private function testerSynonymeProparteSyntaxe($noms) {
230
		$info = array('titre' => 'synonyme_proparte -> syntaxe',
231
			'description' => "Le champ synonyme_proparte contient soit :\n".
232
			" - une valeur vide.\n".
233
			" - un nombre.\n".
234
			" - une suite de nombre séparés par des virgules.",
235
			'resultat' => false);
236
 
237
		// Réalisation du test
238
		$noms_erreur = array();
239
		foreach ($noms as $nom) {
240
			if ($nom['synonyme_proparte'] != '') {
241
				if (!$this->verifierNombreSuite($nom['synonyme_proparte'])) {
242
					$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_proparte']);
243
				}
244
			}
245
		}
246
 
247
		// Analyse des résultats
248
		if (count($noms_erreur) > 0) {
249
			$info['message']['entete'] = array('num_nom', 'synonyme_proparte erroné');
250
			$info['message']['lignes'] = $noms_erreur;
251
		} else {
252
			$info['resultat'] = true;
253
		}
254
 
255
		return $info;
256
	}
257
 
258
	private function testerBasionymeExistence($noms) {
259
		$info = array('titre' => 'basionyme -> existence',
260
			'description' => "Si le champ basionyme contient un nombre alors il doit correspondre à une valeur du champ ".
261
			"num_nom.",
262
			'resultat' => false);
263
 
264
		// Réalisation du test
265
		$noms_erreur = array();
266
		foreach ($noms as $nom) {
267
			if ($nom['basionyme'] != '') {
268
				if (!isset($noms[$nom['basionyme']])) {
269
					$noms_erreur[] = array($nom['num_nom'], $nom['basionyme']);
270
				}
271
			}
272
		}
273
 
274
		// Analyse des résultats
275
		if (count($noms_erreur) > 0) {
276
			$info['message']['entete'] = array('num_nom', 'basionyme introuvable');
277
			$info['message']['lignes'] = $noms_erreur;
278
		} else {
279
			$info['resultat'] = true;
280
		}
281
 
282
		return $info;
283
	}
284
 
285
	private function testerBasionymeSyntaxe($noms) {
286
		$info = array('titre' => 'basionyme -> syntaxe',
287
			'description' => "Le champ basionyme contient :\n".
288
			" - un nombre ou une valeur vide.\n",
289
			'resultat' => false);
290
 
291
		// Réalisation du test
292
		$noms_erreur = array();
293
		foreach ($noms as $nom) {
294
			if ($nom['basionyme'] != '') {
295
				if (!$this->verifierNombre($nom['basionyme'])) {
296
					$noms_erreur[] = array($nom['num_nom'], $nom['basionyme']);
297
				}
298
			}
299
		}
300
 
301
		// Analyse des résultats
302
		if (count($noms_erreur) > 0) {
303
			$info['message']['entete'] = array('num_nom', 'basionyme erroné');
304
			$info['message']['lignes'] = $noms_erreur;
305
		} else {
306
			$info['resultat'] = true;
307
		}
308
 
309
		return $info;
310
	}
311
 
312
	private function testerHomonymieExistence($noms, $noms_homonymie) {
313
		$info = array('titre' => 'homonyme -> existence',
314
			'description' => "Si le champ homonyme contient «1» alors plusieurs noms doivent posséder la même valeur ".
315
			"dans le champ nom_complet.",
316
			'resultat' => false);
317
 
318
		// Réalisation du test
319
		$noms_erreur = array();
320
		foreach ($noms as $nom) {
321
			if ($nom['homonyme'] != '0' && $nom['homonyme'] != '') {
322
				if ($noms_homonymie[$nom['nom_complet']] <= 1) {
323
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet']);
324
				}
325
			}
326
		}
327
 
328
		// Analyse des résultats
329
		if (count($noms_erreur) > 0) {
330
			$info['message']['entete'] = array('num_nom', 'homonyme introuvable');
331
			$info['message']['lignes'] = $noms_erreur;
332
		} else {
333
			$info['resultat'] = true;
334
		}
335
 
336
		return $info;
337
	}
338
 
339
	private function testerHomonymieSyntaxe($noms) {
340
		$info = array('titre' => 'homonyme -> syntaxe',
341
			'description' => "Le champ homonyme contient :\n".
342
			" - le chiffre 1 ou une valeur vide.\n",
343
			'resultat' => false);
344
 
345
		// Réalisation du test
346
		$noms_erreur = array();
347
		foreach ($noms as $nom) {
348
			if ($nom['homonyme'] != '') {
349
				if (!$this->verifierBooleen($nom['homonyme'])) {
350
					$noms_erreur[] = array($nom['num_nom'], $nom['homonyme']);
351
				}
352
			}
353
		}
354
 
355
		// Analyse des résultats
356
		if (count($noms_erreur) > 0) {
357
			$info['message']['entete'] = array('num_nom', 'homonyme erroné');
358
			$info['message']['lignes'] = $noms_erreur;
359
		} else {
360
			$info['resultat'] = true;
361
		}
362
 
363
		return $info;
364
	}
365
 
366
	private function testerBiblioOrigineSyntaxe($noms) {
367
		$info = array('titre' => 'biblio_origine -> syntaxe',
368
			'description' => "Le champ biblio_origine se compose de plusieurs parties séparées par des caractères ".
369
			"précis qui sont dans l'ordre de gauche à droite :\n".
370
			" - Éventuellement le mot « in » suivi d'un intitulé auteur (utilisé pour indiquer l'intitulé auteur de ".
371
			"l'ouvrage global dans lequel la publication est parue).\n".
372
			" - point-virgule « ; » (si l'info précédent a été renseignée)\n".
373
			" - Abréviation ou nom de l'ouvrage ou de la revue selon le standard en vigueur dans le code du nom. ".
374
			"Cette information ne doit pas contenir de caractère virgule « , ».\n".
375
			" - virgule « , »\n".
376
			" - Les informations permettant d'identifier plus précisément le document contenant le nom... ".
377
			"Par exemple, l'éditeur, le tome, le numéro d'édition, le volume... séparées par des virgules ou d'autres ".
378
			"caractères sauf deux points « : ».\n".
379
			" - deux points « : »\n".
380
			" - la page contenant la publication du nom ou un ensemble de page (première et dernière page de ".
381
			"l'ensemble séparées par un tiret « - »). Quelques fois des numéros ou d'autres informations indiquant ".
382
			"dans le document la position du nom. Le tiret « - » doit toujours servir à séparer un ensemble.",
383
			'resultat' => false);
384
 
385
		// Réalisation du test
386
		$noms_erreur = array();
387
		foreach ($noms as $nom) {
388
			if ($nom['biblio_origine'] != '') {
389
				if (!$this->verifierBiblioOrigine($nom['biblio_origine'])) {
390
					$biblio_traite = $this->repererEspace($nom['biblio_origine']);
391
					$noms_erreur[] = array($nom['num_nom'], $biblio_traite);
392
				}
393
			}
394
		}
395
 
396
		// Analyse des résultats
397
		if (count($noms_erreur) > 0) {
398
			$info['message']['entete'] = array('num_nom', 'biblio_origine erroné');
399
			$info['message']['lignes'] = $noms_erreur;
400
		} else {
401
			$info['resultat'] = true;
402
		}
403
 
404
		return $info;
405
	}
406
 
407
	private function testerAnneeSyntaxe($noms) {
408
		$info = array('titre' => 'annee -> syntaxe',
409
			'description' => "Le champ annee doit :\n".
410
			" - contenir un nombre de 4 chiffre\n".
411
			" - être supérieur ou égal à 1753 ",
412
			'resultat' => false);
413
 
414
		// Réalisation du test
415
		$noms_erreur = array();
416
		foreach ($noms as $nom) {
417
			if ($nom['annee'] != '') {
418
				if (!$this->verifierAnnee($nom['annee'])) {
419
					$noms_erreur[] = array($nom['num_nom'], $nom['annee']);
420
				}
421
			}
422
		}
423
 
424
		// Analyse des résultats
425
		if (count($noms_erreur) > 0) {
426
			$info['message']['entete'] = array('num_nom', 'annee erroné');
427
			$info['message']['lignes'] = $noms_erreur;
428
		} else {
429
			$info['resultat'] = true;
430
		}
431
 
432
		return $info;
433
	}
434
 
435
	private function testerAuteurSyntaxe($noms) {
436
		$info = array('titre' => 'auteur -> syntaxe',
437
			'description' => "Le champ auteur doit :\n".
438
			" - contenir l'intitulé complet des noms de l'auteur ou des auteurs ayant publiés à l'origine la combinaison latine courante.\n".
439
    		" - ou débuter par le mot « sensu » et contient l'intitulé complet des noms de l'auteur ou des auteurs ayant publiés un nom dont la description ne correspond pas à celle de l'auteur ou des auteurs d'origine.\n".
440
			" - 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".
441
			" - contenir, si nécessaire, des abréviations de noms d'auteurs respectant les standards.\n".
442
			" - contenir une translittération des noms d'alphabet cyrillique, arabe, chinois... en alphabet latin.\n".
443
			" - inclure entre parenthèses l'intitulé des noms de l'auteur ou des auteurs ayant publié le basionyme.\n".
444
			" - toujours utiliser l'esperluette (&) à la place du mot « et » pour séparer les noms d'auteurs.\n".
445
			" - conformément à la recommandation 46C.2 du CINB, si une un citation comprend plus de deux auteurs, ".
446
			"elle devrait être limitée au nom du premier, suivi de « & al.».\n",
447
			'resultat' => false);
448
 
449
		// Réalisation du test
450
		$noms_erreur = array();
451
		foreach ($noms as $nom) {
452
			if ($nom['auteur'] != '') {
453
				if (!$this->verifierAuteur($nom['auteur'])) {
454
					$intitule_traite = $this->repererEspace($nom['auteur']);
455
					$noms_erreur[] = array($nom['num_nom'], $intitule_traite);
456
				}
457
			}
458
		}
459
 
460
		// Analyse des résultats
461
		if (count($noms_erreur) > 0) {
462
			$info['message']['entete'] = array('num_nom', 'auteur erroné');
463
			$info['message']['lignes'] = $noms_erreur;
464
		} else {
465
			$info['resultat'] = true;
466
		}
467
 
468
		return $info;
469
	}
470
 
471
	private function testerNomCommercialSyntaxe($noms) {
472
		$info = array('titre' => 'nom_commercial -> syntaxe',
473
			'description' => "Le champ nom_commercial doit contenir un nom commercial conforme aux règles du ".
474
				"Code Internationnal de Nomenclature des Plantes Cultivées (CINPC) ".
475
				"qui se compose de caractères majuscules (A-Z) incluant des signes diacritiques et des espaces.\n",
476
			'resultat' => false);
477
 
478
		// Réalisation du test
479
		$noms_erreur = array();
480
		foreach ($noms as $nom) {
481
			if ($nom['nom_commercial'] != '') {
482
				if (!$this->verifierNomCommercial($nom['nom_commercial'])) {
483
					$epithete_traite = $this->repererEspace($nom['nom_commercial']);
484
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
485
				}
486
			}
487
		}
488
 
489
		// Analyse des résultats
490
		if (count($noms_erreur) > 0) {
491
			$info['message']['entete'] = array('num_nom', 'cultivar erroné');
492
			$info['message']['lignes'] = $noms_erreur;
493
		} else {
494
			$info['resultat'] = true;
495
		}
496
 
497
		return $info;
498
	}
499
 
500
	private function testerNomCommercialPresenceCultivar($noms) {
501
		$info = array('titre' => 'nom_commercial -> groupe_cultivar OU cultivar non vide',
502
			'description' => "Si le champ nom_commercial contier un nom commercial alors le champ cultivar OU ".
503
				"cultivar_groupe ne doit pas être vide.",
504
			'resultat' => false);
505
 
506
		// Réalisation du test
507
		$noms_erreur = array();
508
		foreach ($noms as $nom) {
509
			if ($nom['nom_commercial'] != '' && ($nom['cultivar'] == '' && $nom['cultivar_groupe'] == '')) {
510
				$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet']);
511
			}
512
		}
513
 
514
		// Analyse des résultats
515
		if (count($noms_erreur) > 0) {
516
			$info['message']['entete'] = array('num_nom', 'nom_commercial sans cultivar ou cultivar_groupe');
517
			$info['message']['lignes'] = $noms_erreur;
518
		} else {
519
			$info['resultat'] = true;
520
		}
521
 
522
		return $info;
523
	}
524
 
525
	private function testerCultivarSyntaxe($noms) {
526
		$info = array('titre' => 'cultivar -> syntaxe',
527
			'description' => "Le champ cultivar_groupe doit contenir :\n".
528
				" - un nom de cultivar conforme aux règles du Code Internationnal de Nomenclature des Plantes ".
529
				"Cultivées (CINPC) qui se compose de caractères alphanumériques (A-Z,a-z et 0-9) incluant ".
530
				"signes diacritiques et marques de ponctuations.\n".
531
				" - un nom en alphabet latin ce qui implique une translittération des noms d'alphabet cyrillique, ".
532
				"arabe, chinois...\n".
533
				" - une lettre majuscule obligatoire pour le premier caractère du premier mot et pour les autres mots ".
534
				"importants mais pas pour les mots mineurs.\n".
535
				"Ne doit pas contenir :\n".
536
				" - cv., convar. ou de guillemets simples (').\n",
537
			'resultat' => false);
538
 
539
		// Réalisation du test
540
		$noms_erreur = array();
541
		foreach ($noms as $nom) {
542
			if ($nom['cultivar'] != '') {
543
				if (!$this->verifierEpitheteCultivar($nom['cultivar'])) {
544
					$epithete_traite = $this->repererEspace($nom['cultivar']);
545
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
546
				}
547
			}
548
		}
549
 
550
		// Analyse des résultats
551
		if (count($noms_erreur) > 0) {
552
			$info['message']['entete'] = array('num_nom', 'cultivar erroné');
553
			$info['message']['lignes'] = $noms_erreur;
554
		} else {
555
			$info['resultat'] = true;
556
		}
557
 
558
		return $info;
559
	}
560
 
561
	private function testerCultivarRang($noms) {
562
		$info = array('titre' => "cultivar -> rang >= {$this->manuel['rang_genre']}",
563
			'description' => "Si le champ cultivar n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_genre']}.",
564
			'resultat' => false);
565
 
566
		// Réalisation du test
567
		$noms_erreur = array();
568
		foreach ($noms as $nom) {
569
			if ($nom['cultivar'] != '') {
570
				if ($nom['rang'] < $this->manuel['rang_genre']) {
571
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
572
				}
573
			}
574
		}
575
 
576
		// Analyse des résultats
577
		if (count($noms_erreur) > 0) {
578
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
579
			$info['message']['lignes'] = $noms_erreur;
580
		} else {
581
			$info['resultat'] = true;
582
		}
583
 
584
		return $info;
585
	}
586
 
12 jpm 587
	private function testerGroupeCultivarSyntaxe($noms) {
13 jpm 588
		$info = array('titre' => 'cultivar_groupe -> syntaxe',
589
			'description' => "Le champ cultivar_groupe doit contenir un nom de groupe de cultivar conforme aux règles ".
12 jpm 590
				"du code des plantes cultivées qui se compose de caractères alphanumériques (A-Z,a-z et 0-9) incluant ".
591
				"signes diacritiques et marques de ponctuations.\n".
592
				"Il ne doit pas contenir le mot Groupe, l'abbréviation «gp» ou des parenthèses.\n".
593
				"Il peut contir à la fin l'abréviation «gx» pour distinguer les groupes des grex.",
594
			'resultat' => false);
595
 
596
		// Réalisation du test
597
		$noms_erreur = array();
6 jpm 598
		foreach ($noms as $nom) {
13 jpm 599
			if ($nom['cultivar_groupe'] != '') {
600
				if (!$this->verifierEpitheteGroupeCultivar($nom['cultivar_groupe'])) {
601
					$epithete_traite = $this->repererEspace($nom['cultivar_groupe']);
602
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
12 jpm 603
				}
604
			}
6 jpm 605
		}
12 jpm 606
 
607
		// Analyse des résultats
608
		if (count($noms_erreur) > 0) {
13 jpm 609
			$info['message']['entete'] = array('num_nom', 'cultivar_groupe erroné');
12 jpm 610
			$info['message']['lignes'] = $noms_erreur;
611
		} else {
612
			$info['resultat'] = true;
613
		}
614
 
615
		return $info;
6 jpm 616
	}
617
 
13 jpm 618
	private function testerGroupeCultivarRang($noms) {
619
		$info = array('titre' => "cultivar_groupe -> rang >= {$this->manuel['rang_genre']}",
620
			'description' => "Si le champ cultivar_groupe n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_genre']}.",
621
			'resultat' => false);
622
 
623
		// Réalisation du test
624
		$noms_erreur = array();
625
		foreach ($noms as $nom) {
626
			if ($nom['cultivar_groupe'] != '') {
627
				if ($nom['rang'] < $this->manuel['rang_genre']) {
628
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
629
				}
630
			}
631
		}
632
 
633
		// Analyse des résultats
634
		if (count($noms_erreur) > 0) {
635
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
636
			$info['message']['lignes'] = $noms_erreur;
637
		} else {
638
			$info['resultat'] = true;
639
		}
640
 
641
		return $info;
642
	}
643
 
12 jpm 644
	private function testerEpitheteInfraSpEspaces($noms) {
645
		$info = array('titre' => 'epithete_infra_sp -> espaces en trop',
646
			'description' => "Le champ epithete_infra_sp ne doit pas contenir d'espace avant ou aprés le nom.\n".
647
				"Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
648
			'resultat' => false);
649
 
650
		// Réalisation du test
651
		$noms_erreur = array();
652
		foreach ($noms as $nom) {
653
			if ($nom['epithete_infra_sp'] != '') {
654
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_sp'])) {
655
					$epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
656
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
657
				}
658
			}
659
		}
660
 
661
		// Analyse des résultats
662
		if (count($noms_erreur) > 0) {
663
			$info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
664
			$info['message']['lignes'] = $noms_erreur;
665
		} else {
666
			$info['resultat'] = true;
667
		}
668
 
669
		return $info;
670
	}
671
 
672
	private function testerEpitheteInfraSpSyntaxe($noms) {
673
		$info = array('titre' => 'epithete_infra_sp -> syntaxe',
674
			'description' => "Le champ epithete_infra_sp peut contenir :\n".
675
			 	" - un mot unique composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
676
				"	Il commence par une lettre minuscule (avec ou sans tréma).\n".
677
				"	Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
678
				" - une formule d'hybridité composée d'une série de noms d'espèce ou d'infra espèce (au moins 2) séparés entre eux \n".
679
				"	par la lettre x entourée de caractères espaces.",
680
			'resultat' => false);
681
 
682
		// Réalisation du test
683
		$noms_erreur = array();
684
		foreach ($noms as $nom) {
685
			if ($nom['epithete_infra_sp'] != '') {
686
				$mots = explode(' ', $nom['epithete_infra_sp']);
687
				foreach ($mots as $mot) {
13 jpm 688
					if (!(preg_match('/^[+x]$/', $mot) || $this->verifierTypeEpithete($mot)|| $this->verifierEpitheteSp($mot))) {
12 jpm 689
						$epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
690
						$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
691
					}
692
				}
693
			}
694
		}
695
 
696
		// Analyse des résultats
697
		if (count($noms_erreur) > 0) {
698
			$info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
699
			$info['message']['lignes'] = $noms_erreur;
700
		} else {
701
			$info['resultat'] = true;
702
		}
703
 
704
		return $info;
705
	}
706
 
707
	private function testerEpitheteInfraSpRang($noms) {
708
		$info = array('titre' => "epithete_infra_sp -> rang > {$this->manuel['rang_sp']}",
709
			'description' => "Si le champ epithete_infra_sp n'est pas vide alors le rang du nom doit être supérieur à {$this->manuel['rang_sp']}.",
710
			'resultat' => false);
711
 
712
		// Réalisation du test
713
		$noms_erreur = array();
714
		foreach ($noms as $nom) {
715
			if ($nom['epithete_infra_sp'] != '') {
716
				if ($nom['rang'] < $this->manuel['rang_sp']) {
717
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
718
				}
719
			}
720
		}
721
 
722
		// Analyse des résultats
723
		if (count($noms_erreur) > 0) {
724
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
725
			$info['message']['lignes'] = $noms_erreur;
726
		} else {
727
			$info['resultat'] = true;
728
		}
729
 
730
		return $info;
731
	}
732
 
733
	private function testerTypeEpitheteEspaces($noms) {
734
		$info = array('titre' => 'type_epithete -> espaces en trop',
735
			'description' => "Le champ type_epithete ne doit pas contenir d'espace.",
736
			'resultat' => false);
737
 
738
		// Réalisation du test
739
		$noms_erreur = array();
740
		foreach ($noms as $nom) {
741
			if ($nom['type_epithete'] != '') {
742
				if (preg_match('/\s+/', $nom['type_epithete'])) {
743
					$valeur_traitee = $this->repererEspace($nom['epithete_sp']);
744
					$noms_erreur[] = array($nom['num_nom'], $valeur_traitee);
745
				}
746
			}
747
		}
748
 
749
		// Analyse des résultats
750
		if (count($noms_erreur) > 0) {
751
			$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
752
			$info['message']['lignes'] = $noms_erreur;
753
		} else {
754
			$info['resultat'] = true;
755
		}
756
 
757
		return $info;
758
	}
759
 
760
	private function testerTypeEpitheteSyntaxe($noms) {
761
		$info = array('titre' => 'type_epithete -> syntaxe',
762
			'description' => "Le champ type_epithete doit contenir un mot unique composé de lettres minuscules sans ".
763
				" accents et de tirets (-). Il commence par une lettre minuscule sans accent.",
764
			'resultat' => false);
765
 
766
		// Réalisation du test
767
		$noms_erreur = array();
768
		foreach ($noms as $nom) {
769
			if ($nom['type_epithete'] != '') {
13 jpm 770
				if (!$this->verifierTypeEpithete($nom['type_epithete'])) {
12 jpm 771
					$noms_erreur[] = array($nom['num_nom'],  $nom['type_epithete']);
772
				}
773
			}
774
		}
775
 
776
		// Analyse des résultats
777
		if (count($noms_erreur) > 0) {
778
			$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
779
			$info['message']['lignes'] = $noms_erreur;
780
		} else {
781
			$info['resultat'] = true;
782
		}
783
 
784
		return $info;
785
	}
786
 
787
	private function testerTypeEpitheteHybridite($noms) {
788
		$info = array('titre' => 'type_epithete -> hybridité',
789
			'description' => "Le champ type_epithete ne doit pas contenir de préfixe indiquant l'hybridité comme : \n".
790
				" - «n-» \n".
791
				" - «notho-» \n",
792
			'resultat' => false);
793
 
794
		// Réalisation du test
795
		$noms_erreur = array();
796
		foreach ($noms as $nom) {
797
			if ($nom['type_epithete'] != '') {
798
				if (preg_match('/^(?:n-|notho-)/', $nom['type_epithete'])) {
799
					$noms_erreur[] = array($nom['num_nom'], $nom['type_epithete']);
800
				}
801
			}
802
		}
803
 
804
		// Analyse des résultats
805
		if (count($noms_erreur) > 0) {
806
			$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
807
			$info['message']['lignes'] = $noms_erreur;
808
		} else {
809
			$info['resultat'] = true;
810
		}
811
 
812
		return $info;
813
	}
814
 
6 jpm 815
	private function testerNombreDeChamps($colonnes) {
816
		$info = array('titre' => 'Structure -> nombre de champs : %s',
817
			'description' => 'Le nombre de champs présent dans la table doit être supérieur ou égal à 35.',
818
			'resultat' => false);
819
 
820
		$nbre_colonnes = count($colonnes);
821
		$info['titre'] = sprintf($info['titre'], $nbre_colonnes);
822
		if ($nbre_colonnes >= 35) {
823
			$info['resultat'] = true;
824
		}
825
		return $info;
826
	}
827
 
828
	private function testerNomDesChamps($colonnes) {
829
		$info = array('titre' => 'Structure -> noms des champs',
830
			'description' => 'Les champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
831
			'resultat' => false);
832
 
833
		$champs_attendus = explode(',', $this->manuel['champs']);
834
		$champs_presents = array();
835
		foreach ($colonnes as $colonne) {
836
			$champs_presents[$colonne['Field']] = $colonne;
837
		}
838
 
839
		$ok = true;
840
		$champs_manquant = array();
841
		foreach ($champs_attendus as $champ_attendu) {
842
			if (!isset($champs_presents[$champ_attendu])) {
843
				$champs_manquant[] = $champ_attendu;
844
				$ok = false;
845
			}
846
		}
847
		$info['resultat'] = $ok;
848
		if (!$ok) {
849
			$info['message'] = 'Champs manquant : '.implode(', ', $champs_manquant).'.';
850
		}
851
 
852
		return $info;
853
	}
854
 
855
	private function testerTypeDesChamps($colonnes) {
856
		$info = array('titre' => 'Structure -> types des champs',
857
			'description' => 'Les types des champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
858
			'resultat' => false);
859
 
860
		$champs_attendus = explode(',', $this->manuel['champs_type']);
861
		$champs_presents = array();
862
		foreach ($colonnes as $colonne) {
863
			$champs_presents[$colonne['Field']] = $colonne['Type'];
864
		}
865
 
866
		// Recercherche des erreurs
867
		$champs_erreur = array();
868
		foreach ($champs_attendus as $champ_attendu) {
869
			list($champ_attendu_nom, $champ_attendu_type) = explode('=', trim($champ_attendu));
870
 
871
			if (isset($champs_presents[$champ_attendu_nom])) {
872
				$champs_present_type = $champs_presents[$champ_attendu_nom];
873
 
874
				if (($champ_attendu_type == 'VARCHAR' && strstr($champs_present_type, 'varchar') === false)
875
					|| ($champ_attendu_type == 'TEXT' && strstr($champs_present_type, 'text') === false)
876
					|| ($champ_attendu_type == 'INT' && strstr($champs_present_type, 'int') === false)
877
					|| ($champ_attendu_type == 'BOOL' && preg_match('/(?:bool|boolean|tinyint\(1\))/i', $champs_present_type) === false)) {
878
					$champs_erreur[] = $champ_attendu." vaut ".$champs_present_type;
879
				}
880
			}
881
		}
882
 
883
		// Analyse des résultats
884
		if (count($champs_erreur) > 0) {
885
			$info['message'] = "Champs n'ayant pas un bon type : ".implode(', ', $champs_erreur).'.';
886
		} else {
887
			$info['resultat'] = true;
888
		}
889
 
890
		return $info;
891
	}
892
 
893
	private function testerTailleDesChamps($colonnes, $analyses) {
894
		$info = array('titre' => 'Structure -> champs tronqués',
895
			'description' => "Vérifie que les données de type texte insérées dans la table n'ont pas été tronquées lors de leur insertion.",
896
			'resultat' => false);
897
 
898
		$tailles_champs_maxi = array();
899
		foreach ($colonnes as $colonne) {
900
			if (preg_match('/^varchar\(([0-9]+)\)$/', $colonne['Type'], $match)) {
901
				$tailles_champs_maxi[$colonne['Field']] = $match[1];
902
			}
903
		}
904
 
905
		$tailles_trouvees = array();
906
		foreach ($analyses as $analyse) {
907
			if (preg_match('/\.([^.]+)$/', $analyse['Field_name'], $match)) {
908
				$tailles_trouvees[$match[1]] = $analyse['Max_length'];
909
			}
910
		}
911
 
912
		$champs_erreur = array();
913
		$champs_attendus = explode(',', $this->manuel['champs']);
914
		foreach ($champs_attendus as $champ_attendu) {
915
			if (isset($tailles_champs_maxi[$champ_attendu]) && isset($tailles_trouvees[$champ_attendu])) {
916
				if ($tailles_champs_maxi[$champ_attendu] == $tailles_trouvees[$champ_attendu]) {
917
					$champs_erreur[] = $champ_attendu;
918
				}
919
			}
920
		}
921
 
922
		// Analyse des résultats
923
		if (count($champs_erreur) > 0) {
924
			$info['message'] = "Champs possédant des enregistrements avec une taille maximum : ".implode(', ', $champs_erreur).'.';
925
		} else {
926
			$info['resultat'] = true;
927
		}
928
 
929
		return $info;
930
	}
931
 
932
	private function testerNumNomClePrimaire($colonnes) {
933
		$info = array('titre' => 'Structure -> num_nom est clé primaire',
934
			'description' => "Vérifie que le champ num_nom est bien la clé primaire de la table.",
935
			'resultat' => false);
936
 
937
		foreach ($colonnes as $colonne) {
938
			if ($colonne['Field'] == 'num_nom' && $colonne['Key'] == 'PRI') {
939
				$info['resultat'] = true;
940
			}
941
		}
942
 
943
		return $info;
944
	}
945
 
946
	private function testerNumNomSuperieurAZero($noms) {
947
		$info = array('titre' => 'num_nom -> supérieur à 0',
948
			'description' => "Le champ num_nom doit contenir des nombres entiers supérieurs à 0.",
949
			'resultat' => false);
950
 
951
		// Réalisation du test
952
		$noms_erreur = array();
953
		foreach ($noms as $nom) {
954
			if ($nom['num_nom'] <= 0) {
955
				$noms_erreur[] = $nom['num_nom'];
956
			}
957
		}
958
 
959
		// Analyse des résultats
960
		if (count($noms_erreur) > 0) {
961
			$info['message'] = count($noms_erreur)." enregistrements contiennent dans le champ num_nom une valeur inférieure ou égale à 0.";
962
		} else {
963
			$info['resultat'] = true;
964
		}
965
 
966
		return $info;
967
	}
968
 
969
	private function testerNumNomRetenuSuperieurAZero($noms) {
970
		$info = array('titre' => 'num_nom_retenu -> supérieur à 0',
971
			'description' => "Le champ num_nom_retenu doit contenir des nombres entiers supérieurs à 0.",
972
			'resultat' => false);
973
 
974
		// Réalisation du test
975
		$noms_erreur = array();
976
		foreach ($noms as $nom) {
977
			if ($nom['num_nom_retenu'] <= 0) {
978
				$noms_erreur[] = $nom['num_nom'];
979
			}
980
		}
981
 
982
		// Analyse des résultats
983
		if (count($noms_erreur) > 0) {
984
			$info['message'] = count($noms_erreur)." enregistrements dont le champ num_nom_retenu est inférieur ou égal à 0 : ".implode(', ', $noms_erreur).'.';
985
		} else {
986
			$info['resultat'] = true;
987
		}
988
 
989
		return $info;
990
	}
991
 
992
	private function testerNumTaxSupEgalZeroUnique($noms) {
993
		$info = array('titre' => 'num_tax_sup -> égal à 0 unique',
994
			'description' => "Un seul enregistrement doit posséder la valeur 0 dans le champ num_tax_sup. Il correspond au premier taxon de la classification.",
995
			'resultat' => false);
996
 
997
		// Réalisation du test
998
		$noms_erreur = array();
999
		foreach ($noms as $nom) {
1000
			if (preg_match('/^0$/', $nom['num_tax_sup'])) {
1001
				$noms_erreur[] = $nom['num_nom'];
1002
			}
1003
		}
1004
 
1005
		// Analyse des résultats
1006
		if (count($noms_erreur) > 1) {
1007
			$info['message'] = count($noms_erreur)." enregistrements ont une valeur de 0 dans le champ num_tax_sup : ".implode(', ', $noms_erreur).'.';
1008
		} else {
1009
			$info['resultat'] = true;
1010
		}
1011
 
1012
		return $info;
1013
	}
1014
 
1015
	private function testerTaxSupPourTaxon($noms) {
1016
		$info = array('titre' => 'Classification -> uniquement pour les taxons',
1017
			'description' => "Seul les enregistrements représentant un taxon doivent posséder une valeur dans le champ num_tax_sup.",
1018
			'resultat' => false);
1019
 
1020
		// Réalisation du test
1021
		$noms_erreur = array();
1022
		foreach ($noms as $nom) {
1023
			if ($nom['num_nom_retenu'] == $nom['num_nom'] && preg_match('/^[0-9]+$/', $nom['num_tax_sup'])) {
1024
				$noms_erreur[] = $nom['num_nom'];
1025
			}
1026
		}
1027
 
1028
		// Analyse des résultats
1029
		if (count($noms_erreur) > 0) {
1030
			$info['message'] = count($noms_erreur)." enregistrements qui n'est pas un taxon et qui possède une valeur dans num_tax_sup : ".implode(', ', $noms_erreur).'.';
1031
		} else {
1032
			$info['resultat'] = true;
1033
		}
1034
 
1035
		return $info;
1036
	}
1037
 
1038
	private function testerExitenceTaxonSuperieur($noms) {
1039
		$info = array('titre' => 'Classification -> existence du taxon supérieur',
1040
			'description' => "Pour chaque enregistrement représentant un taxon doit posséder un taxon supérieur sauf la racine de la classification.",
1041
			'resultat' => false);
1042
 
1043
		// Réalisation du test
1044
		$noms_erreur = array();
1045
		foreach ($noms as $nom) {
1046
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
1047
				if ($nom['num_tax_sup'] != 0 && !isset($noms[$nom['num_tax_sup']])) {
1048
					$noms_erreur[] = $nom['num_nom'];
1049
				}
1050
			}
1051
		}
1052
 
1053
		// Analyse des résultats
1054
		if (count($noms_erreur) > 0) {
1055
			$info['message'] = count($noms_erreur)." enregistrements dont le taxon supérieur n'existe pas : ".implode(', ', $noms_erreur).'.';
1056
		} else {
1057
			$info['resultat'] = true;
1058
		}
1059
 
1060
		return $info;
1061
	}
1062
 
1063
	private function testerClassificationRang($noms) {
1064
		$info = array('titre' => 'Classification -> taxon supérieur avec rang inférieur',
1065
			'description' => "Pour chaque enregistrement représentant un taxon, chaque taxon supérieur doit avoir un rang inférieur au taxon courant.",
1066
			'resultat' => false);
1067
 
1068
		// Réalisation du test
1069
		$noms_erreur = array();
1070
		foreach ($noms as $nom) {
1071
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
1072
				if (isset($noms[$nom['num_tax_sup']])) {
1073
					$nom_sup = $noms[$nom['num_tax_sup']];
1074
					if ($nom_sup['rang'] > $nom['rang']) {
1075
						$noms_erreur[] = $nom['num_nom'];
1076
					}
1077
				}
1078
			}
1079
		}
1080
 
1081
		// Analyse des résultats
1082
		if (count($noms_erreur) > 0) {
1083
			$info['message'] = count($noms_erreur)." enregistrements avec un problème : ".implode(', ', $noms_erreur).'.';
1084
		} else {
1085
			$info['resultat'] = true;
1086
		}
1087
 
1088
		return $info;
1089
	}
1090
 
1091
	private function testerClassification($noms) {
1092
		$info = array('titre' => 'Classification -> racine liée à chaque noeud',
1093
			'description' => "Pour chaque enregistrement, la classification doit pouvoir être remonté jusqu'à un même nom unique possédant une valeur num_tax_sup de 0.",
1094
			'resultat' => false);
1095
 
1096
		// Réalisation du test
1097
		$noms_erreur = array();
1098
		foreach ($noms as $nom) {
1099
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
1100
				$classif_ok = $this->remonterClassif($noms, $nom);
1101
				if ($classif_ok === false) {
1102
					$noms_erreur[] = $nom['num_nom'];
1103
				}
1104
			}
1105
		}
1106
 
1107
		// Analyse des résultats
1108
		if (count($noms_erreur) > 0) {
1109
			$info['message'] = count($noms_erreur)." taxons dont la classification n'est pas bonne : ".implode(', ', $noms_erreur).'.';
1110
		} else {
1111
			$info['resultat'] = true;
1112
		}
1113
 
1114
		return $info;
1115
	}
1116
 
1117
	private function remonterClassif(&$noms, $nom) {
1118
		if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] == '0') {
1119
			return true;
1120
		} else if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] != '0') {
1121
			return false;
1122
		} else {
1123
			return $this->remonterClassif($noms, $noms[$nom['num_tax_sup']]);
1124
		}
1125
	}
1126
 
1127
	private function testerRang($noms) {
1128
		$info = array('titre' => 'rang',
1129
			'description' => "Le rang doit correspondre à un valeur numérique définit dans le manuel.",
1130
			'resultat' => false);
1131
 
1132
		$rangs = array_flip(explode(',', $this->manuel['rangs']));
1133
 
1134
		// Réalisation du test
1135
		$noms_erreur = array();
1136
		foreach ($noms as $nom) {
1137
			if (!isset($rangs[$nom['rang']])) {
1138
				$noms_erreur[] = $nom['num_nom'];
1139
			}
1140
		}
1141
 
1142
		// Analyse des résultats
1143
		if (count($noms_erreur) > 0) {
1144
			$info['message'] = count($noms_erreur)." noms dont le rang n'est pas bon : ".implode(', ', $noms_erreur).'.';
1145
		} else {
1146
			$info['resultat'] = true;
1147
		}
1148
 
1149
		return $info;
1150
	}
1151
 
1152
	private function testerNomCompletSupraGenerique($noms) {
1153
		$info = array('titre' => 'nom_complet -> noms supra-génériques',
1154
			'description' => "Si le rang est < à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ nom_supra_generique. ".
1155
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
1156
			'resultat' => false);
1157
 
1158
		// Réalisation du test
1159
		$noms_erreur = array();
1160
		foreach ($noms as $nom) {
1161
			if ($nom['rang'] < $this->manuel['rang_genre']) {
1162
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
1163
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['nom_supra_generique']);
1164
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1165
				if ($nom['nom_complet'] != $nom_complet_ideal) {
1166
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
1167
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
1168
				}
1169
			}
1170
		}
1171
 
1172
		// Analyse des résultats
1173
		if (count($noms_erreur) > 0) {
1174
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
1175
			$info['message']['lignes'] = $noms_erreur;
1176
		} else {
1177
			$info['resultat'] = true;
1178
		}
1179
 
1180
		return $info;
1181
	}
1182
 
1183
	private function testerNomCompletGenre($noms) {
1184
		$info = array('titre' => 'nom_complet -> noms de genres',
1185
			'description' => "Si le rang est = à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ genre. ".
1186
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
1187
			'resultat' => false);
1188
 
1189
		// Réalisation du test
1190
		$noms_erreur = array();
1191
		foreach ($noms as $nom) {
1192
			if ($nom['rang'] == $this->manuel['rang_genre']) {
1193
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
1194
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
1195
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1196
				if ($nom['nom_complet'] != $nom_complet_ideal) {
1197
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
1198
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
1199
				}
1200
			}
1201
		}
1202
 
1203
		// Analyse des résultats
1204
		if (count($noms_erreur) > 0) {
1205
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
1206
			$info['message']['lignes'] = $noms_erreur;
1207
		} else {
1208
			$info['resultat'] = true;
1209
		}
1210
 
1211
		return $info;
1212
	}
1213
 
1214
	private function testerNomCompletInfraGenre($noms) {
1215
		$info = array('titre' => 'nom_complet -> noms infra-génériques',
1216
			'description' => "Si le rang est > à {$this->manuel['rang_genre']} et < à {$this->manuel['rang_sp']} le nom_complet doit correspondre à une des formules suivantes : \n".
1217
			" genre + ' ' + type_epithete + ' ' + epithete_infra_generique \n".
1218
			" genre + ' ' + epithete_infra_generique + ' ' + type_epithete=agg. \n".
1219
			"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
1220
			'resultat' => false);
1221
 
1222
		// Réalisation du test
1223
		$noms_erreur = array();
1224
		foreach ($noms as $nom) {
1225
			if ($nom['rang'] > $this->manuel['rang_genre'] && $nom['rang'] < $this->manuel['rang_sp']) {
1226
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
1227
				$nom_complet_ideal = '';
1228
				if ($nom['type_epithete'] == 'agg.') {
1229
					$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
1230
					$nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
1231
					$nom_complet_ideal .= ' '.$nom['type_epithete'];
1232
				} else {
1233
					$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
1234
					$nom_complet_ideal .= ' '.$nom['type_epithete'];
1235
					$nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
1236
				}
1237
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1238
				if ($nom['nom_complet'] != $nom_complet_ideal) {
1239
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
1240
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
1241
				}
1242
			}
1243
		}
1244
 
1245
		// Analyse des résultats
1246
		if (count($noms_erreur) > 0) {
1247
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
1248
			$info['message']['lignes'] = $noms_erreur;
1249
		} else {
1250
			$info['resultat'] = true;
1251
		}
1252
 
1253
		return $info;
1254
	}
1255
 
1256
	private function testerNomCompletEspece($noms) {
1257
		$info = array('titre' => "nom_complet -> noms d'espèce",
1258
			'description' => "Si le rang est = à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
1259
				" genre + ' ' + epithete_sp \n".
1260
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
1261
			'resultat' => false);
1262
 
1263
		// Réalisation du test
1264
		$noms_erreur = array();
1265
		foreach ($noms as $nom) {
1266
			if ($nom['rang'] == $this->manuel['rang_sp']) {
1267
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
1268
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
1269
				$nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
1270
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1271
				if ($nom['nom_complet'] != $nom_complet_ideal) {
1272
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
1273
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
1274
				}
1275
			}
1276
		}
1277
 
1278
		// Analyse des résultats
1279
		if (count($noms_erreur) > 0) {
1280
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
1281
			$info['message']['lignes'] = $noms_erreur;
1282
		} else {
1283
			$info['resultat'] = true;
1284
		}
1285
 
1286
		return $info;
1287
	}
1288
 
1289
	private function testerNomCompletInfraSpecifique($noms) {
1290
		$info = array('titre' => 'nom_complet -> noms infra-spécifiques',
1291
			'description' => "Si le rang est > à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
1292
				" genre + ' ' + epithete_sp + ' ' + type_epithete + ' ' + epithete_infra_generique\n".
1293
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
1294
			'resultat' => false);
1295
 
1296
		// Réalisation du test
1297
		$noms_erreur = array();
1298
		foreach ($noms as $nom) {
1299
			if ($nom['rang'] > $this->manuel['rang_sp']) {
1300
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
1301
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
1302
				$nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
1303
				$nom_complet_ideal .= ' '.strtolower($nom['type_epithete']);
1304
				$nom_complet_ideal .= ' '.strtolower($nom['epithete_infra_sp']);
1305
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
1306
				if ($nom['nom_complet'] != $nom_complet_ideal) {
1307
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
1308
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
1309
				}
1310
			}
1311
		}
1312
 
1313
		// Analyse des résultats
1314
		if (count($noms_erreur) > 0) {
1315
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
1316
			$info['message']['lignes'] = $noms_erreur;
1317
		} else {
1318
			$info['resultat'] = true;
1319
		}
1320
 
1321
		return $info;
1322
	}
1323
 
12 jpm 1324
	private function testerNomSupraGeneriqueEspaces($noms) {
1325
		$info = array('titre' => 'nom_supra_generique -> espaces en trop',
1326
			'description' => "Le champ nom_supra_generique ne doit pas contenir d'espace avant ou aprés le nom.",
6 jpm 1327
			'resultat' => false);
1328
 
1329
		// Réalisation du test
1330
		$noms_erreur = array();
1331
		foreach ($noms as $nom) {
1332
			if ($nom['nom_supra_generique'] != '') {
12 jpm 1333
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s+$)/', $nom['nom_supra_generique'])) {
6 jpm 1334
					$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
1335
					$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
1336
				}
1337
			}
1338
		}
1339
 
1340
		// Analyse des résultats
1341
		if (count($noms_erreur) > 0) {
1342
			$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
1343
			$info['message']['lignes'] = $noms_erreur;
1344
		} else {
1345
			$info['resultat'] = true;
1346
		}
1347
 
1348
		return $info;
1349
	}
1350
 
12 jpm 1351
	private function testerNomSupraGeneriqueSyntaxe($noms) {
1352
		$info = array('titre' => 'nom_supra_generique -> syntaxe',
1353
			'description' => "Le champ nom_supra_generique contient un mot composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
1354
				"La première lettre (avec ou sans tréma) du mot doit être en majuscule.",
6 jpm 1355
			'resultat' => false);
1356
 
1357
		// Réalisation du test
1358
		$noms_erreur = array();
1359
		foreach ($noms as $nom) {
1360
			if ($nom['nom_supra_generique'] != '') {
12 jpm 1361
				if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+$/', $nom['nom_supra_generique'])) {
6 jpm 1362
					$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
1363
					$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
1364
				}
1365
			}
1366
		}
1367
 
1368
		// Analyse des résultats
1369
		if (count($noms_erreur) > 0) {
1370
			$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
1371
			$info['message']['lignes'] = $noms_erreur;
1372
		} else {
1373
			$info['resultat'] = true;
1374
		}
1375
 
1376
		return $info;
1377
	}
1378
 
12 jpm 1379
	private function testerNomSupraGeneriqueRang($noms) {
1380
		$info = array('titre' => "nom_supra_generique -> rang < {$this->manuel['rang_genre']}",
1381
			'description' => "Si le champ nom_supra_generique n'est pas vide alors le rang du nom doit être inférieur à {$this->manuel['rang_genre']}.",
1382
			'resultat' => false);
1383
 
1384
		// Réalisation du test
1385
		$noms_erreur = array();
1386
		foreach ($noms as $nom) {
1387
			if ($nom['nom_supra_generique'] != '') {
1388
				if ($nom['rang'] >= $this->manuel['rang_genre']) {
1389
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
1390
				}
1391
			}
1392
		}
1393
 
1394
		// Analyse des résultats
1395
		if (count($noms_erreur) > 0) {
1396
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
1397
			$info['message']['lignes'] = $noms_erreur;
1398
		} else {
1399
			$info['resultat'] = true;
1400
		}
1401
 
1402
		return $info;
1403
	}
1404
 
1405
	private function testerGenreEspaces($noms) {
1406
		$info = array('titre' => 'genre -> espaces en trop',
1407
			'description' => "Le champ genre ne doit pas contenir d'espace avant ou aprés le nom.\n".
1408
				"Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
1409
			'resultat' => false);
1410
 
1411
		// Réalisation du test
1412
		$noms_erreur = array();
1413
		foreach ($noms as $nom) {
1414
			if ($nom['genre'] != '') {
1415
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['genre'])) {
1416
					$nom_traite = $this->repererEspace($nom['genre']);
1417
					$noms_erreur[] = array($nom['num_nom'], $nom_traite);
1418
				}
1419
			}
1420
		}
1421
 
1422
		// Analyse des résultats
1423
		if (count($noms_erreur) > 0) {
1424
			$info['message']['entete'] = array('num_nom', 'genre erroné');
1425
			$info['message']['lignes'] = $noms_erreur;
1426
		} else {
1427
			$info['resultat'] = true;
1428
		}
1429
 
1430
		return $info;
1431
	}
1432
 
1433
	private function testerGenreSyntaxe($noms) {
1434
		$info = array('titre' => 'genre -> syntaxe',
1435
			'description' => "Le champ genre peut contenir :\n".
1436
			 	" - un mot unique composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
1437
				"	Il commence par une lettre majuscule (avec ou sans tréma).".
1438
				"	Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
1439
				" - une formule d'hybridité composée d'une série de noms de genre (au moins 2) séparés entre eux \n".
1440
				"	par la lettre x entourée de caractères espaces.",
1441
			'resultat' => false);
1442
 
1443
		// Réalisation du test
1444
		$noms_erreur = array();
1445
		foreach ($noms as $nom) {
1446
			if ($nom['genre'] != '') {
1447
				$mots = explode(' ', $nom['genre']);
1448
				foreach ($mots as $mot) {
13 jpm 1449
					if (!(preg_match('/^[+x]$/', $mot) || $this->verifierEpitheteGenre($mot))) {
12 jpm 1450
						$nom_traite = $this->repererEspace($nom['genre']);
1451
						$noms_erreur[] = array($nom['num_nom'], $nom_traite);
1452
					}
1453
				}
1454
			}
1455
		}
1456
 
1457
		// Analyse des résultats
1458
		if (count($noms_erreur) > 0) {
1459
			$info['message']['entete'] = array('num_nom', 'genre erroné');
1460
			$info['message']['lignes'] = $noms_erreur;
1461
		} else {
1462
			$info['resultat'] = true;
1463
		}
1464
 
1465
		return $info;
1466
	}
1467
 
1468
	private function testerGenreRang($noms) {
1469
		$info = array('titre' => "genre -> rang >= {$this->manuel['rang_genre']}",
1470
			'description' => "Si le champ genre n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_genre']}.",
1471
			'resultat' => false);
1472
 
1473
		// Réalisation du test
1474
		$noms_erreur = array();
1475
		foreach ($noms as $nom) {
1476
			if ($nom['genre'] != '') {
1477
				if ($nom['rang'] < $this->manuel['rang_genre']) {
1478
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
1479
				}
1480
			}
1481
		}
1482
 
1483
		// Analyse des résultats
1484
		if (count($noms_erreur) > 0) {
1485
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
1486
			$info['message']['lignes'] = $noms_erreur;
1487
		} else {
1488
			$info['resultat'] = true;
1489
		}
1490
 
1491
		return $info;
1492
	}
1493
 
1494
	private function testerEpitheteInfraGeneriqueSyntaxe($noms) {
1495
		$info = array('titre' => 'epithete_infra_generique -> syntaxe',
1496
			'description' => "Le champ epithete_infra_generique est composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
1497
				"La première lettre (avec ou sans tréma) doit être en majuscule.",
1498
			'resultat' => false);
1499
 
1500
		// Réalisation du test
1501
		$noms_erreur = array();
1502
		foreach ($noms as $nom) {
1503
			if ($nom['epithete_infra_generique'] != '') {
1504
				if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+/', $nom['epithete_infra_generique'])) {
1505
					$epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
1506
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1507
				}
1508
			}
1509
		}
1510
 
1511
		// Analyse des résultats
1512
		if (count($noms_erreur) > 0) {
1513
			$info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
1514
			$info['message']['lignes'] = $noms_erreur;
1515
		} else {
1516
			$info['resultat'] = true;
1517
		}
1518
 
1519
		return $info;
1520
	}
1521
 
1522
	private function testerEpitheteInfraGeneriqueRang($noms) {
1523
		$info = array('titre' => "epithete_infra_generique -> {$this->manuel['rang_genre']} < rang < {$this->manuel['rang_sp']}",
1524
			'description' => "Si le champ epithete_infra_generique n'est pas vide alors le rang du nom doit être compris \n".
1525
				"entre {$this->manuel['rang_genre']} et {$this->manuel['rang_sp']}.",
1526
			'resultat' => false);
1527
 
1528
		// Réalisation du test
1529
		$noms_erreur = array();
1530
		foreach ($noms as $nom) {
1531
			if ($nom['epithete_infra_generique'] != '') {
1532
				if ($nom['rang'] <= $this->manuel['rang_genre'] || $nom['rang'] >= $this->manuel['rang_sp']) {
1533
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
1534
				}
1535
			}
1536
		}
1537
 
1538
		// Analyse des résultats
1539
		if (count($noms_erreur) > 0) {
1540
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
1541
			$info['message']['lignes'] = $noms_erreur;
1542
		} else {
1543
			$info['resultat'] = true;
1544
		}
1545
 
1546
		return $info;
1547
	}
1548
 
1549
	private function testerEpitheteInfraGeneriqueEspaces($noms) {
1550
		$info = array('titre' => 'epithete_infra_generique -> espaces en trop',
1551
			'description' => "Le champ epithete_infra_generique ne doit pas contenir d'espace avant ou aprés sa valeur.",
1552
			'resultat' => false);
1553
 
1554
		// Réalisation du test
1555
		$noms_erreur = array();
1556
		foreach ($noms as $nom) {
1557
			if ($nom['epithete_infra_generique'] != '') {
1558
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_generique'])) {
1559
					$epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
1560
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1561
				}
1562
			}
1563
		}
1564
 
1565
		// Analyse des résultats
1566
		if (count($noms_erreur) > 0) {
1567
			$info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
1568
			$info['message']['lignes'] = $noms_erreur;
1569
		} else {
1570
			$info['resultat'] = true;
1571
		}
1572
 
1573
		return $info;
1574
	}
1575
 
1576
	private function testerEpitheteSpEspaces($noms) {
1577
		$info = array('titre' => 'epithete_sp -> espaces en trop',
1578
			'description' => "Le champ epithete_sp ne doit pas contenir d'espace avant ou aprés le nom.\n".
1579
				"Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
1580
			'resultat' => false);
1581
 
1582
		// Réalisation du test
1583
		$noms_erreur = array();
1584
		foreach ($noms as $nom) {
1585
			if ($nom['epithete_sp'] != '') {
1586
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_sp'])) {
1587
					$epithete_traite = $this->repererEspace($nom['epithete_sp']);
1588
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1589
				}
1590
			}
1591
		}
1592
 
1593
		// Analyse des résultats
1594
		if (count($noms_erreur) > 0) {
1595
			$info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
1596
			$info['message']['lignes'] = $noms_erreur;
1597
		} else {
1598
			$info['resultat'] = true;
1599
		}
1600
 
1601
		return $info;
1602
	}
1603
 
1604
	private function testerEpitheteSpSyntaxe($noms) {
1605
		$info = array('titre' => 'epithete_sp -> syntaxe',
1606
			'description' => "Le champ epithete_sp peut contenir :\n".
13 jpm 1607
			 	" - un mot unique composé de lettres minuscules [a-z] incluant les caractères [ëï-]. \n".
1608
				"	Il commence par une lettre minuscule [a-zëï].\n".
12 jpm 1609
				"	Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
1610
				" - un mot contenant sp. suivi d'un ou plusieurs caractères numériques (1-9) ou d'un seul caractère majuscule (A-Z) \n".
1611
				" - une formule d'hybridité composée d'une série de noms d'espèce (au moins 2) séparés entre eux \n".
1612
				"	par la lettre x entourée de caractères espaces.",
1613
			'resultat' => false);
1614
 
1615
		// Réalisation du test
1616
		$noms_erreur = array();
1617
		foreach ($noms as $nom) {
1618
			if ($nom['epithete_sp'] != '') {
1619
				$mots = explode(' ', $nom['epithete_sp']);
1620
				foreach ($mots as $mot) {
13 jpm 1621
					if (!(preg_match('/^[+x]$/', $mot) || $this->verifierEpitheteSp($mot))) {
12 jpm 1622
						$epithete_traite = $this->repererEspace($nom['epithete_sp']);
1623
						$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1624
					}
1625
				}
1626
			}
1627
		}
1628
 
1629
		// Analyse des résultats
1630
		if (count($noms_erreur) > 0) {
1631
			$info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
1632
			$info['message']['lignes'] = $noms_erreur;
1633
		} else {
1634
			$info['resultat'] = true;
1635
		}
1636
 
1637
		return $info;
1638
	}
1639
 
1640
	private function testerEpitheteSpRang($noms) {
1641
		$info = array('titre' => "epithete_sp -> rang >= {$this->manuel['rang_sp']}",
1642
			'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']}.",
1643
			'resultat' => false);
1644
 
1645
		// Réalisation du test
1646
		$noms_erreur = array();
1647
		foreach ($noms as $nom) {
1648
			if ($nom['epithete_sp'] != '') {
1649
				if ($nom['rang'] < $this->manuel['rang_sp']) {
1650
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
1651
				}
1652
			}
1653
		}
1654
 
1655
		// Analyse des résultats
1656
		if (count($noms_erreur) > 0) {
1657
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
1658
			$info['message']['lignes'] = $noms_erreur;
1659
		} else {
1660
			$info['resultat'] = true;
1661
		}
1662
 
1663
		return $info;
1664
	}
1665
 
1666
	//+--------------------------------------------------------------------------------------------------------------+//
1667
	// MÉTHODES COMMUNES aux TESTS
1668
 
13 jpm 1669
	private function verifierBooleen($valeur) {
1670
		$ok = true;
1671
		if (!preg_match('/^1$/', $valeur)) {
1672
			$ok = false;
1673
		}
1674
		return $ok;
1675
	}
1676
 
1677
	private function verifierNombre($valeur) {
1678
		$ok = true;
1679
		if (!preg_match('/^[0-9]+$/', $valeur)) {
1680
			$ok = false;
1681
		}
1682
		return $ok;
1683
	}
1684
 
1685
	private function verifierNombreSuite($valeur) {
1686
		$ok = true;
1687
		if (!preg_match('/^(?:[0-9]+,)*[0-9]+$/', $valeur)) {
1688
			$ok = false;
1689
		}
1690
		return $ok;
1691
	}
1692
 
12 jpm 1693
	private function verifierTypeEpithete($type) {
13 jpm 1694
		$ok = false;
1695
		$rejetes = $this->manuel['type_epithete_rejetes'];
1696
		if (preg_replace("/^(?:$rejetes)$/", '', $type) == '') {
1697
			$ok = false;
1698
		} else if (preg_match('/^[a-z][-a-z]*[.]?$/', $type)) {
1699
			$ok = true;
1700
		}
1701
		return $ok;
1702
	}
1703
 
1704
	private function verifierBiblioOrigine($intitule) {
12 jpm 1705
		$ok = true;
13 jpm 1706
		if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $intitule)) {
1707
			$ok = false;// Contient des espaces en trop
1708
		} else if (!preg_match('/^(?:in [^;]+[;]|)[^,]+?(?:[,][^:]+|)(?:[:].+|)$/', $intitule)) {
12 jpm 1709
			$ok = false;
13 jpm 1710
		} else if (preg_match('/(?:(?:^|[,:])\s*(?:[:,]|$))/', $intitule)) {
1711
			$ok = false;// Contient une mauvaise suite de caractères
12 jpm 1712
		}
1713
		return $ok;
1714
	}
1715
 
13 jpm 1716
	private function verifierAnnee($annee) {
1717
		$ok = true;
1718
		if (!preg_match('/^[0-9]{4}$/', $annee)) {
1719
			$ok = false;
1720
		} else if ($annee < 1753) {
1721
			$ok = false;
1722
		}
1723
		return $ok;
1724
	}
1725
 
1726
	private function verifierAuteur($intitule) {
1727
		$ok = true;
1728
		$acceptes = $this->manuel['auteur_acceptes'];
1729
		if (!preg_match("/^(?:$acceptes)$/", $intitule)) {
1730
			if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $intitule)) {
1731
				$ok = false;// Contient des espaces en trop
1732
			} else {
1733
				$mots_rejetes = $this->manuel['auteur_mots_rejetes'];
1734
				$mots = explode(' ', $intitule);
1735
				foreach ($mots as $position => $mot) {
1736
					if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
1737
						$ok = false;// Mot rejeté
1738
					} else if (preg_match("/^(?:(?:\p{L}|[.'\(\)-])+|[&])$/u", $mot)) {
1739
						continue;// Mot de l'intitulé auteur
1740
					} else {
1741
						$ok = false;
1742
					}
1743
				}
1744
			}
1745
		}
1746
		return $ok;
1747
	}
1748
 
1749
	private function verifierNomCommercial($epithete) {
12 jpm 1750
		$ok = false;
13 jpm 1751
		if (preg_match("/^[[:upper:][:punct:][:digit:][:space:]]+$/", $epithete)) {
12 jpm 1752
			$ok = true;
13 jpm 1753
		}
1754
		return $ok;
1755
	}
1756
 
1757
	private function verifierEpitheteCultivar($epithete) {
1758
		$ok = true;
1759
		$acceptes = $this->manuel['cultivar_acceptes'];
1760
		if (!preg_match("/^(?:$acceptes)$/", $epithete)) {
1761
			if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $epithete)) {
1762
				$ok = false;// Contient des espaces en trop
1763
			} else {
1764
				$mots_rejetes = $this->manuel['cultivar_mots_rejetes'];
1765
				$mots_mineurs = $this->manuel['mots_mineurs'];
1766
				$mots = explode(' ', $epithete);
1767
				foreach ($mots as $position => $mot) {
1768
					if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
1769
						$ok = false;// Mot rejeté
1770
					} else if ($position > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot)) {
1771
						continue;// Mot mineur en minuscule qui n'est pas en 1ère position
1772
					} else {
1773
						$mots_tiret = explode('-', $mot);
1774
						foreach ($mots_tiret as $position_tiret => $mot_tiret) {
1775
							if ($position_tiret > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot_tiret)) {
1776
								continue;// Mot-tiret mineur en minuscule qui n'est pas en 1ère position
1777
							} else if (preg_match('/^[[:upper:]][[:lower:]]+$/', $mot_tiret)) {
1778
								continue;//Mot (ou 'mot-tiret') avec lettre initiale majuscule
1779
							} else if ($position_tiret == count($mots_tiret) && preg_match('/^[:upper:][:lower:]+[:punct:]?$/', $mot_tiret)) {
1780
								continue;//Dernier mot (ou 'mot-tiret') avec lettre initiale majuscule, suivi d'un éventuel signe de ponctuation
1781
							} else {
1782
								$ok = false;
1783
							}
1784
						}
1785
					}
1786
				}
1787
			}
1788
		}
1789
		return $ok;
1790
	}
1791
 
1792
	private function verifierEpitheteGroupeCultivar($epithete) {
1793
		$ok = true;
1794
		$acceptes = $this->manuel['cultivar_gp_acceptes'];
1795
		if (!preg_match("/^(?:$acceptes)$/", $epithete)) {
1796
			if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $epithete)) {
1797
				$ok = false;// Contient des espaces en trop
1798
			} else {
1799
				$mots_acceptes = $this->manuel['cultivar_gp_mots_acceptes'];
1800
				$mots_rejetes = $this->manuel['cultivar_gp_mots_rejetes'];
1801
				$mots_mineurs = $this->manuel['mots_mineurs'];
1802
				$mots = explode(' ', $epithete);
1803
				foreach ($mots as $position => $mot) {
1804
					if (preg_match("/^(?:$mots_acceptes)$/i", $mot)) {
1805
						continue;// Mot accepté
1806
					} else if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
1807
						$ok = false;// Mot rejeté
1808
					} else if ($position > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot)) {
1809
						continue;// Mot mineur en minuscule qui n'est pas en 1ère position
1810
					} else {
1811
						$mots_tiret = explode('-', $mot);
1812
						foreach ($mots_tiret as $position_tiret => $mot_tiret) {
1813
							if ($position_tiret > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot_tiret)) {
1814
								continue;// Mot-tiret mineur en minuscule qui n'est pas en 1ère position dans le mot
1815
							} else if (preg_match('/^[[:upper:]][[:lower:]]+$/', $mot_tiret)) {
1816
								continue;// Mot (ou 'mot-tiret') avec lettre initiale majuscule
1817
							} else if ($position_tiret == count($mots_tiret) && preg_match('/^[:upper:][:lower:]+[:punct:]?$/', $mot_tiret)) {
1818
								continue;// Dernier mot (ou 'mot-tiret') avec lettre initiale majuscule, suivi d'un éventuel signe de ponctuation
1819
							} else {
1820
								$ok = false;
1821
							}
1822
						}
1823
					}
1824
				}
1825
			}
1826
		}
1827
		return $ok;
1828
	}
1829
 
1830
	private function verifierEpitheteSp($epithete) {
1831
		$ok = false;
1832
		if (preg_match('/^[a-zëï][-a-zëï]+$/', $epithete)) {
1833
			$ok = true;
12 jpm 1834
		} else if (preg_match('/^sp\.(?:[A-Z]|[1-9][0-9]*)$/', $epithete)) {
1835
			$ok = true;
1836
		}
1837
		return $ok;
1838
	}
1839
 
13 jpm 1840
	private function verifierEpitheteGenre($epithete) {
1841
		$ok = false;
1842
		if (preg_match('/^[A-ZËÏ](?:[-a-zëï]+|[a-zëï]+-[A-ZËÏ][a-zëï]+)$/', $epithete)) {
1843
			$ok = true;
1844
		}
1845
		return $ok;
1846
	}
1847
 
6 jpm 1848
	private function formaterStyleNomGenre($genre) {
1849
		$genre_fmt = '';
1850
		if (preg_match('/^\s*([x+])\s+(.+)$/i', $genre, $match)) {
1851
			$genre_fmt = strtolower($match[1]).' '.ucfirst(strtolower($match[2]));
1852
		} else {
1853
			$genre_fmt = ucfirst(strtolower($genre));
1854
		}
1855
		return $genre_fmt;
1856
	}
1857
 
1858
	private function repererEspace($nom_complet) {
1859
		$nom_complet = str_replace(' ', '<span class="espace">&nbsp;</span>', $nom_complet);
1860
		return $nom_complet;
1861
	}
1862
 
1863
	private function construireSuffixeNomPltCultivee($nom) {
1864
		$suffixe = array();
1865
		$suffixe[] = $this->construireNomCultivarGroupe($nom);
1866
		$suffixe[] = $this->construireNomCommercial($nom);
1867
		$suffixe[] = $this->construireNomCultivar($nom);
1868
		$suffixe = array_filter($suffixe);
1869
		return implode(' ', $suffixe);
1870
	}
1871
 
1872
	private function construireNomCultivarGroupe($nom) {
1873
		$nom_groupe_cultivar = '';
1874
		if ($nom['cultivar_groupe'] != '') {
1875
			if (preg_match('/ gx$/', $nom['cultivar_groupe'])) {
1876
				$nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].')';
1877
			} else {
1878
				$nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].' Gp)';
1879
			}
1880
		}
1881
		return $nom_groupe_cultivar;
1882
	}
1883
 
1884
	private function construireNomCommercial($nom) {
1885
		$nom_commercial = '';
1886
		if ($nom['nom_commercial'] != '') {
1887
			$nom_commercial =  strtoupper($nom['nom_commercial']);
1888
		}
1889
		return $nom_commercial;
1890
	}
1891
 
1892
	private function construireNomCultivar($nom) {
1893
		$nom_cultivar = '';
1894
		if ($nom['cultivar'] != '') {
1895
			$nom_cultivar =  "'".$nom['cultivar']."'";
1896
		}
1897
		return $nom_cultivar;
1898
	}
1899
 
13 jpm 1900
	private function classerNomsParNumNom($noms) {
12 jpm 1901
		$noms_classes = array();
1902
		foreach ($noms as $nom) {
1903
			$noms_classes[$nom['num_nom']] = $nom;
1904
		}
1905
		return $noms_classes;
1906
	}
13 jpm 1907
 
1908
	private function classerNomsParNomComplet($noms) {
1909
		$noms_classes = array();
1910
		foreach ($noms as $nom) {
1911
			if (!isset($noms_classes[$nom['nom_complet']])) {
1912
				$noms_classes[$nom['nom_complet']] = 1;
1913
			} else {
1914
				$noms_classes[$nom['nom_complet']]++;
1915
			}
1916
		}
1917
		return $noms_classes;
1918
	}
6 jpm 1919
}
1920
?>