Subversion Repositories Applications.referentiel

Rev

Rev 12 | Go to most recent revision | Details | 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
55
		$donnees['tests'][] = $this->testerNombreDeChamps($colonnes);
56
		$donnees['tests'][] = $this->testerNomDesChamps($colonnes);
57
		$donnees['tests'][] = $this->testerTypeDesChamps($colonnes);
58
		$donnees['tests'][] = $this->testerTailleDesChamps($colonnes, $analyses);
59
		$donnees['tests'][] = $this->testerNumNomClePrimaire($colonnes);
60
		$donnees['tests'][] = $this->testerNumNomSuperieurAZero($noms);
61
		$donnees['tests'][] = $this->testerNumNomRetenuSuperieurAZero($noms);
62
		$donnees['tests'][] = $this->testerNumTaxSupEgalZeroUnique($noms);
63
		$donnees['tests'][] = $this->testerTaxSupPourTaxon($noms);
64
		$donnees['tests'][] = $this->testerExitenceTaxonSuperieur($noms);
65
		$donnees['tests'][] = $this->testerClassificationRang($noms);
66
		$donnees['tests'][] = $this->testerClassification($noms);
67
		$donnees['tests'][] = $this->testerRang($noms);
68
		$donnees['tests'][] = $this->testerNomCompletSupraGenerique($noms);
69
		$donnees['tests'][] = $this->testerNomCompletGenre($noms);
70
		$donnees['tests'][] = $this->testerNomCompletInfraGenre($noms);
71
		$donnees['tests'][] = $this->testerNomCompletEspece($noms);
72
		$donnees['tests'][] = $this->testerNomCompletInfraSpecifique($noms);
73
		$donnees['tests'][] = $this->testerNomSupraGeneriqueMotUnique($noms);
74
		$donnees['tests'][] = $this->testerNomSupraGeneriqueEspaces($noms);
75
 
76
		//Debug::printr($this->manuel);
77
		$this->setSortie(self::RENDU_CORPS, $this->getVue('test', $donnees));
78
	}
79
 
80
	private function classerNoms($noms) {
81
		$noms_classes = array();
82
		foreach ($noms as $nom) {
83
			$noms_classes[$nom['num_nom']] = $nom;
84
		}
85
		return $noms_classes;
86
	}
87
 
88
	private function testerNombreDeChamps($colonnes) {
89
		$info = array('titre' => 'Structure -> nombre de champs : %s',
90
			'description' => 'Le nombre de champs présent dans la table doit être supérieur ou égal à 35.',
91
			'resultat' => false);
92
 
93
		$nbre_colonnes = count($colonnes);
94
		$info['titre'] = sprintf($info['titre'], $nbre_colonnes);
95
		if ($nbre_colonnes >= 35) {
96
			$info['resultat'] = true;
97
		}
98
		return $info;
99
	}
100
 
101
	private function testerNomDesChamps($colonnes) {
102
		$info = array('titre' => 'Structure -> noms des champs',
103
			'description' => 'Les champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
104
			'resultat' => false);
105
 
106
		$champs_attendus = explode(',', $this->manuel['champs']);
107
		$champs_presents = array();
108
		foreach ($colonnes as $colonne) {
109
			$champs_presents[$colonne['Field']] = $colonne;
110
		}
111
 
112
		$ok = true;
113
		$champs_manquant = array();
114
		foreach ($champs_attendus as $champ_attendu) {
115
			if (!isset($champs_presents[$champ_attendu])) {
116
				$champs_manquant[] = $champ_attendu;
117
				$ok = false;
118
			}
119
		}
120
		$info['resultat'] = $ok;
121
		if (!$ok) {
122
			$info['message'] = 'Champs manquant : '.implode(', ', $champs_manquant).'.';
123
		}
124
 
125
		return $info;
126
	}
127
 
