Subversion Repositories Applications.referentiel

Rev

Rev 6 | Rev 13 | 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);
52
		$noms = $this->classerNoms($noms);
53
 
54
		// Lancement des tests unitaires
12 jpm 55
		/*
6 jpm 56
		$donnees['tests'][] = $this->testerNombreDeChamps($colonnes);
57
		$donnees['tests'][] = $this->testerNomDesChamps($colonnes);
58
		$donnees['tests'][] = $this->testerTypeDesChamps($colonnes);
59
		$donnees['tests'][] = $this->testerTailleDesChamps($colonnes, $analyses);
60
		$donnees['tests'][] = $this->testerNumNomClePrimaire($colonnes);
12 jpm 61
 
6 jpm 62
		$donnees['tests'][] = $this->testerNumNomSuperieurAZero($noms);
12 jpm 63
 
6 jpm 64
		$donnees['tests'][] = $this->testerNumNomRetenuSuperieurAZero($noms);
65
		$donnees['tests'][] = $this->testerNumTaxSupEgalZeroUnique($noms);
66
		$donnees['tests'][] = $this->testerTaxSupPourTaxon($noms);
67
		$donnees['tests'][] = $this->testerExitenceTaxonSuperieur($noms);
68
		$donnees['tests'][] = $this->testerClassificationRang($noms);
69
		$donnees['tests'][] = $this->testerClassification($noms);
12 jpm 70
 
6 jpm 71
		$donnees['tests'][] = $this->testerRang($noms);
12 jpm 72
 
6 jpm 73
		$donnees['tests'][] = $this->testerNomCompletSupraGenerique($noms);
74
		$donnees['tests'][] = $this->testerNomCompletGenre($noms);
75
		$donnees['tests'][] = $this->testerNomCompletInfraGenre($noms);
76
		$donnees['tests'][] = $this->testerNomCompletEspece($noms);
77
		$donnees['tests'][] = $this->testerNomCompletInfraSpecifique($noms);
12 jpm 78
 
6 jpm 79
		$donnees['tests'][] = $this->testerNomSupraGeneriqueEspaces($noms);
12 jpm 80
		$donnees['tests'][] = $this->testerNomSupraGeneriqueSyntaxe($noms);
81
		$donnees['tests'][] = $this->testerNomSupraGeneriqueRang($noms);
6 jpm 82
 
12 jpm 83
		$donnees['tests'][] = $this->testerGenreEspaces($noms);
84
		$donnees['tests'][] = $this->testerGenreSyntaxe($noms);
85
		$donnees['tests'][] = $this->testerGenreRang($noms);
86
 
87
		$donnees['tests'][] = $this->testerEpitheteInfraGeneriqueEspaces($noms);
88
		$donnees['tests'][] = $this->testerEpitheteInfraGeneriqueSyntaxe($noms);
89
		$donnees['tests'][] = $this->testerEpitheteInfraGeneriqueRang($noms);
90
 
91
		$donnees['tests'][] = $this->testerEpitheteSpEspaces($noms);
92
		$donnees['tests'][] = $this->testerEpitheteSpSyntaxe($noms);
93
		$donnees['tests'][] = $this->testerEpitheteSpRang($noms);
94
 
95
		$donnees['tests'][] = $this->testerTypeEpitheteEspaces($noms);
96
		$donnees['tests'][] = $this->testerTypeEpitheteSyntaxe($noms);
97
		$donnees['tests'][] = $this->testerTypeEpitheteHybridite($noms);
98
 
99
		$donnees['tests'][] = $this->testerEpitheteInfraSpEspaces($noms);
100
		$donnees['tests'][] = $this->testerEpitheteInfraSpSyntaxe($noms);
101
		$donnees['tests'][] = $this->testerEpitheteInfraSpRang($noms);
102
		*/
103
		$donnees['tests'][] = $this->testerGroupeCultivarSyntaxe($noms);
104
 
6 jpm 105
		//Debug::printr($this->manuel);
106
		$this->setSortie(self::RENDU_CORPS, $this->getVue('test', $donnees));
107
	}
108
 
12 jpm 109
	//+--------------------------------------------------------------------------------------------------------------+//
110
	// TESTS
111
 
112
	private function testerGroupeCultivarSyntaxe($noms) {
113
		$info = array('titre' => 'groupe_cultivar -> syntaxe',
114
			'description' => "Le champ groupe_cultivar doit contenir un nom de groupe de cultivar conforme aux règles ".
115
				"du code des plantes cultivées qui se compose de caractères alphanumériques (A-Z,a-z et 0-9) incluant ".
116
				"signes diacritiques et marques de ponctuations.\n".
117
				"Il ne doit pas contenir le mot Groupe, l'abbréviation «gp» ou des parenthèses.\n".
118
				"Il peut contir à la fin l'abréviation «gx» pour distinguer les groupes des grex.",
119
			'resultat' => false);
120
 
121
		// Réalisation du test
122
		$noms_erreur = array();
6 jpm 123
		foreach ($noms as $nom) {
12 jpm 124
			if ($nom['groupe_cultivar'] != '') {
125
				$mots = explode(' ', $nom['groupe_cultivar']);
126
				foreach ($mots as $mot) {
127
					if (!(preg_match('/^[+x]$/', $mot) || $this->verifierTypeEpithete($mot)|| $this->verifierEpithteSp($mot))) {
128
						$epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
129
						$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
130
					}
131
				}
132
			}
6 jpm 133
		}
12 jpm 134
 
135
		// Analyse des résultats
136
		if (count($noms_erreur) > 0) {
137
			$info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
138
			$info['message']['lignes'] = $noms_erreur;
139
		} else {
140
			$info['resultat'] = true;
141
		}
142
 
143
		return $info;
6 jpm 144
	}
145
 
