Subversion Repositories Applications.referentiel

Rev

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