128
	private function testerTypeDesChamps($colonnes) {
129
		$info = array('titre' => 'Structure -> types des champs',
130
			'description' => 'Les types des champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
131
			'resultat' => false);
132
 
133
		$champs_attendus = explode(',', $this->manuel['champs_type']);
134
		$champs_presents = array();
135
		foreach ($colonnes as $colonne) {
136
			$champs_presents[$colonne['Field']] = $colonne['Type'];
137
		}
138
 
139
		// Recercherche des erreurs
140
		$champs_erreur = array();
141
		foreach ($champs_attendus as $champ_attendu) {
142
			list($champ_attendu_nom, $champ_attendu_type) = explode('=', trim($champ_attendu));
143
 
144
			if (isset($champs_presents[$champ_attendu_nom])) {
145
				$champs_present_type = $champs_presents[$champ_attendu_nom];
146
 
147
				if (($champ_attendu_type == 'VARCHAR' && strstr($champs_present_type, 'varchar') === false)
148
					|| ($champ_attendu_type == 'TEXT' && strstr($champs_present_type, 'text') === false)
149
					|| ($champ_attendu_type == 'INT' && strstr($champs_present_type, 'int') === false)
150
					|| ($champ_attendu_type == 'BOOL' && preg_match('/(?:bool|boolean|tinyint\(1\))/i', $champs_present_type) === false)) {
151
					$champs_erreur[] = $champ_attendu." vaut ".$champs_present_type;
152
				}
153
			}
154
		}
155
 
156
		// Analyse des résultats
157
		if (count($champs_erreur) > 0) {
158
			$info['message'] = "Champs n'ayant pas un bon type : ".implode(', ', $champs_erreur).'.';
159
		} else {
160
			$info['resultat'] = true;
161
		}
162
 
163
		return $info;
164
	}
165
 
166
	private function testerTailleDesChamps($colonnes, $analyses) {
167
		$info = array('titre' => 'Structure -> champs tronqués',
168
			'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.",
169
			'resultat' => false);
170
 
171
		$tailles_champs_maxi = array();
172
		foreach ($colonnes as $colonne) {
173
			if (preg_match('/^varchar\(([0-9]+)\)$/', $colonne['Type'], $match)) {
174
				$tailles_champs_maxi[$colonne['Field']] = $match[1];
175
			}
176
		}
177
 
178
		$tailles_trouvees = array();
179
		foreach ($analyses as $analyse) {
180
			if (preg_match('/\.([^.]+)$/', $analyse['Field_name'], $match)) {
181
				$tailles_trouvees[$match[1]] = $analyse['Max_length'];
182
			}
183
		}
184
 
185
		$champs_erreur = array();
186
		$champs_attendus = explode(',', $this->manuel['champs']);
187
		foreach ($champs_attendus as $champ_attendu) {
188
			if (isset($tailles_champs_maxi[$champ_attendu]) && isset($tailles_trouvees[$champ_attendu])) {
189
				if ($tailles_champs_maxi[$champ_attendu] == $tailles_trouvees[$champ_attendu]) {
190
					$champs_erreur[] = $champ_attendu;
191
				}
192
			}
193
		}
194
 
195
		// Analyse des résultats
196
		if (count($champs_erreur) > 0) {
197
			$info['message'] = "Champs possédant des enregistrements avec une taille maximum : ".implode(', ', $champs_erreur).'.';
198
		} else {
199
			$info['resultat'] = true;
200
		}
201
 
202
		return $info;
203
	}
204
 
205
	private function testerNumNomClePrimaire($colonnes) {
206
		$info = array('titre' => 'Structure -> num_nom est clé primaire',
207
			'description' => "Vérifie que le champ num_nom est bien la clé primaire de la table.",
208
			'resultat' => false);
209
 
210
		foreach ($colonnes as $colonne) {
211
			if ($colonne['Field'] == 'num_nom' && $colonne['Key'] == 'PRI') {
212
				$info['resultat'] = true;
213
			}
214
		}
215
 
216
		return $info;
217
	}
218
 
219
	private function testerNumNomSuperieurAZero($noms) {
220
		$info = array('titre' => 'num_nom -> supérieur à 0',
221
			'description' => "Le champ num_nom doit contenir des nombres entiers supérieurs à 0.",
222
			'resultat' => false);
223
 
224
		// Réalisation du test
225
		$noms_erreur = array();
226
		foreach ($noms as $nom) {
227
			if ($nom['num_nom'] <= 0) {
228
				$noms_erreur[] = $nom['num_nom'];
229
			}
230
		}
231
 
232
		// Analyse des résultats
233
		if (count($noms_erreur) > 0) {
234
			$info['message'] = count($noms_erreur)." enregistrements contiennent dans le champ num_nom une valeur inférieure ou égale à 0.";
235
		} else {
236
			$info['resultat'] = true;
237
		}
238
 
239
		return $info;
240
	}