12 jpm 146
	private function testerEpitheteInfraSpEspaces($noms) {
147
		$info = array('titre' => 'epithete_infra_sp -> espaces en trop',
148
			'description' => "Le champ epithete_infra_sp ne doit pas contenir d'espace avant ou aprés le nom.\n".
149
				"Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
150
			'resultat' => false);
151
 
152
		// Réalisation du test
153
		$noms_erreur = array();
154
		foreach ($noms as $nom) {
155
			if ($nom['epithete_infra_sp'] != '') {
156
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_sp'])) {
157
					$epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
158
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
159
				}
160
			}
161
		}
162
 
163
		// Analyse des résultats
164
		if (count($noms_erreur) > 0) {
165
			$info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
166
			$info['message']['lignes'] = $noms_erreur;
167
		} else {
168
			$info['resultat'] = true;
169
		}
170
 
171
		return $info;
172
	}
173
 
174
	private function testerEpitheteInfraSpSyntaxe($noms) {
175
		$info = array('titre' => 'epithete_infra_sp -> syntaxe',
176
			'description' => "Le champ epithete_infra_sp peut contenir :\n".
177
			 	" - un mot unique composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
178
				"	Il commence par une lettre minuscule (avec ou sans tréma).\n".
179
				"	Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
180
				" - 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".
181
				"	par la lettre x entourée de caractères espaces.",
182
			'resultat' => false);
183
 
184
		// Réalisation du test
185
		$noms_erreur = array();
186
		foreach ($noms as $nom) {
187
			if ($nom['epithete_infra_sp'] != '') {
188
				$mots = explode(' ', $nom['epithete_infra_sp']);
189
				foreach ($mots as $mot) {
190
					if (!(preg_match('/^[+x]$/', $mot) || $this->verifierTypeEpithete($mot)|| $this->verifierEpithteSp($mot))) {
191
						$epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
192
						$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
193
					}
194
				}
195
			}
196
		}
197
 
198
		// Analyse des résultats
199
		if (count($noms_erreur) > 0) {
200
			$info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
201
			$info['message']['lignes'] = $noms_erreur;
202
		} else {
203
			$info['resultat'] = true;
204
		}
205
 
206
		return $info;
207
	}
208
 
209
	private function testerEpitheteInfraSpRang($noms) {
210
		$info = array('titre' => "epithete_infra_sp -> rang > {$this->manuel['rang_sp']}",
211
			'description' => "Si le champ epithete_infra_sp n'est pas vide alors le rang du nom doit être supérieur à {$this->manuel['rang_sp']}.",
212
			'resultat' => false);
213
 
214
		// Réalisation du test
215
		$noms_erreur = array();
216
		foreach ($noms as $nom) {
217
			if ($nom['epithete_infra_sp'] != '') {
218
				if ($nom['rang'] < $this->manuel['rang_sp']) {
219
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
220
				}
221
			}
222
		}
223
 
224
		// Analyse des résultats
225
		if (count($noms_erreur) > 0) {
226
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
227
			$info['message']['lignes'] = $noms_erreur;
228
		} else {
229
			$info['resultat'] = true;
230
		}
231
 
232
		return $info;
233
	}
234
 
235
	private function testerTypeEpitheteEspaces($noms) {
236
		$info = array('titre' => 'type_epithete -> espaces en trop',
237
			'description' => "Le champ type_epithete ne doit pas contenir d'espace.",
238
			'resultat' => false);
239
 
240
		// Réalisation du test
241
		$noms_erreur = array();
242
		foreach ($noms as $nom) {
243
			if ($nom['type_epithete'] != '') {
244
				if (preg_match('/\s+/', $nom['type_epithete'])) {
245
					$valeur_traitee = $this->repererEspace($nom['epithete_sp']);
246
					$noms_erreur[] = array($nom['num_nom'], $valeur_traitee);
247
				}
248
			}
249
		}
250
 
251
		// Analyse des résultats
252
		if (count($noms_erreur) > 0) {
253
			$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
254
			$info['message']['lignes'] = $noms_erreur;
255
		} else {
256
			$info['resultat'] = true;
257
		}
258
 
259
		return $info;
260
	}
261
 
262
	private function testerTypeEpitheteSyntaxe($noms) {
263
		$info = array('titre' => 'type_epithete -> syntaxe',
264
			'description' => "Le champ type_epithete doit contenir un mot unique composé de lettres minuscules sans ".
265
				" accents et de tirets (-). Il commence par une lettre minuscule sans accent.",
266
			'resultat' => false);
267
 
268
		// Réalisation du test
269
		$noms_erreur = array();
270
		foreach ($noms as $nom) {
271
			if ($nom['type_epithete'] != '') {
272
				if (!preg_match('/^[a-z][-a-z]*[.]?$/', $nom['type_epithete'])) {
273
					$noms_erreur[] = array($nom['num_nom'],  $nom['type_epithete']);
274
				}
275
			}
276
		}
277
 
278
		// Analyse des résultats
279
		if (count($noms_erreur) > 0) {
280
			$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
281
			$info['message']['lignes'] = $noms_erreur;
282
		} else {
283
			$info['resultat'] = true;
284
		}
285
 
286
		return $info;
287
	}
288
 
289
	private function testerTypeEpitheteHybridite($noms) {
290
		$info = array('titre' => 'type_epithete -> hybridité',
291
			'description' => "Le champ type_epithete ne doit pas contenir de préfixe indiquant l'hybridité comme : \n".
292
				" - «n-» \n".
293
				" - «notho-» \n",
294
			'resultat' => false);
295
 
296
		// Réalisation du test
297
		$noms_erreur = array();
298
		foreach ($noms as $nom) {
299
			if ($nom['type_epithete'] != '') {
300
				if (preg_match('/^(?:n-|notho-)/', $nom['type_epithete'])) {
301
					$noms_erreur[] = array($nom['num_nom'], $nom['type_epithete']);
302
				}
303
			}
304
		}
305
 
306
		// Analyse des résultats
307
		if (count($noms_erreur) > 0) {
308
			$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
309
			$info['message']['lignes'] = $noms_erreur;
310
		} else {
311
			$info['resultat'] = true;
312
		}
313
 
314
		return $info;
315
	}
316
 
6 jpm 317
	private function testerNombreDeChamps($colonnes) {
318
		$info = array('titre' => 'Structure -> nombre de champs : %s',
319
			'description' => 'Le nombre de champs présent dans la table doit être supérieur ou égal à 35.',
320
			'resultat' => false);
321
 
322
		$nbre_colonnes = count($colonnes);
323
		$info['titre'] = sprintf($info['titre'], $nbre_colonnes);
324
		if ($nbre_colonnes >= 35) {
325
			$info['resultat'] = true;
326
		}
327
		return $info;
328
	}
329
 
330
	private function testerNomDesChamps($colonnes) {
331
		$info = array('titre' => 'Structure -> noms des champs',
332
			'description' => 'Les champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
333
			'resultat' => false);
334
 
335
		$champs_attendus = explode(',', $this->manuel['champs']);
336
		$champs_presents = array();
337
		foreach ($colonnes as $colonne) {
338
			$champs_presents[$colonne['Field']] = $colonne;
339
		}
340
 
341
		$ok = true;
342
		$champs_manquant = array();
343
		foreach ($champs_attendus as $champ_attendu) {
344
			if (!isset($champs_presents[$champ_attendu])) {
345
				$champs_manquant[] = $champ_attendu;
346
				$ok = false;
347
			}
348
		}
349
		$info['resultat'] = $ok;
350
		if (!$ok) {
351
			$info['message'] = 'Champs manquant : '.implode(', ', $champs_manquant).'.';
352
		}
353
 
354
		return $info;
355
	}
356
 
357
	private function testerTypeDesChamps($colonnes) {
358
		$info = array('titre' => 'Structure -> types des champs',
359
			'description' => 'Les types des champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
360
			'resultat' => false);
361
 
362
		$champs_attendus = explode(',', $this->manuel['champs_type']);
363
		$champs_presents = array();
364
		foreach ($colonnes as $colonne) {
365
			$champs_presents[$colonne['Field']] = $colonne['Type'];
366
		}
367
 
368
		// Recercherche des erreurs
369
		$champs_erreur = array();
370
		foreach ($champs_attendus as $champ_attendu) {
371
			list($champ_attendu_nom, $champ_attendu_type) = explode('=', trim($champ_attendu));
372
 
373
			if (isset($champs_presents[$champ_attendu_nom])) {
374
				$champs_present_type = $champs_presents[$champ_attendu_nom];
375
 
376
				if (($champ_attendu_type == 'VARCHAR' && strstr($champs_present_type, 'varchar') === false)
377
					|| ($champ_attendu_type == 'TEXT' && strstr($champs_present_type, 'text') === false)
378
					|| ($champ_attendu_type == 'INT' && strstr($champs_present_type, 'int') === false)
379
					|| ($champ_attendu_type == 'BOOL' && preg_match('/(?:bool|boolean|tinyint\(1\))/i', $champs_present_type) === false)) {
380
					$champs_erreur[] = $champ_attendu." vaut ".$champs_present_type;
381
				}
382
			}
383
		}
384
 
385
		// Analyse des résultats
386
		if (count($champs_erreur) > 0) {
387
			$info['message'] = "Champs n'ayant pas un bon type : ".implode(', ', $champs_erreur).'.';
388
		} else {
389
			$info['resultat'] = true;
390
		}
391
 
392
		return $info;
393
	}
394
 
395
	private function testerTailleDesChamps($colonnes, $analyses) {
396
		$info = array('titre' => 'Structure -> champs tronqués',
397
			'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.",
398
			'resultat' => false);
399
 
400
		$tailles_champs_maxi = array();
401
		foreach ($colonnes as $colonne) {
402
			if (preg_match('/^varchar\(([0-9]+)\)$/', $colonne['Type'], $match)) {
403
				$tailles_champs_maxi[$colonne['Field']] = $match[1];
404
			}
405
		}
406
 
407
		$tailles_trouvees = array();
408
		foreach ($analyses as $analyse) {
409
			if (preg_match('/\.([^.]+)$/', $analyse['Field_name'], $match)) {
410
				$tailles_trouvees[$match[1]] = $analyse['Max_length'];
411
			}
412
		}
413
 
414
		$champs_erreur = array();
415
		$champs_attendus = explode(',', $this->manuel['champs']);
416
		foreach ($champs_attendus as $champ_attendu) {
417
			if (isset($tailles_champs_maxi[$champ_attendu]) && isset($tailles_trouvees[$champ_attendu])) {
418
				if ($tailles_champs_maxi[$champ_attendu] == $tailles_trouvees[$champ_attendu]) {
419
					$champs_erreur[] = $champ_attendu;
420
				}
421
			}
422
		}
423
 
424
		// Analyse des résultats
425
		if (count($champs_erreur) > 0) {
426
			$info['message'] = "Champs possédant des enregistrements avec une taille maximum : ".implode(', ', $champs_erreur).'.';
427
		} else {
428
			$info['resultat'] = true;
429
		}
430
 
431
		return $info;
432
	}
433
 
434
	private function testerNumNomClePrimaire($colonnes) {
435
		$info = array('titre' => 'Structure -> num_nom est clé primaire',
436
			'description' => "Vérifie que le champ num_nom est bien la clé primaire de la table.",
437
			'resultat' => false);
438
 
439
		foreach ($colonnes as $colonne) {
440
			if ($colonne['Field'] == 'num_nom' && $colonne['Key'] == 'PRI') {
441
				$info['resultat'] = true;
442
			}
443
		}
444
 
445
		return $info;
446
	}
447
 