241
 
242
	private function testerNumNomRetenuSuperieurAZero($noms) {
243
		$info = array('titre' => 'num_nom_retenu -> supérieur à 0',
244
			'description' => "Le champ num_nom_retenu doit contenir des nombres entiers supérieurs à 0.",
245
			'resultat' => false);
246
 
247
		// Réalisation du test
248
		$noms_erreur = array();
249
		foreach ($noms as $nom) {
250
			if ($nom['num_nom_retenu'] <= 0) {
251
				$noms_erreur[] = $nom['num_nom'];
252
			}
253
		}
254
 
255
		// Analyse des résultats
256
		if (count($noms_erreur) > 0) {
257
			$info['message'] = count($noms_erreur)." enregistrements dont le champ num_nom_retenu est inférieur ou égal à 0 : ".implode(', ', $noms_erreur).'.';
258
		} else {
259
			$info['resultat'] = true;
260
		}
261
 
262
		return $info;
263
	}
264
 
265
	private function testerNumTaxSupEgalZeroUnique($noms) {
266
		$info = array('titre' => 'num_tax_sup -> égal à 0 unique',
267
			'description' => "Un seul enregistrement doit posséder la valeur 0 dans le champ num_tax_sup. Il correspond au premier taxon de la classification.",
268
			'resultat' => false);
269
 
270
		// Réalisation du test
271
		$noms_erreur = array();
272
		foreach ($noms as $nom) {
273
			if (preg_match('/^0$/', $nom['num_tax_sup'])) {
274
				$noms_erreur[] = $nom['num_nom'];
275
			}
276
		}
277
 
278
		// Analyse des résultats
279
		if (count($noms_erreur) > 1) {
280
			$info['message'] = count($noms_erreur)." enregistrements ont une valeur de 0 dans le champ num_tax_sup : ".implode(', ', $noms_erreur).'.';
281
		} else {
282
			$info['resultat'] = true;
283
		}
284
 
285
		return $info;
286
	}
287
 
288
	private function testerTaxSupPourTaxon($noms) {
289
		$info = array('titre' => 'Classification -> uniquement pour les taxons',
290
			'description' => "Seul les enregistrements représentant un taxon doivent posséder une valeur dans le champ num_tax_sup.",
291
			'resultat' => false);
292
 
293
		// Réalisation du test
294
		$noms_erreur = array();
295
		foreach ($noms as $nom) {
296
			if ($nom['num_nom_retenu'] == $nom['num_nom'] && preg_match('/^[0-9]+$/', $nom['num_tax_sup'])) {
297
				$noms_erreur[] = $nom['num_nom'];
298
			}
299
		}
300
 
301
		// Analyse des résultats
302
		if (count($noms_erreur) > 0) {
303
			$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).'.';
304
		} else {
305
			$info['resultat'] = true;
306
		}
307
 
308
		return $info;
309
	}
310
 
311
	private function testerExitenceTaxonSuperieur($noms) {
312
		$info = array('titre' => 'Classification -> existence du taxon supérieur',
313
			'description' => "Pour chaque enregistrement représentant un taxon doit posséder un taxon supérieur sauf la racine de la classification.",
314
			'resultat' => false);
315
 
316
		// Réalisation du test
317
		$noms_erreur = array();
318
		foreach ($noms as $nom) {
319
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
320
				if ($nom['num_tax_sup'] != 0 && !isset($noms[$nom['num_tax_sup']])) {
321
					$noms_erreur[] = $nom['num_nom'];
322
				}
323
			}
324
		}
325
 
326
		// Analyse des résultats
327
		if (count($noms_erreur) > 0) {
328
			$info['message'] = count($noms_erreur)." enregistrements dont le taxon supérieur n'existe pas : ".implode(', ', $noms_erreur).'.';
329
		} else {
330
			$info['resultat'] = true;
331
		}
332
 
333
		return $info;
334
	}
335
 