448
	private function testerNumNomSuperieurAZero($noms) {
449
		$info = array('titre' => 'num_nom -> supérieur à 0',
450
			'description' => "Le champ num_nom doit contenir des nombres entiers supérieurs à 0.",
451
			'resultat' => false);
452
 
453
		// Réalisation du test
454
		$noms_erreur = array();
455
		foreach ($noms as $nom) {
456
			if ($nom['num_nom'] <= 0) {
457
				$noms_erreur[] = $nom['num_nom'];
458
			}
459
		}
460
 
461
		// Analyse des résultats
462
		if (count($noms_erreur) > 0) {
463
			$info['message'] = count($noms_erreur)." enregistrements contiennent dans le champ num_nom une valeur inférieure ou égale à 0.";
464
		} else {
465
			$info['resultat'] = true;
466
		}
467
 
468
		return $info;
469
	}
470
 
471
	private function testerNumNomRetenuSuperieurAZero($noms) {
472
		$info = array('titre' => 'num_nom_retenu -> supérieur à 0',
473
			'description' => "Le champ num_nom_retenu doit contenir des nombres entiers supérieurs à 0.",
474
			'resultat' => false);
475
 
476
		// Réalisation du test
477
		$noms_erreur = array();
478
		foreach ($noms as $nom) {
479
			if ($nom['num_nom_retenu'] <= 0) {
480
				$noms_erreur[] = $nom['num_nom'];
481
			}
482
		}
483
 
484
		// Analyse des résultats
485
		if (count($noms_erreur) > 0) {
486
			$info['message'] = count($noms_erreur)." enregistrements dont le champ num_nom_retenu est inférieur ou égal à 0 : ".implode(', ', $noms_erreur).'.';
487
		} else {
488
			$info['resultat'] = true;
489
		}
490
 
491
		return $info;
492
	}
493
 
494
	private function testerNumTaxSupEgalZeroUnique($noms) {
495
		$info = array('titre' => 'num_tax_sup -> égal à 0 unique',
496
			'description' => "Un seul enregistrement doit posséder la valeur 0 dans le champ num_tax_sup. Il correspond au premier taxon de la classification.",
497
			'resultat' => false);
498
 
499
		// Réalisation du test
500
		$noms_erreur = array();
501
		foreach ($noms as $nom) {
502
			if (preg_match('/^0$/', $nom['num_tax_sup'])) {
503
				$noms_erreur[] = $nom['num_nom'];
504
			}
505
		}
506
 
507
		// Analyse des résultats
508
		if (count($noms_erreur) > 1) {
509
			$info['message'] = count($noms_erreur)." enregistrements ont une valeur de 0 dans le champ num_tax_sup : ".implode(', ', $noms_erreur).'.';
510
		} else {
511
			$info['resultat'] = true;
512
		}
513
 
514
		return $info;
515
	}
516
 
517
	private function testerTaxSupPourTaxon($noms) {
518
		$info = array('titre' => 'Classification -> uniquement pour les taxons',
519
			'description' => "Seul les enregistrements représentant un taxon doivent posséder une valeur dans le champ num_tax_sup.",
520
			'resultat' => false);
521
 
522
		// Réalisation du test
523
		$noms_erreur = array();
524
		foreach ($noms as $nom) {
525
			if ($nom['num_nom_retenu'] == $nom['num_nom'] && preg_match('/^[0-9]+$/', $nom['num_tax_sup'])) {
526
				$noms_erreur[] = $nom['num_nom'];
527
			}
528
		}
529
 
530
		// Analyse des résultats
531
		if (count($noms_erreur) > 0) {
532
			$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).'.';
533
		} else {
534
			$info['resultat'] = true;
535
		}
536
 
537
		return $info;
538
	}
539
 
540
	private function testerExitenceTaxonSuperieur($noms) {
541
		$info = array('titre' => 'Classification -> existence du taxon supérieur',
542
			'description' => "Pour chaque enregistrement représentant un taxon doit posséder un taxon supérieur sauf la racine de la classification.",
543
			'resultat' => false);
544
 
545
		// Réalisation du test
546
		$noms_erreur = array();
547
		foreach ($noms as $nom) {
548
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
549
				if ($nom['num_tax_sup'] != 0 && !isset($noms[$nom['num_tax_sup']])) {
550
					$noms_erreur[] = $nom['num_nom'];
551
				}
552
			}
553
		}
554
 
555
		// Analyse des résultats
556
		if (count($noms_erreur) > 0) {
557
			$info['message'] = count($noms_erreur)." enregistrements dont le taxon supérieur n'existe pas : ".implode(', ', $noms_erreur).'.';
558
		} else {
559
			$info['resultat'] = true;
560
		}
561
 
562
		return $info;
563
	}
564
 
565
	private function testerClassificationRang($noms) {
566
		$info = array('titre' => 'Classification -> taxon supérieur avec rang inférieur',
567
			'description' => "Pour chaque enregistrement représentant un taxon, chaque taxon supérieur doit avoir un rang inférieur au taxon courant.",
568
			'resultat' => false);
569
 
570
		// Réalisation du test
571
		$noms_erreur = array();
572
		foreach ($noms as $nom) {
573
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
574
				if (isset($noms[$nom['num_tax_sup']])) {
575
					$nom_sup = $noms[$nom['num_tax_sup']];
576
					if ($nom_sup['rang'] > $nom['rang']) {
577
						$noms_erreur[] = $nom['num_nom'];
578
					}
579
				}
580
			}
581
		}
582
 
583
		// Analyse des résultats
584
		if (count($noms_erreur) > 0) {
585
			$info['message'] = count($noms_erreur)." enregistrements avec un problème : ".implode(', ', $noms_erreur).'.';
586
		} else {
587
			$info['resultat'] = true;
588
		}
589
 
590
		return $info;
591
	}
592
 
593
	private function testerClassification($noms) {
594
		$info = array('titre' => 'Classification -> racine liée à chaque noeud',
595
			'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.",
596
			'resultat' => false);
597
 
598
		// Réalisation du test
599
		$noms_erreur = array();
600
		foreach ($noms as $nom) {
601
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
602
				$classif_ok = $this->remonterClassif($noms, $nom);
603
				if ($classif_ok === false) {
604
					$noms_erreur[] = $nom['num_nom'];
605
				}
606
			}
607
		}
608
 
609
		// Analyse des résultats
610
		if (count($noms_erreur) > 0) {
611
			$info['message'] = count($noms_erreur)." taxons dont la classification n'est pas bonne : ".implode(', ', $noms_erreur).'.';
612
		} else {
613
			$info['resultat'] = true;
614
		}
615
 
616
		return $info;
617
	}
618
 
619
	private function remonterClassif(&$noms, $nom) {
620
		if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] == '0') {
621
			return true;
622
		} else if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] != '0') {
623
			return false;
624
		} else {
625
			return $this->remonterClassif($noms, $noms[$nom['num_tax_sup']]);
626
		}
627
	}
628
 
629
	private function testerRang($noms) {
630
		$info = array('titre' => 'rang',
631
			'description' => "Le rang doit correspondre à un valeur numérique définit dans le manuel.",
632
			'resultat' => false);
633
 
634
		$rangs = array_flip(explode(',', $this->manuel['rangs']));
635
 
636
		// Réalisation du test
637
		$noms_erreur = array();
638
		foreach ($noms as $nom) {
639
			if (!isset($rangs[$nom['rang']])) {
640
				$noms_erreur[] = $nom['num_nom'];
641
			}
642
		}
643
 
644
		// Analyse des résultats
645
		if (count($noms_erreur) > 0) {
646
			$info['message'] = count($noms_erreur)." noms dont le rang n'est pas bon : ".implode(', ', $noms_erreur).'.';
647
		} else {
648
			$info['resultat'] = true;
649
		}
650
 
651
		return $info;
652
	}
653
 
654
	private function testerNomCompletSupraGenerique($noms) {
655
		$info = array('titre' => 'nom_complet -> noms supra-génériques',
656
			'description' => "Si le rang est < à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ nom_supra_generique. ".
657
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
658
			'resultat' => false);
659
 
660
		// Réalisation du test
661
		$noms_erreur = array();
662
		foreach ($noms as $nom) {
663
			if ($nom['rang'] < $this->manuel['rang_genre']) {
664
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
665
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['nom_supra_generique']);
666
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
667
				if ($nom['nom_complet'] != $nom_complet_ideal) {
668
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
669
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
670
				}
671
			}
672
		}
673
 
674
		// Analyse des résultats
675
		if (count($noms_erreur) > 0) {
676
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
677
			$info['message']['lignes'] = $noms_erreur;
678
		} else {
679
			$info['resultat'] = true;
680
		}
681
 
682
		return $info;
683
	}
684
 
685
	private function testerNomCompletGenre($noms) {
686
		$info = array('titre' => 'nom_complet -> noms de genres',
687
			'description' => "Si le rang est = à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ genre. ".
688
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
689
			'resultat' => false);
690
 
691
		// Réalisation du test
692
		$noms_erreur = array();
693
		foreach ($noms as $nom) {
694
			if ($nom['rang'] == $this->manuel['rang_genre']) {
695
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
696
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
697
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
698
				if ($nom['nom_complet'] != $nom_complet_ideal) {
699
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
700
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
701
				}
702
			}
703
		}
704
 
705
		// Analyse des résultats
706
		if (count($noms_erreur) > 0) {
707
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
708
			$info['message']['lignes'] = $noms_erreur;
709
		} else {
710
			$info['resultat'] = true;
711
		}
712
 
713
		return $info;
714
	}
715
 
716
	private function testerNomCompletInfraGenre($noms) {
717
		$info = array('titre' => 'nom_complet -> noms infra-génériques',
718
			'description' => "Si le rang est > à {$this->manuel['rang_genre']} et < à {$this->manuel['rang_sp']} le nom_complet doit correspondre à une des formules suivantes : \n".
719
			" genre + ' ' + type_epithete + ' ' + epithete_infra_generique \n".
720
			" genre + ' ' + epithete_infra_generique + ' ' + type_epithete=agg. \n".
721
			"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
722
			'resultat' => false);
723
 
724
		// Réalisation du test
725
		$noms_erreur = array();
726
		foreach ($noms as $nom) {
727
			if ($nom['rang'] > $this->manuel['rang_genre'] && $nom['rang'] < $this->manuel['rang_sp']) {
728
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
729
				$nom_complet_ideal = '';
730
				if ($nom['type_epithete'] == 'agg.') {
731
					$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
732
					$nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
733
					$nom_complet_ideal .= ' '.$nom['type_epithete'];
734
				} else {
735
					$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
736
					$nom_complet_ideal .= ' '.$nom['type_epithete'];
737
					$nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
738
				}
739
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
740
				if ($nom['nom_complet'] != $nom_complet_ideal) {
741
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
742
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
743
				}
744
			}
745
		}
746
 
747
		// Analyse des résultats
748
		if (count($noms_erreur) > 0) {
749
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
750
			$info['message']['lignes'] = $noms_erreur;
751
		} else {
752
			$info['resultat'] = true;
753
		}
754
 
755
		return $info;
756
	}
757
 
758
	private function testerNomCompletEspece($noms) {
759
		$info = array('titre' => "nom_complet -> noms d'espèce",
760
			'description' => "Si le rang est = à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
761
				" genre + ' ' + epithete_sp \n".
762
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
763
			'resultat' => false);
764
 
765
		// Réalisation du test
766
		$noms_erreur = array();
767
		foreach ($noms as $nom) {
768
			if ($nom['rang'] == $this->manuel['rang_sp']) {
769
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
770
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
771
				$nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
772
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
773
				if ($nom['nom_complet'] != $nom_complet_ideal) {
774
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
775
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
776
				}
777
			}
778
		}
779
 
780
		// Analyse des résultats
781
		if (count($noms_erreur) > 0) {
782
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
783
			$info['message']['lignes'] = $noms_erreur;
784
		} else {
785
			$info['resultat'] = true;
786
		}
787
 
788
		return $info;
789
	}