336
	private function testerClassificationRang($noms) {
337
		$info = array('titre' => 'Classification -> taxon supérieur avec rang inférieur',
338
			'description' => "Pour chaque enregistrement représentant un taxon, chaque taxon supérieur doit avoir un rang inférieur au taxon courant.",
339
			'resultat' => false);
340
 
341
		// Réalisation du test
342
		$noms_erreur = array();
343
		foreach ($noms as $nom) {
344
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
345
				if (isset($noms[$nom['num_tax_sup']])) {
346
					$nom_sup = $noms[$nom['num_tax_sup']];
347
					if ($nom_sup['rang'] > $nom['rang']) {
348
						$noms_erreur[] = $nom['num_nom'];
349
					}
350
				}
351
			}
352
		}
353
 
354
		// Analyse des résultats
355
		if (count($noms_erreur) > 0) {
356
			$info['message'] = count($noms_erreur)." enregistrements avec un problème : ".implode(', ', $noms_erreur).'.';
357
		} else {
358
			$info['resultat'] = true;
359
		}
360
 
361
		return $info;
362
	}
363
 
364
	private function testerClassification($noms) {
365
		$info = array('titre' => 'Classification -> racine liée à chaque noeud',
366
			'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.",
367
			'resultat' => false);
368
 
369
		// Réalisation du test
370
		$noms_erreur = array();
371
		foreach ($noms as $nom) {
372
			if ($nom['num_nom_retenu'] == $nom['num_nom']) {
373
				$classif_ok = $this->remonterClassif($noms, $nom);
374
				if ($classif_ok === false) {
375
					$noms_erreur[] = $nom['num_nom'];
376
				}
377
			}
378
		}
379
 
380
		// Analyse des résultats
381
		if (count($noms_erreur) > 0) {
382
			$info['message'] = count($noms_erreur)." taxons dont la classification n'est pas bonne : ".implode(', ', $noms_erreur).'.';
383
		} else {
384
			$info['resultat'] = true;
385
		}
386
 
387
		return $info;
388
	}
389
 
390
	private function remonterClassif(&$noms, $nom) {
391
		if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] == '0') {
392
			return true;
393
		} else if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] != '0') {
394
			return false;
395
		} else {
396
			return $this->remonterClassif($noms, $noms[$nom['num_tax_sup']]);
397
		}
398
	}
399
 
400
	private function testerRang($noms) {
401
		$info = array('titre' => 'rang',
402
			'description' => "Le rang doit correspondre à un valeur numérique définit dans le manuel.",
403
			'resultat' => false);
404
 
405
		$rangs = array_flip(explode(',', $this->manuel['rangs']));
406
 
407
		// Réalisation du test
408
		$noms_erreur = array();
409
		foreach ($noms as $nom) {
410
			if (!isset($rangs[$nom['rang']])) {
411
				$noms_erreur[] = $nom['num_nom'];
412
			}
413
		}
414
 
415
		// Analyse des résultats
416
		if (count($noms_erreur) > 0) {
417
			$info['message'] = count($noms_erreur)." noms dont le rang n'est pas bon : ".implode(', ', $noms_erreur).'.';
418
		} else {
419
			$info['resultat'] = true;
420
		}
421
 
422
		return $info;
423
	}
424
 
425
	private function testerNomCompletSupraGenerique($noms) {
426
		$info = array('titre' => 'nom_complet -> noms supra-génériques',
427
			'description' => "Si le rang est < à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ nom_supra_generique. ".
428
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
429
			'resultat' => false);
430
 
431
		// Réalisation du test
432
		$noms_erreur = array();
433
		foreach ($noms as $nom) {
434
			if ($nom['rang'] < $this->manuel['rang_genre']) {
435
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
436
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['nom_supra_generique']);
437
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
438
				if ($nom['nom_complet'] != $nom_complet_ideal) {
439
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
440
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
441
				}
442
			}
443
		}
444
 
445
		// Analyse des résultats
446
		if (count($noms_erreur) > 0) {
447
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
448
			$info['message']['lignes'] = $noms_erreur;
449
		} else {
450
			$info['resultat'] = true;
451
		}
452
 
453
		return $info;
454
	}
455
 