790
 
791
	private function testerNomCompletInfraSpecifique($noms) {
792
		$info = array('titre' => 'nom_complet -> noms infra-spécifiques',
793
			'description' => "Si le rang est > à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
794
				" genre + ' ' + epithete_sp + ' ' + type_epithete + ' ' + epithete_infra_generique\n".
795
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
796
			'resultat' => false);
797
 
798
		// Réalisation du test
799
		$noms_erreur = array();
800
		foreach ($noms as $nom) {
801
			if ($nom['rang'] > $this->manuel['rang_sp']) {
802
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
803
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
804
				$nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
805
				$nom_complet_ideal .= ' '.strtolower($nom['type_epithete']);
806
				$nom_complet_ideal .= ' '.strtolower($nom['epithete_infra_sp']);
807
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
808
				if ($nom['nom_complet'] != $nom_complet_ideal) {
809
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
810
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
811
				}
812
			}
813
		}
814
 
815
		// Analyse des résultats
816
		if (count($noms_erreur) > 0) {
817
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
818
			$info['message']['lignes'] = $noms_erreur;
819
		} else {
820
			$info['resultat'] = true;
821
		}
822
 
823
		return $info;
824
	}
825
 
12 jpm 826
	private function testerNomSupraGeneriqueEspaces($noms) {
827
		$info = array('titre' => 'nom_supra_generique -> espaces en trop',
828
			'description' => "Le champ nom_supra_generique ne doit pas contenir d'espace avant ou aprés le nom.",
6 jpm 829
			'resultat' => false);
830
 
831
		// Réalisation du test
832
		$noms_erreur = array();
833
		foreach ($noms as $nom) {
834
			if ($nom['nom_supra_generique'] != '') {
12 jpm 835
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s+$)/', $nom['nom_supra_generique'])) {
6 jpm 836
					$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
837
					$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
838
				}
839
			}
840
		}
841
 
842
		// Analyse des résultats
843
		if (count($noms_erreur) > 0) {
844
			$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
845
			$info['message']['lignes'] = $noms_erreur;
846
		} else {
847
			$info['resultat'] = true;
848
		}
849
 
850
		return $info;
851
	}
852
 
12 jpm 853
	private function testerNomSupraGeneriqueSyntaxe($noms) {
854
		$info = array('titre' => 'nom_supra_generique -> syntaxe',
855
			'description' => "Le champ nom_supra_generique contient un mot composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
856
				"La première lettre (avec ou sans tréma) du mot doit être en majuscule.",
6 jpm 857
			'resultat' => false);
858
 
859
		// Réalisation du test
860
		$noms_erreur = array();
861
		foreach ($noms as $nom) {
862
			if ($nom['nom_supra_generique'] != '') {
12 jpm 863
				if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+$/', $nom['nom_supra_generique'])) {
6 jpm 864
					$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
865
					$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
866
				}
867
			}
868
		}
869
 
870
		// Analyse des résultats
871
		if (count($noms_erreur) > 0) {
872
			$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
873
			$info['message']['lignes'] = $noms_erreur;
874
		} else {
875
			$info['resultat'] = true;
876
		}
877
 
878
		return $info;
879
	}
880
 
12 jpm 881
	private function testerNomSupraGeneriqueRang($noms) {
882
		$info = array('titre' => "nom_supra_generique -> rang < {$this->manuel['rang_genre']}",
883
			'description' => "Si le champ nom_supra_generique n'est pas vide alors le rang du nom doit être inférieur à {$this->manuel['rang_genre']}.",
884
			'resultat' => false);
885
 
886
		// Réalisation du test
887
		$noms_erreur = array();
888
		foreach ($noms as $nom) {
889
			if ($nom['nom_supra_generique'] != '') {
890
				if ($nom['rang'] >= $this->manuel['rang_genre']) {
891
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
892
				}
893
			}
894
		}
895
 
896
		// Analyse des résultats
897
		if (count($noms_erreur) > 0) {
898
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
899
			$info['message']['lignes'] = $noms_erreur;
900
		} else {
901
			$info['resultat'] = true;
902
		}
903
 
904
		return $info;
905
	}
906
 
907
	private function testerGenreEspaces($noms) {
908
		$info = array('titre' => 'genre -> espaces en trop',
909
			'description' => "Le champ genre ne doit pas contenir d'espace avant ou aprés le nom.\n".
910
				"Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
911
			'resultat' => false);
912
 
913
		// Réalisation du test
914
		$noms_erreur = array();
915
		foreach ($noms as $nom) {
916
			if ($nom['genre'] != '') {
917
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['genre'])) {
918
					$nom_traite = $this->repererEspace($nom['genre']);
919
					$noms_erreur[] = array($nom['num_nom'], $nom_traite);
920
				}
921
			}
922
		}
923
 
924
		// Analyse des résultats
925
		if (count($noms_erreur) > 0) {
926
			$info['message']['entete'] = array('num_nom', 'genre erroné');
927
			$info['message']['lignes'] = $noms_erreur;
928
		} else {
929
			$info['resultat'] = true;
930
		}
931
 
932
		return $info;
933
	}
934
 
935
	private function testerGenreSyntaxe($noms) {
936
		$info = array('titre' => 'genre -> syntaxe',
937
			'description' => "Le champ genre peut contenir :\n".
938
			 	" - un mot unique composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
939
				"	Il commence par une lettre majuscule (avec ou sans tréma).".
940
				"	Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
941
				" - une formule d'hybridité composée d'une série de noms de genre (au moins 2) séparés entre eux \n".
942
				"	par la lettre x entourée de caractères espaces.",
943
			'resultat' => false);
944
 
945
		// Réalisation du test
946
		$noms_erreur = array();
947
		foreach ($noms as $nom) {
948
			if ($nom['genre'] != '') {
949
				$mots = explode(' ', $nom['genre']);
950
				foreach ($mots as $mot) {
951
					if (!(preg_match('/^[+x]$/', $mot) || preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+/', $mot))) {
952
						$nom_traite = $this->repererEspace($nom['genre']);
953
						$noms_erreur[] = array($nom['num_nom'], $nom_traite);
954
					}
955
				}
956
			}
957
		}
958
 
959
		// Analyse des résultats
960
		if (count($noms_erreur) > 0) {
961
			$info['message']['entete'] = array('num_nom', 'genre erroné');
962
			$info['message']['lignes'] = $noms_erreur;
963
		} else {
964
			$info['resultat'] = true;
965
		}
966
 
967
		return $info;
968
	}
969
 
970
	private function testerGenreRang($noms) {
971
		$info = array('titre' => "genre -> rang >= {$this->manuel['rang_genre']}",
972
			'description' => "Si le champ genre n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_genre']}.",
973
			'resultat' => false);
974
 
975
		// Réalisation du test
976
		$noms_erreur = array();
977
		foreach ($noms as $nom) {
978
			if ($nom['genre'] != '') {
979
				if ($nom['rang'] < $this->manuel['rang_genre']) {
980
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
981
				}
982
			}
983
		}
984
 
985
		// Analyse des résultats
986
		if (count($noms_erreur) > 0) {
987
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
988
			$info['message']['lignes'] = $noms_erreur;
989
		} else {
990
			$info['resultat'] = true;
991
		}
992
 
993
		return $info;
994
	}
995
 
996
	private function testerEpitheteInfraGeneriqueSyntaxe($noms) {
997
		$info = array('titre' => 'epithete_infra_generique -> syntaxe',
998
			'description' => "Le champ epithete_infra_generique est composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
999
				"La première lettre (avec ou sans tréma) doit être en majuscule.",
1000
			'resultat' => false);
1001
 
1002
		// Réalisation du test
1003
		$noms_erreur = array();
1004
		foreach ($noms as $nom) {
1005
			if ($nom['epithete_infra_generique'] != '') {
1006
				if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+/', $nom['epithete_infra_generique'])) {
1007
					$epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
1008
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1009
				}
1010
			}
1011
		}
1012
 
1013
		// Analyse des résultats
1014
		if (count($noms_erreur) > 0) {
1015
			$info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
1016
			$info['message']['lignes'] = $noms_erreur;
1017
		} else {
1018
			$info['resultat'] = true;
1019
		}
1020
 
1021
		return $info;
1022
	}
1023
 
1024
	private function testerEpitheteInfraGeneriqueRang($noms) {
1025
		$info = array('titre' => "epithete_infra_generique -> {$this->manuel['rang_genre']} < rang < {$this->manuel['rang_sp']}",
1026
			'description' => "Si le champ epithete_infra_generique n'est pas vide alors le rang du nom doit être compris \n".
1027
				"entre {$this->manuel['rang_genre']} et {$this->manuel['rang_sp']}.",
1028
			'resultat' => false);
1029
 
1030
		// Réalisation du test
1031
		$noms_erreur = array();
1032
		foreach ($noms as $nom) {
1033
			if ($nom['epithete_infra_generique'] != '') {
1034
				if ($nom['rang'] <= $this->manuel['rang_genre'] || $nom['rang'] >= $this->manuel['rang_sp']) {
1035
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
1036
				}
1037
			}
1038
		}
1039
 
1040
		// Analyse des résultats
1041
		if (count($noms_erreur) > 0) {
1042
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
1043
			$info['message']['lignes'] = $noms_erreur;
1044
		} else {
1045
			$info['resultat'] = true;
1046
		}
1047
 
1048
		return $info;
1049
	}
1050
 
1051
	private function testerEpitheteInfraGeneriqueEspaces($noms) {
1052
		$info = array('titre' => 'epithete_infra_generique -> espaces en trop',
1053
			'description' => "Le champ epithete_infra_generique ne doit pas contenir d'espace avant ou aprés sa valeur.",
1054
			'resultat' => false);
1055
 
1056
		// Réalisation du test
1057
		$noms_erreur = array();
1058
		foreach ($noms as $nom) {
1059
			if ($nom['epithete_infra_generique'] != '') {
1060
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_generique'])) {
1061
					$epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
1062
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1063
				}
1064
			}
1065
		}
1066
 
1067
		// Analyse des résultats
1068
		if (count($noms_erreur) > 0) {
1069
			$info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
1070
			$info['message']['lignes'] = $noms_erreur;
1071
		} else {
1072
			$info['resultat'] = true;
1073
		}
1074
 
1075
		return $info;
1076
	}
1077
 
1078
	private function testerEpitheteSpEspaces($noms) {
1079
		$info = array('titre' => 'epithete_sp -> espaces en trop',
1080
			'description' => "Le champ epithete_sp ne doit pas contenir d'espace avant ou aprés le nom.\n".
1081
				"Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
1082
			'resultat' => false);
1083
 
1084
		// Réalisation du test
1085
		$noms_erreur = array();
1086
		foreach ($noms as $nom) {
1087
			if ($nom['epithete_sp'] != '') {
1088
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_sp'])) {
1089
					$epithete_traite = $this->repererEspace($nom['epithete_sp']);
1090
					$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1091
				}
1092
			}
1093
		}
1094
 
1095
		// Analyse des résultats
1096
		if (count($noms_erreur) > 0) {
1097
			$info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
1098
			$info['message']['lignes'] = $noms_erreur;
1099
		} else {
1100
			$info['resultat'] = true;
1101
		}