456
	private function testerNomCompletGenre($noms) {
457
		$info = array('titre' => 'nom_complet -> noms de genres',
458
			'description' => "Si le rang est = à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ genre. ".
459
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
460
			'resultat' => false);
461
 
462
		// Réalisation du test
463
		$noms_erreur = array();
464
		foreach ($noms as $nom) {
465
			if ($nom['rang'] == $this->manuel['rang_genre']) {
466
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
467
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
468
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
469
				if ($nom['nom_complet'] != $nom_complet_ideal) {
470
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
471
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
472
				}
473
			}
474
		}
475
 
476
		// Analyse des résultats
477
		if (count($noms_erreur) > 0) {
478
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
479
			$info['message']['lignes'] = $noms_erreur;
480
		} else {
481
			$info['resultat'] = true;
482
		}
483
 
484
		return $info;
485
	}
486
 
487
	private function testerNomCompletInfraGenre($noms) {
488
		$info = array('titre' => 'nom_complet -> noms infra-génériques',
489
			'description' => "Si le rang est > à {$this->manuel['rang_genre']} et < à {$this->manuel['rang_sp']} le nom_complet doit correspondre à une des formules suivantes : \n".
490
			" genre + ' ' + type_epithete + ' ' + epithete_infra_generique \n".
491
			" genre + ' ' + epithete_infra_generique + ' ' + type_epithete=agg. \n".
492
			"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
493
			'resultat' => false);
494
 
495
		// Réalisation du test
496
		$noms_erreur = array();
497
		foreach ($noms as $nom) {
498
			if ($nom['rang'] > $this->manuel['rang_genre'] && $nom['rang'] < $this->manuel['rang_sp']) {
499
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
500
				$nom_complet_ideal = '';
501
				if ($nom['type_epithete'] == 'agg.') {
502
					$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
503
					$nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
504
					$nom_complet_ideal .= ' '.$nom['type_epithete'];
505
				} else {
506
					$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
507
					$nom_complet_ideal .= ' '.$nom['type_epithete'];
508
					$nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
509
				}
510
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
511
				if ($nom['nom_complet'] != $nom_complet_ideal) {
512
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
513
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
514
				}
515
			}
516
		}
517
 
518
		// Analyse des résultats
519
		if (count($noms_erreur) > 0) {
520
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
521
			$info['message']['lignes'] = $noms_erreur;
522
		} else {
523
			$info['resultat'] = true;
524
		}
525
 
526
		return $info;
527
	}
528
 
529
	private function testerNomCompletEspece($noms) {
530
		$info = array('titre' => "nom_complet -> noms d'espèce",
531
			'description' => "Si le rang est = à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
532
				" genre + ' ' + epithete_sp \n".
533
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
534
			'resultat' => false);
535
 
536
		// Réalisation du test
537
		$noms_erreur = array();
538
		foreach ($noms as $nom) {
539
			if ($nom['rang'] == $this->manuel['rang_sp']) {
540
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
541
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
542
				$nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
543
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
544
				if ($nom['nom_complet'] != $nom_complet_ideal) {
545
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
546
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
547
				}
548
			}
549
		}
550
 
551
		// Analyse des résultats
552
		if (count($noms_erreur) > 0) {
553
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
554
			$info['message']['lignes'] = $noms_erreur;
555
		} else {
556
			$info['resultat'] = true;
557
		}
558
 
559
		return $info;
560
	}
561
 
562
	private function testerNomCompletInfraSpecifique($noms) {
563
		$info = array('titre' => 'nom_complet -> noms infra-spécifiques',
564
			'description' => "Si le rang est > à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
565
				" genre + ' ' + epithete_sp + ' ' + type_epithete + ' ' + epithete_infra_generique\n".
566
				"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
567
			'resultat' => false);
568
 
569
		// Réalisation du test
570
		$noms_erreur = array();
571
		foreach ($noms as $nom) {
572
			if ($nom['rang'] > $this->manuel['rang_sp']) {
573
				$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
574
				$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
575
				$nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
576
				$nom_complet_ideal .= ' '.strtolower($nom['type_epithete']);
577
				$nom_complet_ideal .= ' '.strtolower($nom['epithete_infra_sp']);
578
				$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
579
				if ($nom['nom_complet'] != $nom_complet_ideal) {
580
					$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
581
					$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
582
				}
583
			}
584
		}
585
 
586
		// Analyse des résultats
587
		if (count($noms_erreur) > 0) {
588
			$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
589
			$info['message']['lignes'] = $noms_erreur;
590
		} else {
591
			$info['resultat'] = true;
592
		}
593
 
594
		return $info;
595
	}
596
 
597
	private function testerNomSupraGeneriqueMotUnique($noms) {
598
		$info = array('titre' => 'nom_supra_generique -> plusieurs mots',
599
			'description' => "Le champ nom_supra_generique doit contenir un seul mot.",
600
			'resultat' => false);
601
 
602
		// Réalisation du test
603
		$noms_erreur = array();
604
		foreach ($noms as $nom) {
605
			if ($nom['nom_supra_generique'] != '') {
606
				$mots = explode(' ', trim($nom['nom_supra_generique']));
607
				if (count($mots) > 1) {
608
					$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
609
					$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
610
				}
611
			}
612
		}
613
 
614
		// Analyse des résultats
615
		if (count($noms_erreur) > 0) {
616
			$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
617
			$info['message']['lignes'] = $noms_erreur;
618
		} else {
619
			$info['resultat'] = true;
620
		}
621
 
622
		return $info;
623
	}
624
 
625
	private function testerNomSupraGeneriqueEspaces($noms) {
626
		$info = array('titre' => 'nom_supra_generique -> espaces en trop',
627
			'description' => "Le champ nom_supra_generique ne doit pas contenir d'espace avant ou aprés le nom.",
628
			'resultat' => false);
629
 
630
		// Réalisation du test
631
		$noms_erreur = array();
632
		foreach ($noms as $nom) {
633
			if ($nom['nom_supra_generique'] != '') {
634
				if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s+$)/', $nom['nom_supra_generique'])) {
635
					$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
636
					$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
637
				}
638
			}
639
		}
640
 
641
		// Analyse des résultats
642
		if (count($noms_erreur) > 0) {
643
			$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
644
			$info['message']['lignes'] = $noms_erreur;
645
		} else {
646
			$info['resultat'] = true;
647
		}
648
 
649
		return $info;
650
	}
651
 
652
	private function formaterStyleNomGenre($genre) {
653
		$genre_fmt = '';
654
		if (preg_match('/^\s*([x+])\s+(.+)$/i', $genre, $match)) {
655
			$genre_fmt = strtolower($match[1]).' '.ucfirst(strtolower($match[2]));
656
		} else {
657
			$genre_fmt = ucfirst(strtolower($genre));
658
		}
659
		return $genre_fmt;
660
	}
661
 
662
	private function repererEspace($nom_complet) {
663
		$nom_complet = str_replace(' ', '<span class="espace">&nbsp;</span>', $nom_complet);
664
		return $nom_complet;
665
	}
666
 
667
	private function construireSuffixeNomPltCultivee($nom) {
668
		$suffixe = array();
669
		$suffixe[] = $this->construireNomCultivarGroupe($nom);
670
		$suffixe[] = $this->construireNomCommercial($nom);
671
		$suffixe[] = $this->construireNomCultivar($nom);
672
		$suffixe = array_filter($suffixe);
673
		return implode(' ', $suffixe);
674
	}
675
 
676
	private function construireNomCultivarGroupe($nom) {
677
		$nom_groupe_cultivar = '';
678
		if ($nom['cultivar_groupe'] != '') {
679
			if (preg_match('/ gx$/', $nom['cultivar_groupe'])) {
680
				$nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].')';
681
			} else {
682
				$nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].' Gp)';
683
			}
684
		}
685
		return $nom_groupe_cultivar;
686
	}
687
 
688
	private function construireNomCommercial($nom) {
689
		$nom_commercial = '';
690
		if ($nom['nom_commercial'] != '') {
691
			$nom_commercial =  strtoupper($nom['nom_commercial']);
692
		}
693
		return $nom_commercial;
694
	}
695
 
696
	private function construireNomCultivar($nom) {
697
		$nom_cultivar = '';
698
		if ($nom['cultivar'] != '') {
699
			$nom_cultivar =  "'".$nom['cultivar']."'";
700
		}
701
		return $nom_cultivar;
702
	}
703
 
704
}
705
?>