1102
 
1103
		return $info;
1104
	}
1105
 
1106
	private function testerEpitheteSpSyntaxe($noms) {
1107
		$info = array('titre' => 'epithete_sp -> syntaxe',
1108
			'description' => "Le champ epithete_sp peut contenir :\n".
1109
			 	" - un mot unique composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
1110
				"	Il commence par une lettre minuscule (avec ou sans tréma).\n".
1111
				"	Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
1112
				" - 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".
1113
				" - une formule d'hybridité composée d'une série de noms d'espèce (au moins 2) séparés entre eux \n".
1114
				"	par la lettre x entourée de caractères espaces.",
1115
			'resultat' => false);
1116
 
1117
		// Réalisation du test
1118
		$noms_erreur = array();
1119
		foreach ($noms as $nom) {
1120
			if ($nom['epithete_sp'] != '') {
1121
				$mots = explode(' ', $nom['epithete_sp']);
1122
				foreach ($mots as $mot) {
1123
					if (!(preg_match('/^[+x]$/', $mot) || $this->verifierEpithteSp($mot))) {
1124
						$epithete_traite = $this->repererEspace($nom['epithete_sp']);
1125
						$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
1126
					}
1127
				}
1128
			}
1129
		}
1130
 
1131
		// Analyse des résultats
1132
		if (count($noms_erreur) > 0) {
1133
			$info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
1134
			$info['message']['lignes'] = $noms_erreur;
1135
		} else {
1136
			$info['resultat'] = true;
1137
		}
1138
 
1139
		return $info;
1140
	}
1141
 
1142
	private function testerEpitheteSpRang($noms) {
1143
		$info = array('titre' => "epithete_sp -> rang >= {$this->manuel['rang_sp']}",
1144
			'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']}.",
1145
			'resultat' => false);
1146
 
1147
		// Réalisation du test
1148
		$noms_erreur = array();
1149
		foreach ($noms as $nom) {
1150
			if ($nom['epithete_sp'] != '') {
1151
				if ($nom['rang'] < $this->manuel['rang_sp']) {
1152
					$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
1153
				}
1154
			}
1155
		}
1156
 
1157
		// Analyse des résultats
1158
		if (count($noms_erreur) > 0) {
1159
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
1160
			$info['message']['lignes'] = $noms_erreur;
1161
		} else {
1162
			$info['resultat'] = true;
1163
		}
1164
 
1165
		return $info;
1166
	}
1167
 
1168
	//+--------------------------------------------------------------------------------------------------------------+//
1169
	// MÉTHODES COMMUNES aux TESTS
1170
 
1171
	private function verifierTypeEpithete($type) {
1172
		$ok = true;
1173
		if (!preg_match('/^[a-z][-a-z]*[.]?$/', $type)) {
1174
			$ok = false;
1175
		}
1176
		return $ok;
1177
	}
1178
 
1179
	private function verifierEpithteSp($epithete) {
1180
		$ok = false;
1181
		if (preg_match('/^[a-zäëḧïöẗüẅẍÿ][-a-zäëḧïöẗüẅẍÿ]+$/', $epithete)) {
1182
			$ok = true;
1183
		} else if (preg_match('/^sp\.(?:[A-Z]|[1-9][0-9]*)$/', $epithete)) {
1184
			$ok = true;
1185
		}
1186
		return $ok;
1187
	}
1188
 
6 jpm 1189
	private function formaterStyleNomGenre($genre) {
1190
		$genre_fmt = '';
1191
		if (preg_match('/^\s*([x+])\s+(.+)$/i', $genre, $match)) {
1192
			$genre_fmt = strtolower($match[1]).' '.ucfirst(strtolower($match[2]));
1193
		} else {
1194
			$genre_fmt = ucfirst(strtolower($genre));
1195
		}
1196
		return $genre_fmt;
1197
	}
1198
 
1199
	private function repererEspace($nom_complet) {
1200
		$nom_complet = str_replace(' ', '<span class="espace">&nbsp;</span>', $nom_complet);
1201
		return $nom_complet;
1202
	}
1203
 
1204
	private function construireSuffixeNomPltCultivee($nom) {
1205
		$suffixe = array();
1206
		$suffixe[] = $this->construireNomCultivarGroupe($nom);
1207
		$suffixe[] = $this->construireNomCommercial($nom);
1208
		$suffixe[] = $this->construireNomCultivar($nom);
1209
		$suffixe = array_filter($suffixe);
1210
		return implode(' ', $suffixe);
1211
	}
1212
 
1213
	private function construireNomCultivarGroupe($nom) {
1214
		$nom_groupe_cultivar = '';
1215
		if ($nom['cultivar_groupe'] != '') {
1216
			if (preg_match('/ gx$/', $nom['cultivar_groupe'])) {
1217
				$nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].')';
1218
			} else {
1219
				$nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].' Gp)';
1220
			}
1221
		}
1222
		return $nom_groupe_cultivar;
1223
	}
1224
 
1225
	private function construireNomCommercial($nom) {
1226
		$nom_commercial = '';
1227
		if ($nom['nom_commercial'] != '') {
1228
			$nom_commercial =  strtoupper($nom['nom_commercial']);
1229
		}
1230
		return $nom_commercial;
1231
	}
1232
 
1233
	private function construireNomCultivar($nom) {
1234
		$nom_cultivar = '';
1235
		if ($nom['cultivar'] != '') {
1236
			$nom_cultivar =  "'".$nom['cultivar']."'";
1237
		}
1238
		return $nom_cultivar;
1239
	}
1240
 
12 jpm 1241
	private function classerNoms($noms) {
1242
		$noms_classes = array();
1243
		foreach ($noms as $nom) {
1244
			$noms_classes[$nom['num_nom']] = $nom;
1245
		}
1246
		return $noms_classes;
1247
	}
6 jpm 1248
}
1249
?>