Subversion Repositories Applications.referentiel

Rev

Rev 167 | Rev 173 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
// Encodage : UTF-8
// +-------------------------------------------------------------------------------------------------------------------+
/**
* Tests de référentiels de nomenclature et taxonomie
*
* Description : classe permettant de tester les référentiels selon le manuel technique
* Utilisation : php script.php tests -p bdnff -a tout
*
//Auteur original :
* @author       Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @copyright    Tela-Botanica 1999-2010
* @link                 http://www.tela-botanica.org/wikini/RTaxMethodo/wakka.php?wiki=MaNuel
* @licence              GPL v3 & CeCILL v2
* @version              $Id$
*/
// +-------------------------------------------------------------------------------------------------------------------+
// TODO : supprimer l'utilisation du paramêtres 'p' et chercher les infos depuis la bdd
class Tests extends ScriptCommande {
        
        const SCRIPT_NOM = 'tests';
        
        private $projet = null;
        private $traitement = null;
        
        private $manuel = null;
        private $tests = null;
        private $colonnes = null;
        private $analyses = null;
        private $noms = null;
        
        private $resultatDao = null;
        private $traitementDao = null;
        private $tableStructureDao = null;
        private $referentielDao = null;
        
        public function executer() {
                $this->manuel = parse_ini_file(Config::get('chemin_appli').DS.'..'.DS.'configurations'.DS.'referentiel_v4.1.ini');
                $this->tests = parse_ini_file($this->getModuleChemin().DS.'configurations'.DS.'tests.ini', true);
                
                $this->resultatDao = new ResultatDao();
                $this->traitementDao = new TraitementDao();
                Debug::printr('Dans le script test');
                // Récupération du dernier traitement demandé
                $this->traitement = $this->traitementDao->getDernierTraitement('tout', self::SCRIPT_NOM);
                if (isset($this->traitement)) {
                        $this->projet = $this->traitement['referentiel_code']; // Récupération du nom de projet
                        Debug::printr($this->traitement);
                        // Écriture de la date de début du traitement
                        Debug::printr('Debute:'.$this->traitementDao->debuterTraitement($this->traitement['id_traitement']));
                        
                        // Nettoyage des traitements obsolètes
                        $traitements_obsoletes = $this->traitementDao->getTraitementsObsoletes($this->projet, self::SCRIPT_NOM);
                        if (isset($traitements_obsoletes)) {
                                Debug::printr('Supp. obsoletes:'.$this->traitementDao->supprimer($traitements_obsoletes));
                        }
                        
                        $this->tableStructureDao = new TableStructureDao();
                        $this->referentielDao = new ReferentielDao();
                        
                        // Lancement du test demandé
                        $cmd = $this->getParam('a');
                switch ($cmd) {
                                case 'tout' :
                                        Debug::printr('Départ lancement test:');
                                        $this->recupererDonnees();
                                        $this->lancerTests();
                                        break;
                                case 'test11' :
                                        $this->recupererDonnees();
                                        Debug::printr('Départ lancement test 11 :');
                                        $this->testerClassificationRang();
                                        break;
                                default :
                                        $this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
                        }
                        // Écriture de la date de fin du traitement
                        Debug::printr('Termine:'.$this->traitementDao->terminerTraitement($this->traitement['id_traitement']));
                } else {
                        Debug::printr("Aucun dernier traitement trouvé pour le script '".self::SCRIPT_NOM."' !");
                }
    }
    
    public function recupererDonnees() {
                // Récupération des données à tester
                $this->colonnes = $this->tableStructureDao->getColonnes($this->projet);
                $this->analyses = $this->tableStructureDao->getAnalyse($this->projet);
                $this->noms = $this->referentielDao->getTout($this->projet);
                Debug::printr('Nbre noms :'.count($this->noms));
    }
    
    public function lancerTests() {
                // Lancement des tests unitaires
                $resultats = array();
                $resultats[] = $this->testerNombreDeChamps($this->colonnes);
                $resultats[] = $this->testerNomDesChamps($this->colonnes);
                $resultats[] = $this->testerTypeDesChamps($this->colonnes);
                $resultats[] = $this->testerNumNomClePrimaire($this->colonnes);
                
                // Si la structure est bonne nous lançons les autres tests
                Debug::printr($resultats);
                if ($this->verifierResultats($resultats)) {
                        $this->testerTailleDesChamps($this->colonnes, $this->analyses);
                        
                        $this->testerNumNomSuperieurAZero();
                        
                        $this->testerNumNomRetenuSuperieurAZero();
                        $this->testerNumTaxSupEgalZeroUnique();
                        $this->testerTaxSupPourTaxon();
                        $this->testerExitenceTaxonSuperieur();
                        $this->testerClassificationRang();      
                        $this->testerClassification();
                        
                        $this->testerRang();
                        
                        $this->testerNomCompletSupraGenerique();
                        $this->testerNomCompletGenre();
                        $this->testerNomCompletInfraGenre();
                        $this->testerNomCompletEspece();
                        $this->testerNomCompletInfraSpecifique();
        
                        $this->testerNomSupraGeneriqueEspaces();
                        $this->testerNomSupraGeneriqueSyntaxe();
                        $this->testerNomSupraGeneriqueRang();
                        
                        $this->testerGenreEspaces();
                        $this->testerGenreSyntaxe();
                        $this->testerGenreRang();
                        
                        $this->testerEpitheteInfraGeneriqueEspaces();
                        $this->testerEpitheteInfraGeneriqueSyntaxe();
                        $this->testerEpitheteInfraGeneriqueRang();
                        
                        $this->testerEpitheteSpEspaces();
                        $this->testerEpitheteSpSyntaxe();
                        $this->testerEpitheteSpRang();
                        
                        $this->testerTypeEpitheteEspaces();
                        $this->testerTypeEpitheteSyntaxe();
                        $this->testerTypeEpitheteHybridite();
                        
                        $this->testerEpitheteInfraSpEspaces();
                        $this->testerEpitheteInfraSpSyntaxe();
                        $this->testerEpitheteInfraSpRang();
                        
                        $this->testerGroupeCultivarSyntaxe();
                        $this->testerGroupeCultivarRang();              
                        
                        $this->testerCultivarSyntaxe();
                        $this->testerCultivarRang();
                        
                        $this->testerNomCommercialSyntaxe();
                        $this->testerNomCommercialPresenceCultivar();
                        
                        $this->testerAuteurSyntaxe();
                        
                        $this->testerAnneeSyntaxe();
                        
                        $this->testerBiblioOrigineSyntaxe();
                        
                        $this->testerHomonymieSyntaxe();
                        $this->testerHomonymieExistence();
                        
                        $this->testerBasionymeSyntaxe();
                        $this->testerBasionymeExistence();
                        
                        $this->testerSynonymeProparteSyntaxe();
                        $this->testerSynonymeProparteExistence();
                        
                        $this->testerSynonymeDouteuxSyntaxe();
                        $this->testerSynonymeDouteuxNumNomRetenu();
                        
                        $this->testerSynonymeMalAppliqueSyntaxe();
                        
                        $this->testerSynonymeOrthographiqueSyntaxe();
                        $this->testerSynonymeOrthographiqueExistence();
                        
                        $this->testerHybrideParent01Syntaxe();
                        $this->testerHybrideParent01Existence();
                        $this->testerHybrideParent02Syntaxe();
                        $this->testerHybrideParent02Existence();
                        
                        $this->testerPresenceSyntaxe();
                        $this->testerStatutOrigineSyntaxe();
                        $this->testerStatutIntroductionSyntaxe();
                        $this->testerStatutCultureSyntaxe();
                        $this->testerExclureTaxRefSyntaxe();
                }
        }
        private function verifierResultats($resultats) {
                $ok = true;
                foreach ($resultats as $resultat) {
                        if ($resultat == '0') {
                                $ok = false;
                                break;
                        }
                }
                return $ok;
        }
        
        //+--------------------------------------------------------------------------------------------------------------+//
        // Enregistrement des résultats
        private function traiterResultatTest($info) {
                Debug::printr($info['nom']);
                if (isset($info['message'])) {
                        if (is_array($info['message'])) {
                                $info['message'] = $this->getVue('tests/squelettes/message_table', $info);
                        } else {
                                $info['message'] = $this->getVue('tests/squelettes/message_p', $info);
                        }
                }
                $this->resultatDao->ajouter($this->traitement['id_traitement'], $info);
                $info = null;
        }
        
        //+--------------------------------------------------------------------------------------------------------------+//
        // TESTS
        
        /**
         * Test #01
         */
        private function testerNombreDeChamps($colonnes) {
                $info = $this->getInfosTest(1);
                
                $nbre_colonnes = count($colonnes);
                $info['message'] = $nbre_colonnes;
                if ($nbre_colonnes >= 35) {
                        $info['resultat'] = true;
                }
                $this->traiterResultatTest($info);
                return ($info['resultat'] ? '1' : '0');
        }
        
        /**
         * Test #02
         */
        private function testerNomDesChamps($colonnes) {
                $info = $this->getInfosTest(2);
                
                $champs_attendus = explode(',', $this->manuel['champs']);
                $champs_presents = array();
                foreach ($colonnes as $colonne) {
                        $champs_presents[$colonne['Field']] = $colonne;
                }
                
                $ok = true;
                $champs_manquant = array(); 
                foreach ($champs_attendus as $champ_attendu) {
                        if (!isset($champs_presents[$champ_attendu])) {
                                $champs_manquant[] = $champ_attendu; 
                                $ok = false;
                        }
                }
                $info['resultat'] = $ok;
                if (!$ok) {
                        $info['message'] = sprintf($info['message'], implode(', ', $champs_manquant));
                }
                
                $this->traiterResultatTest($info);
                return ($info['resultat'] ? '1' : '0');
        }
        
        /**
         * Test #03
         */
        private function testerTypeDesChamps($colonnes) {
                $info = $this->getInfosTest(3);
                
                $champs_attendus = explode(',', $this->manuel['champs_type']);
                $champs_presents = array();
                foreach ($colonnes as $colonne) {
                        $champs_presents[$colonne['Field']] = $colonne['Type'];
                }
                
                // Recercherche des erreurs
                $champs_erreur = array(); 
                foreach ($champs_attendus as $champ_attendu) {
                        list($champ_attendu_nom, $champ_attendu_type_taille) = explode('=', trim($champ_attendu));
                        list($champ_attendu_type, $champ_attendu_taille) = explode('|', trim($champ_attendu_type_taille));
                        
                        if (isset($champs_presents[$champ_attendu_nom])) {
                                $champs_present_type = $champs_presents[$champ_attendu_nom];
                                
                                if (($champ_attendu_type == 'VARCHAR' && strstr($champs_present_type, 'varchar') === false)
                                        || ($champ_attendu_type == 'TEXT' && strstr($champs_present_type, 'text') === false)
                                        || ($champ_attendu_type == 'INT' && strstr($champs_present_type, 'int') === false) 
                                        || ($champ_attendu_type == 'BOOL' && preg_match('/(?:bool|boolean|tinyint\(1\))/i', $champs_present_type) === false)) {
                                        $champs_erreur[] = $champ_attendu." vaut ".$champs_present_type;
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($champs_erreur) > 0) {
                        $info['message'] = sprintf($info['message'], implode(', ', $champs_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
                return ($info['resultat'] ? '1' : '0');
        }
        
        /**
         * Test #04
         */
        private function testerNumNomClePrimaire($colonnes) {
                $info = $this->getInfosTest(4);
                
                foreach ($colonnes as $colonne) {
                        if ($colonne['Field'] == 'num_nom' && $colonne['Key'] == 'PRI') {
                                $info['resultat'] = true;
                        }
                }
                
                $this->traiterResultatTest($info);
                return ($info['resultat'] ? '1' : '0');
        }
        
        
        /**
         * Test #05
         */
        private function testerTailleDesChamps($colonnes, $analyses) {
                $info = $this->getInfosTest(5);
                
                $tailles_champs_maxi = array();
                foreach ($colonnes as $colonne) {
                        if (preg_match('/^varchar\(([0-9]+)\)$/', $colonne['Type'], $match)) {
                                $tailles_champs_maxi[$colonne['Field']] = $match[1];
                        }
                }
                
                $tailles_trouvees = array();
                foreach ($analyses as $analyse) {
                        if (preg_match('/\.([^.]+)$/', $analyse['Field_name'], $match)) {
                                $tailles_trouvees[$match[1]] = $analyse['Max_length'];
                        }
                }
                
                $champs_erreur = array();
                $champs_attendus = explode(',', $this->manuel['champs']);
                foreach ($champs_attendus as $champ_attendu) {
                        if (isset($tailles_champs_maxi[$champ_attendu]) && isset($tailles_trouvees[$champ_attendu])) {
                                if ($tailles_champs_maxi[$champ_attendu] == $tailles_trouvees[$champ_attendu]) {
                                        $champs_erreur[] = $champ_attendu;
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($champs_erreur) > 0) {
                        $info['message'] = sprintf($info['message'], implode(', ', $champs_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
                
        /**
         * Test #06
         */
        private function testerNumNomSuperieurAZero() {
                $info = $this->getInfosTest(6);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['num_nom'] <= 0) {
                                $noms_erreur[] = $nom['num_nom'];
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = sprintf($info['message'], count($noms_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #07
         */
        private function testerNumNomRetenuSuperieurAZero() {
                $info = $this->getInfosTest(7);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['num_nom_retenu'] != '' && $nom['num_nom_retenu'] <= 0) {
                                $noms_erreur[] = $nom['num_nom'];
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = sprintf($info['message'], count($noms_erreur), implode(', ', $noms_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #08
         */
        private function testerNumTaxSupEgalZeroUnique() {
                $info = $this->getInfosTest(8);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if (preg_match('/^0$/', $nom['num_tax_sup'])) {
                                $noms_erreur[] = $nom['num_nom'];
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 1) {
                        $info['message'] = sprintf($info['message'], count($noms_erreur), implode(', ', $noms_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #09
         */
        private function testerTaxSupPourTaxon() {
                $info = $this->getInfosTest(9);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['num_nom_retenu'] != $nom['num_nom'] && $nom['num_tax_sup'] != '') {
                                $noms_erreur[] = $nom['num_nom']; 
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = sprintf($info['message'], count($noms_erreur), implode(', ', $noms_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #10
         */
        private function testerExitenceTaxonSuperieur() {
                $info = $this->getInfosTest(10);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['num_nom_retenu'] == $nom['num_nom']) {
                                if ($nom['num_tax_sup'] != 0 && !isset($this->noms[$nom['num_tax_sup']])) {
                                        $noms_erreur[] = $nom['num_nom'];
                                } 
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = sprintf($info['message'], count($noms_erreur), implode(', ', $noms_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #11
         */
        private function testerClassificationRang() {
                $info = $this->getInfosTest(11);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['num_nom_retenu'] == $nom['num_nom']) {
                                if (isset($this->noms[$nom['num_tax_sup']])) {
                                        $nom_sup = $this->noms[$nom['num_tax_sup']];
                                        if ($nom_sup['rang'] >= $nom['rang']) {
                                                // Prise en compte de l'exception des clades
                                                if (! ($nom_sup['rang'] == 70 && $nom['rang'] == 70)) {
                                                        $noms_erreur[] = $nom['num_nom'];
                                                }
                                        }
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = sprintf($info['message'], count($noms_erreur), implode(', ', $noms_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #12
         */
        private function testerClassification() {
                $info = $this->getInfosTest(12);
                
                // Réalisation du test
                $noms_erreur = array();
                $this->noms_ok = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['num_nom_retenu'] == $nom['num_nom']) {
                                if (isset($this->noms_ok[$nom['num_tax_sup']])) {
                                        $this->noms_ok[$nom['num_nom']] = true;
                                } else {
                                        $this->detection_boucle_infini = array();
                                        $classif_ok = $this->remonterClassif($nom);
                                        unset($this->detection_boucle_infini); 
                                        
                                        if ($classif_ok === false) {
                                                $noms_erreur[] = $nom['num_nom'];
                                        } else {
                                                $this->noms_ok[$nom['num_nom']] = $classif_ok;
                                        }
                                }
                        }
                }
                unset($this->noms_ok);
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = sprintf($info['message'], count($noms_erreur), implode(', ', $noms_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function remonterClassif(&$nom) {
                $this->detection_boucle_infini[$nom['num_nom']] = true;
                if (preg_match('/^[0-9]*$/', $nom['num_tax_sup'])) {
                        if (isset($this->noms_ok[$nom['num_tax_sup']])) {
                                $this->noms_ok[$nom['num_nom']] = true;
                                return true;
                        } else if (!isset($this->noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] == '0') {
                                $this->noms_ok[$nom['num_nom']] = true;
                                return true;
                        } else if (!isset($this->noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] != '0') {
                                return false;
                        } else if (isset($this->detection_boucle_infini[$nom['num_tax_sup']])) {
                                return false;
                        } else {
                                $retour = $this->remonterClassif($this->noms[$nom['num_tax_sup']]);
                                if ($retour === true) {
                                        $this->noms_ok[$nom['num_tax_sup']] = true;
                                }
                                return $retour;
                        }
                } else {
                        return false;
                }
        }
        
        /**
         * Test #13
         */
        private function testerRang() {
                $info = $this->getInfosTest(13);
                
                $rangs = array_flip(explode(',', $this->manuel['rangs']));
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if (!isset($rangs[$nom['rang']])) {
                                $noms_erreur[] = $nom['num_nom'];
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = sprintf($info['message'], count($noms_erreur), implode(', ', $noms_erreur));
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #14
         */
        private function testerNomCompletSupraGenerique() {
                $info = $this->getInfosTest(14);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_genre']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['rang'] < $this->manuel['rang_genre']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_sci_ideal = $this->formaterStyleNomGenre($nom['nom_supra_generique']);
                                $nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_sci'] != $nom_sci_ideal) {
                                        $nom_sci_traite = $this->repererEspace($nom['nom_sci']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #15
         */
        private function testerNomCompletGenre() {
                $info = $this->getInfosTest(15);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_genre']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['rang'] == $this->manuel['rang_genre']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                $nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_sci'] != $nom_sci_ideal) {
                                        $nom_sci_traite = $this->repererEspace($nom['nom_sci']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #16
         */
        private function testerNomCompletInfraGenre() {
                $info = $this->getInfosTest(16);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_genre'], $this->manuel['rang_sp']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['rang'] > $this->manuel['rang_genre'] && $nom['rang'] < $this->manuel['rang_sp']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_sci_ideal = '';
                                if ($nom['type_epithete'] == 'agg.') {
                                        $nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                        $nom_sci_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
                                        $nom_sci_ideal .= ' '.$nom['type_epithete'];
                                } else {
                                        $nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                        $nom_sci_ideal .= ' '.$nom['type_epithete'];
                                        $nom_sci_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
                                }
                                $nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_sci'] != $nom_sci_ideal) {
                                        $nom_sci_traite = $this->repererEspace($nom['nom_sci']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #17
         */
        private function testerNomCompletEspece() {
                $info = $this->getInfosTest(17);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_sp']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['rang'] == $this->manuel['rang_sp']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                $nom_sci_ideal .= ' '.strtolower($nom['epithete_sp']);
                                $nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_sci'] != $nom_sci_ideal) {
                                        $nom_sci_traite = $this->repererEspace($nom['nom_sci']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #18
         */
        private function testerNomCompletInfraSpecifique() {
                $info = $this->getInfosTest(18);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_sp']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['rang'] > $this->manuel['rang_sp']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_sci_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                $nom_sci_ideal .= ' '.strtolower($nom['epithete_sp']);
                                $nom_sci_ideal .= ' '.strtolower($nom['type_epithete']);
                                $nom_sci_ideal .= ' '.strtolower($nom['epithete_infra_sp']);
                                $nom_sci_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_sci'] != $nom_sci_ideal) {
                                        $nom_sci_traite = $this->repererEspace($nom['nom_sci']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_sci_traite, $nom_sci_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'nom_sci corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #19
         */
        private function testerNomSupraGeneriqueEspaces() {
                $info = $this->getInfosTest(19);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['nom_supra_generique'] != '') {
                                if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s+$)/', $nom['nom_supra_generique'])) {
                                        $nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #20
         */
        private function testerNomSupraGeneriqueSyntaxe() {
                $info = $this->getInfosTest(20);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['nom_supra_generique'] != '') {
                                if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+$/', $nom['nom_supra_generique'])) {
                                        $nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #21
         */
        private function testerNomSupraGeneriqueRang() {
                $info = $this->getInfosTest(21);
                $info['nom'] = sprintf($info['nom'], $this->manuel['rang_genre']);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_genre']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['nom_supra_generique'] != '') {
                                if ($nom['rang'] >= $this->manuel['rang_genre']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #22
         */
        private function testerGenreEspaces() {
                $info = $this->getInfosTest(22);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['genre'] != '') {
                                if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['genre'])) {
                                        $nom_traite = $this->repererEspace($nom['genre']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'genre erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #23
         */
        private function testerGenreSyntaxe() {
                $info = $this->getInfosTest(23);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['genre'] != '') {
                                $mots = explode(' ', $nom['genre']);
                                foreach ($mots as $mot) {
                                        if (!(preg_match('/^[+x]$/', $mot) || $this->verifierEpitheteGenre($mot))) {
                                                $nom_traite = $this->repererEspace($nom['genre']);
                                                $noms_erreur[] = array($nom['num_nom'], $nom_traite);
                                        }
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'genre erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #24
         */
        private function testerGenreRang() {
                $info = $this->getInfosTest(24);
                $info['nom'] = sprintf($info['nom'], $this->manuel['rang_genre']);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_genre']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['genre'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_genre']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
                
        /**
         * Test #25
         */
        private function testerEpitheteInfraGeneriqueSyntaxe() {
                $info = $this->getInfosTest(25);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['epithete_infra_generique'] != '') {
                                if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+/', $nom['epithete_infra_generique'])) {
                                        $epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
                                        $noms_erreur[] = array($nom['num_nom'], $epithete_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #26
         */
        private function testerEpitheteInfraGeneriqueRang() {
                $info = $this->getInfosTest(26);
                $info['nom'] = sprintf($info['nom'], $this->manuel['rang_genre'], $this->manuel['rang_sp']);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_genre'], $this->manuel['rang_sp']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['epithete_infra_generique'] != '') {
                                if ($nom['rang'] <= $this->manuel['rang_genre'] || $nom['rang'] >= $this->manuel['rang_sp']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #27
         */
        private function testerEpitheteInfraGeneriqueEspaces() {
                $info = $this->getInfosTest(27);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['epithete_infra_generique'] != '') {
                                if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_generique'])) {
                                        $epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
                                        $noms_erreur[] = array($nom['num_nom'], $epithete_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #28
         */
        private function testerEpitheteSpEspaces() {
                $info = $this->getInfosTest(28);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['epithete_sp'] != '') {
                                if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_sp'])) {
                                        $epithete_traite = $this->repererEspace($nom['epithete_sp']);
                                        $noms_erreur[] = array($nom['num_nom'], $epithete_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #29
         */
        private function testerEpitheteSpSyntaxe() {
                $info = $this->getInfosTest(29);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['epithete_sp'] != '') {
                                $mots = explode(' ', $nom['epithete_sp']);
                                foreach ($mots as $mot) {
                                        if (!(preg_match('/^[+x]$/', $mot) || $this->verifierEpitheteSp($mot))) {
                                                $epithete_traite = $this->repererEspace($nom['epithete_sp']);
                                                $noms_erreur[] = array($nom['num_nom'], $epithete_traite);
                                        }
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #30
         */
        private function testerEpitheteSpRang() {
                $info = $this->getInfosTest(30);
                $info['nom'] = sprintf($info['nom'], $this->manuel['rang_sp']);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_sp']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['epithete_sp'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_sp']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #31
         */
        private function testerTypeEpitheteEspaces() {
                $info = $this->getInfosTest(31);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['type_epithete'] != '') {
                                if (preg_match('/\s+/', $nom['type_epithete'])) {
                                        $valeur_traitee = $this->repererEspace($nom['epithete_sp']);
                                        $noms_erreur[] = array($nom['num_nom'], $valeur_traitee);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'type_epithete erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #32
         */
        private function testerTypeEpitheteSyntaxe() {
                $info = $this->getInfosTest(32);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['type_epithete'] != '') {
                                if (!$this->verifierTypeEpithete($nom['type_epithete'])) {
                                        $noms_erreur[] = array($nom['num_nom'],  $nom['type_epithete']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'type_epithete erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #33
         */
        private function testerTypeEpitheteHybridite() {
                $info = $this->getInfosTest(33);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['type_epithete'] != '') {
                                if (preg_match('/^(?:n-|notho-)/', $nom['type_epithete'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['type_epithete']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'type_epithete erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #34
         */
        private function testerEpitheteInfraSpEspaces() {
                $info = $this->getInfosTest(34);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['epithete_infra_sp'] != '') {
                                if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_sp'])) {
                                        $epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
                                        $noms_erreur[] = array($nom['num_nom'], $epithete_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #35
         */
        private function testerEpitheteInfraSpSyntaxe() {
                $info = $this->getInfosTest(35);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['epithete_infra_sp'] != '') {
                                $mots = explode(' ', $nom['epithete_infra_sp']);
                                foreach ($mots as $mot) {
                                        if (!(preg_match('/^[+x]$/', $mot) || $this->verifierTypeEpithete($mot)|| $this->verifierEpitheteSp($mot))) {
                                                $epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
                                                $noms_erreur[] = array($nom['num_nom'], $epithete_traite);
                                        }
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #36
         */
        private function testerEpitheteInfraSpRang() {
                $info = $this->getInfosTest(36);
                $info['nom'] = sprintf($info['nom'], $this->manuel['rang_sp']);
                $info['description'] = sprintf($info['description'], $this->manuel['rang_sp']);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['epithete_infra_sp'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_sp']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
private function testerStatutCultureSyntaxe() {
                $info = array('nom' => 'statut_culture -> syntaxe',
                        'description' => "Le champ statut_culture peut contenir :\n".
                                                                " - le symbole tiret «-» précédant une autre information non référencée...\n".
                                                                " - une première lettre en majuscule indiquant le code standard attribué à ce taxon,\n".
                                                                " - éventuellement suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
                                                                "un code de présence spécifique au référentiel.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['statut_culture'] != '') {
                                if (!$this->verifierStatutCulture($nom['statut_culture'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['statut_culture']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'statut_culture erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerStatutIntroductionSyntaxe() {
                $info = array('nom' => 'statut_introduction -> syntaxe',
                        'description' => "Le champ statut_introduction peut contenir :\n".
                                                                " - le symbole tiret «-» précédant une autre information non référencée...\n".
                                                                " - une première lettre en majuscule indiquant le code standard attribué à ce taxon,\n".
                                                                " - éventuellement suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
                                                                "un code de présence spécifique au référentiel.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['statut_introduction'] != '') {
                                if (!$this->verifierStatutIntroduction($nom['statut_introduction'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['statut_introduction']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'statut_introduction erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerStatutOrigineSyntaxe() {
                $info = array('nom' => 'statut_origine -> syntaxe',
                        'description' => "Le champ statut_origine peut contenir :\n".
                                                                " - le symbole tiret «-» précédant une autre information non référencée...\n".
                                                                " - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
                                                                " - éventuellement suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
                                                                "un code de présence spécifique au référentiel.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['statut_origine'] != '') {
                                if (!$this->verifierStatutOrigine($nom['statut_origine'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['statut_origine']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'statut_origine erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerPresenceSyntaxe() {
                $info = array('nom' => 'presence -> syntaxe',
                        'description' => "Le champ presence contient soit :\n".
                                                                " - le symbole tiret «-» précédant une autre information non référencée...\n".
                                                                " - une première lettre en majuscule indiquant le code standard attribué à ce taxon,\n".
                                                                " - éventuellement suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
                                                                "un code de présence spécifique au référentiel.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['presence'] != '') {
                                if (!$this->verifierPresence($nom['presence'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['presence']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'presence erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerHybrideParent02Existence() {
                $info = array('nom' => 'hybride_parent_02 -> existence',
                        'description' => "Si le champ hybride_parent_02 contient un nombre alors il doit correspondre à une valeur ".
                                                                "du champ num_nom.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['hybride_parent_02'] != '') {
                                if (!isset($this->noms[$nom['hybride_parent_02']]) && $nom['hybride_parent_02'] != '0') {
                                        $noms_erreur[] = array($nom['num_nom'], $this->repererEspace($nom['hybride_parent_02']));
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'hybride_parent_02 introuvable');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerHybrideParent02Syntaxe() {
                $info = array('nom' => 'hybride_parent_02 -> syntaxe',
                        'description' => "Le champ hybride_parent_02 contient soit :\n".
                                                                " - une valeur vide,\n".
                                                                " - un nombre.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['hybride_parent_02'] != '') {
                                if (!$this->verifierNombre($nom['hybride_parent_02'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $this->repererEspace($nom['hybride_parent_02']));
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'hybride_parent_02 erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        
        private function testerHybrideParent01Existence() {
                $info = array('nom' => 'hybride_parent_01 -> existence',
                        'description' => "Si le champ hybride_parent_01 contient un nombre alors il doit correspondre à une valeur ".
                                                                "du champ num_nom.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['hybride_parent_01'] != '' && $nom['hybride_parent_01'] != '0') {
                                if (!isset($this->noms[$nom['hybride_parent_01']])) {
                                        $noms_erreur[] = array($nom['num_nom'], $this->repererEspace($nom['hybride_parent_01']));
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'hybride_parent_01 introuvable');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerHybrideParent01Syntaxe() {
                $info = array('nom' => 'hybride_parent_01 -> syntaxe',
                        'description' => "Le champ hybride_parent_01 contient soit :\n".
                                                                " - une valeur vide,\n".
                                                                " - un nombre.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['hybride_parent_01'] != '') {
                                if (!$this->verifierNombre($nom['hybride_parent_01'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $this->repererEspace($nom['hybride_parent_01']));
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'hybride_parent_01 erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeOrthographiqueExistence() {
                $info = array('nom' => 'synonyme_orthographique -> existence',
                        'description' => "Si le champ synonyme_orthographique contient un nombre alors il doit correspondre ".
                                                                "à une valeur du champ num_nom.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['synonyme_orthographique'] != '') {
                                if (!isset($this->noms[$nom['synonyme_orthographique']])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['synonyme_orthographique']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'synonyme_orthographique introuvable');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeOrthographiqueSyntaxe() {
                $info = array('nom' => 'synonyme_orthographique -> syntaxe',
                        'description' => "Le champ synonyme_orthographique contient soit :\n".
                                                                " - une valeur vide,\n".
                                                                " - un nombre.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as $nom) {
                        if ($nom['synonyme_orthographique'] != '') {
                                if (!$this->verifierNombre($nom['synonyme_orthographique'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['synonyme_orthographique']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'synonyme_orthographique erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeMalAppliqueSyntaxe() {
                $info = array('nom' => 'synonyme_mal_applique -> syntaxe',
                        'description' => "Le champ synonyme_mal_applique contient soit :\n".
                        " - une valeur vide,\n".
                        " - le chiffre 1.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['synonyme_mal_applique'] != '') {
                                if (!$this->verifierBooleen($nom['synonyme_mal_applique'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['synonyme_mal_applique']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'synonyme_mal_applique erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        
        private function testerSynonymeDouteuxSyntaxe() {
                $info = array('nom' => 'synonyme_douteux -> syntaxe',
                        'description' => "Le champ synonyme_douteux contient soit :\n".
                        " - une valeur vide,\n".
                        " - le chiffre 1.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['synonyme_douteux'] != '') {
                                if (!$this->verifierBooleen($nom['synonyme_douteux'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['synonyme_douteux']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'synonyme_douteux erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeDouteuxNumNomRetenu() {
                $info = array('nom' => 'synonyme_douteux -> présence num_nom_retenu',
                        'description' => "Si le nom est un synonyme douteux, le champs num_nom_retenu doit être vide.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['synonyme_douteux'] == 1 && $nom['num_nom_retenu'] != ' ') {
                                $noms_erreur[] = array($nom['num_nom'], $nom['synonyme_douteux'], $nom['num_nom_retenu']);
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'synonyme_douteux', 'num_nom_retenu');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                $this->traiterResultatTest($info);
        }
        
        
        private function testerSynonymeProparteExistence() {
                $info = array('nom' => 'synonyme_proparte -> existence',
                        'description' => "Si le champ synonyme_proparte contient un ou plusieurs nombres alors chacun d'entre eux ".
                                                                "doit correspondre à une valeur du champ num_nom.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['synonyme_proparte'] != '') {
                                $num_nom_a_verifier = explode(',', $nom['synonyme_proparte']);
                                $num_nom_en_erreur = array();
                                foreach ($num_nom_a_verifier as $num_nom) {
                                        if (!isset($this->noms[$num_nom])) {
                                                $num_nom_en_erreur[] = $num_nom;
                                        }
                                }
                                if (count($nbre_en_erreur) > 0) {
                                        $noms_erreur[] = array($nom['num_nom'], implode(',', $num_nom_en_erreur));
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'synonyme_proparte introuvable');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeProparteSyntaxe() {
                $info = array('nom' => 'synonyme_proparte -> syntaxe',
                        'description' => "Le champ synonyme_proparte contient soit :\n".
                        " - une valeur vide,\n".
                        " - un nombre,\n".
                        " - une suite de nombres séparés par des virgules.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['synonyme_proparte'] != '') {
                                if (!$this->verifierNombreSuite($nom['synonyme_proparte'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['synonyme_proparte']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'synonyme_proparte erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerBasionymeExistence() {
                $info = array('nom' => 'basionyme -> existence',
                        'description' => "Si le champ basionyme contient un nombre alors il doit correspondre à une valeur du champ ".
                                                                "num_nom.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['basionyme'] != '') {
                                if (!isset($this->noms[$nom['basionyme']])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['basionyme']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'basionyme introuvable');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        private function testerBasionymeSyntaxe() {
                $info = array('nom' => 'basionyme -> syntaxe',
                        'description' => "Le champ basionyme contient :\n".
                                                                " - une valeur vide,\n".
                                                                " - un nombre.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['basionyme'] != '') {
                                if (!$this->verifierNombre($nom['basionyme'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['basionyme']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'basionyme erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #37
         */
        private function testerGroupeCultivarSyntaxe() {
                $info = array('nom' => 'cultivar_groupe -> syntaxe',
                        'description' => "Le champ cultivar_groupe doit contenir un nom de groupe de cultivar conforme aux règles ".
                                "du code des plantes cultivées, c.-à-d. composer de caractères alphanumériques (A-Z,a-z et 0-9) incluant ".
                                "signes diacritiques et marques de ponctuations.\n".
                                "Il ne doit pas contenir le mot Groupe, l'abbréviation «gp» ou des parenthèses.\n".
                                "Il peut se terminer par l'abréviation «gx» pour distinguer les groupes des grex.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['cultivar_groupe'] != '') {
                                if (!$this->verifierEpitheteGroupeCultivar($nom['cultivar_groupe'])) {
                                        $epithete_traite = $this->repererEspace($nom['cultivar_groupe']);
                                        $noms_erreur[] = array($nom['num_nom'], $epithete_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'cultivar_groupe erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #38
         */
        private function testerGroupeCultivarRang() {
                $info = array('nom' => "cultivar_groupe -> rang >= {$this->manuel['rang_genre']}",
                        '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']}.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['cultivar_groupe'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_genre']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #39
         */
        private function testerCultivarSyntaxe() {
                $info = array('nom' => 'cultivar -> syntaxe',
                        'description' => "Le champ cultivar_groupe doit contenir :\n".
                                " - un nom de cultivar conforme aux règles du Code Internationnal de Nomenclature \n".
                                "   des Plantes Cultivées (CINPC), c.-à-d. composer de caractères alphanumériques \n".
                                "   (A-Z,a-z et 0-9) incluant signes diacritiques et marques de ponctuations.\n".
                                " - un nom en alphabet latin, ce qui implique une translittération des noms d'alphabet \n".
                                "   cyrillique, arabe, chinois...\n".
                                " - une lettre majuscule obligatoire pour le premier caractère du premier mot et pour \n".
                                "   les autres mots importants mais pas pour les mots mineurs.\n".
                                "Ne doit pas contenir :\n".
                                " - cv., convar. ou de guillemets simples (').\n",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['cultivar'] != '') {
                                if (!$this->verifierEpitheteCultivar($nom['cultivar'])) {
                                        $epithete_traite = $this->repererEspace($nom['cultivar']);
                                        $noms_erreur[] = array($nom['num_nom'], $epithete_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'cultivar erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #40
         */
        private function testerCultivarRang() {
                $info = array('nom' => "cultivar -> rang >= {$this->manuel['rang_genre']}",
                        'description' => "Si le champ cultivar n'est pas vide alors le rang du nom doit être supérieur ou égal à ". 
                                                                "{$this->manuel['rang_genre']}.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['cultivar'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_genre']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_sci'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_sci', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #41
         */
        private function testerNomCommercialSyntaxe() {
                $info = array('nom' => 'nom_commercial -> syntaxe',
                        'description' => "Le champ nom_commercial doit contenir un nom commercial conforme aux règles du ".
                                "Code Internationnal de Nomenclature des Plantes Cultivées (CINPC) ".
                                "qui se compose de caractères majuscules (A-Z) incluant des signes diacritiques et des espaces.\n",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['nom_commercial'] != '') {
                                if (!$this->verifierNomCommercial($nom['nom_commercial'])) {
                                        $epithete_traite = $this->repererEspace($nom['nom_commercial']);
                                        $noms_erreur[] = array($nom['num_nom'], $epithete_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'cultivar erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #42
         */
        private function testerNomCommercialPresenceCultivar() {
                $info = array('nom' => 'nom_commercial -> groupe_cultivar OU cultivar non vide',
                        'description' => "Si le champ nom_commercial contient un nom commercial alors le champ cultivar OU ".
                                "cultivar_groupe ne doit pas être vide.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ((isset($nom['nom_commercial']) && $nom['nom_commercial'] != '') && ($nom['cultivar'] == '' && $nom['cultivar_groupe'] == '')) {
                                $noms_erreur[] = array($nom['num_nom'], $nom['nom_sci']);
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_commercial sans cultivar ou cultivar_groupe');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #43
         */
        private function testerAuteurSyntaxe() {
                $info = array('nom' => 'auteur -> syntaxe',
                        'description' => "Le champ auteur doit :\n".
                        " - contenir l'intitulé complet des noms de l'auteur, ou des auteurs, ayant publié à l'origine la combinaison latine courante.\n".
                " - OU débuter par le mot « sensu » et contenir l'intitulé complet des noms de l'auteur, ou des auteurs, ".
                        "ayant publié un nom dont la description ne correspond pas à celle de l'auteur, ou des auteurs, d'origine.\n".
                        " - 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".
                        " - contenir, si nécessaire, des abréviations de noms d'auteurs respectant les standards.\n".
                        " - contenir une translittération des noms d'alphabet cyrillique, arabe, chinois... en alphabet latin.\n".
                        " - inclure entre parenthèses l'intitulé des noms de l'auteur ou des auteurs ayant publié le basionyme.\n".
                        " - toujours utiliser l'esperluette (&) à la place du mot « et » pour séparer les noms d'auteurs.\n".
                        " - conformément à la recommandation 46C.2 du CINB, si une un citation comprend plus de deux auteurs, ".
                        "elle devrait être limitée au nom du premier, suivi de « & al.».\n",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['auteur'] != '') {
                                if (!$this->verifierAuteur($nom['auteur'])) {
                                        $intitule_traite = $this->repererEspace($nom['auteur']);
                                        $noms_erreur[] = array($nom['num_nom'], $intitule_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'auteur erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #44
         */
        private function testerAnneeSyntaxe() {
                $info = array('nom' => 'annee -> syntaxe',
                        'description' => "Le champ annee doit :\n".
                        " - contenir un nombre de 4 chiffres,\n".
                        " - être supérieur ou égal à 1753.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['annee'] != '') {
                                if (!$this->verifierAnnee($nom['annee'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['annee']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'annee erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #45
         */
        private function testerBiblioOrigineSyntaxe() {
                $info = array('nom' => 'biblio_origine -> syntaxe',
                        'description' => "Le champ biblio_origine se compose de plusieurs parties séparées par des caractères ".
                        "précis qui sont dans l'ordre de gauche à droite :\n".
                        " - éventuellement, le mot « in » suivi d'un intitulé auteur (utilisé pour indiquer l'intitulé auteur de ".
                        "l'ouvrage dans lequel la publication est parue),\n".
                        " - point-virgule « ; » (si l'info précédent a été renseignée),\n".
                        " - abréviation, ou nom, de l'ouvrage ou de la revue selon le standard en vigueur dans le code du nom. ".
                        "Cette information ne doit pas contenir de caractère virgule « , »,\n".
                        " - virgule « , »,\n".
                        " - informations permettant d'identifier plus précisément le document contenant le nom... ".
                        "(par exemple, l'éditeur, le tome, le numéro d'édition, le volume...) séparées par des virgules ou d'autres ".
                        "caractères sauf deux points « : ».\n".
                        " - deux points « : »,\n".
                        " - numéro(s) de la page contenant la publication du nom ou de l'ensemble de pages (première et dernière ".
                        "pages de l'ensemble séparées par un tiret « - »). Quelques fois des numéros ou d'autres informations indiquant ".
                        "la position du nom dans le document. Le tiret « - » doit toujours servir à séparer un ensemble.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['biblio_origine'] != '') {
                                if (!$this->verifierBiblioOrigine($nom['biblio_origine'])) {
                                        $biblio_traite = $this->repererEspace($nom['biblio_origine']);
                                        $noms_erreur[] = array($nom['num_nom'], $biblio_traite);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'biblio_origine erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #46
         */
        private function testerHomonymieSyntaxe() {
                $info = array('nom' => 'homonyme -> syntaxe',
                        'description' => "Le champ homonyme contient :\n".
                                " - une valeur vide,\n".
                                " - le chiffre 1.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['homonyme'] != '') {
                                if (!$this->verifierBooleen($nom['homonyme'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['homonyme']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'homonyme erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #47
         */
        private function testerHomonymieExistence() {
                $info = array('nom' => 'homonyme -> existence',
                        'description' => "Si le champ homonyme contient «1» alors plusieurs noms doivent posséder la même valeur ".
                                                                "dans le champ nom_sci.",
                        'resultat' => false);
                
                $noms_homonymie = $this->classerNomsParNomComplet();
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['homonyme'] != '0' && $nom['homonyme'] != '') {
                                if ($noms_homonymie[$nom['nom_sci']] <= 1) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_sci']);
                                }
                        }
                }
                $noms_homonymie = null;
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'homonyme introuvable');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }
        
        /**
         * Test #65
         */
        private function testerExclureTaxRefSyntaxe() {
                $info = $this->getInfosTest(65);
                $info = array('nom' => 'exclure_taxref -> syntaxe',
                        'description' => "Le champ exclure_taxref contient soit :\n".
                        " - une valeur vide.\n".
                        " - une valeur null.\n".
                        " - le chiffre 0.\n".
                        " - le chiffre 1",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($this->noms as &$nom) {
                        if ($nom['exclure_taxref'] != '' && $nom['exclure_taxref'] != null) {
                                if (!$this->verifierBooleen($nom['exclure_taxref'])) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['exclure_taxref']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'exclure_taxref erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                $noms_erreur = null;
                
                $this->traiterResultatTest($info);
        }

        

        //+--------------------------------------------------------------------------------------------------------------+//
        // MÉTHODES COMMUNES aux TESTS
        
        private function verifierPresence(&$valeur) {
                $codes = $this->manuel['codes_presence'];
                $ok = $this->verifierStatuts($valeur, $codes);
                return $ok;
        }
        
        private function verifierStatutOrigine(&$valeur) {
                $codes = $this->manuel['codes_statuts_origine'];
                $ok = $this->verifierStatuts($valeur, $codes);
                return $ok;
        }
        
        private function verifierStatutIntroduction(&$valeur) {
                $codes = $this->manuel['codes_statuts_introduction'];
                $ok = $this->verifierStatuts($valeur, $codes);
                return $ok;
        }
        
        private function verifierStatutCulture(&$valeur) {
                $codes = $this->manuel['codes_statuts_culture'];
                $ok = $this->verifierStatuts($valeur, $codes);
                return $ok;
        }
        
        private function verifierStatuts(&$valeur, &$codes) {
                $ok = true;
                if (!preg_match("/^(?:|-|[$codes](?:-[A-Z])?)$/", $valeur)) {
                        $ok = false;
                }
                return $ok;
        }
        
        private function verifierBooleen(&$valeur) {
                $ok = true;
                if (!preg_match('/^1$/', $valeur)) {
                        $ok = false;
                }
                return $ok;
        }
        
        private function verifierNombre(&$valeur) {
                $ok = true;
                if (!preg_match('/^[0-9]+$/', $valeur)) {
                        $ok = false;
                }
                return $ok;
        }
        
        private function verifierNombreSuite(&$valeur) {
                $ok = true;
                if (!preg_match('/^(?:[0-9]+,)*[0-9]+$/', $valeur)) {
                        $ok = false;
                }
                return $ok;
        }
        
        private function verifierTypeEpithete(&$type) {
                $ok = false;
                $rejetes = $this->manuel['type_epithete_rejetes'];
                if (preg_replace("/^(?:$rejetes)$/", '', $type) == '') {
                        $ok = false;
                } else if (preg_match('/^[a-z][-a-z]*[.]?$/', $type)) {
                        $ok = true;
                }
                return $ok;
        }
        
        private function verifierBiblioOrigine(&$intitule) {
                $ok = true;
                if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $intitule)) {
                        $ok = false;// Contient des espaces en trop
                } else if (!preg_match('/^(?:in [^;]+[;]|)[^,]+?(?:[,][^:]+|)(?:[:].+|)$/', $intitule)) {
                        $ok = false;
                } else if (preg_match('/(?:(?:^|[,:])\s*(?:[:,]|$))/', $intitule)) {
                        $ok = false;// Contient une mauvaise suite de caractères
                }
                return $ok;
        }
        
        private function verifierAnnee(&$annee) {
                $ok = true;
                if (!preg_match('/^[0-9]{4}$/', $annee)) {
                        $ok = false;
                } else if ($annee < 1753) {
                        $ok = false;
                }
                return $ok;
        }
        
        private function verifierAuteur(&$intitule) {
                $ok = true;
                $acceptes = $this->manuel['auteur_acceptes'];
                if (!preg_match("/^(?:$acceptes)$/", $intitule)) {
                        if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $intitule)) {
                                $ok = false;// Contient des espaces en trop
                        } else {
                                $mots_rejetes = $this->manuel['auteur_mots_rejetes'];
                                $mots = explode(' ', $intitule);
                                foreach ($mots as $position => $mot) {
                                        if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
                                                $ok = false;// Mot rejeté
                                        } else if (preg_match("/^(?:(?:\p{L}|[.'\(\)-])+|[&])$/u", $mot)) {
                                                continue;// Mot de l'intitulé auteur
                                        } else {
                                                $ok = false;
                                        }
                                }
                        }
                }
                return $ok;
        }
        
        private function verifierNomCommercial(&$epithete) {
                $ok = false;
                if (preg_match("/^[[:upper:][:punct:][:digit:][:space:]]+$/", $epithete)) {
                        $ok = true;
                }
                return $ok;
        }
        
        private function verifierEpitheteCultivar(&$epithete) {
                $ok = true;
                $acceptes = $this->manuel['cultivar_acceptes'];
                if (!preg_match("/^(?:$acceptes)$/", $epithete)) {
                        if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $epithete)) {
                                $ok = false;// Contient des espaces en trop
                        } else {
                                $mots_rejetes = $this->manuel['cultivar_mots_rejetes'];
                                $mots_mineurs = $this->manuel['mots_mineurs'];
                                $mots = explode(' ', $epithete);
                                foreach ($mots as $position => $mot) {
                                        if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
                                                $ok = false;// Mot rejeté
                                        } else if ($position > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot)) {
                                                continue;// Mot mineur en minuscule qui n'est pas en 1ère position
                                        } else {
                                                $mots_tiret = explode('-', $mot);
                                                foreach ($mots_tiret as $position_tiret => $mot_tiret) {
                                                        if ($position_tiret > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot_tiret)) {
                                                                continue;// Mot-tiret mineur en minuscule qui n'est pas en 1ère position
                                                        } else if (preg_match('/^[[:upper:]][[:lower:]]+$/', $mot_tiret)) {
                                                                continue;//Mot (ou 'mot-tiret') avec lettre initiale majuscule
                                                        } else if ($position_tiret == count($mots_tiret) && preg_match('/^[:upper:][:lower:]+[:punct:]?$/', $mot_tiret)) {
                                                                continue;//Dernier mot (ou 'mot-tiret') avec lettre initiale majuscule, suivi d'un éventuel signe de ponctuation
                                                        } else {
                                                                $ok = false;
                                                        }
                                                }
                                        }
                                }
                        }
                }
                return $ok;
        }
        
        private function verifierEpitheteGroupeCultivar(&$epithete) {
                $ok = true;
                $acceptes = $this->manuel['cultivar_gp_acceptes'];
                if (!preg_match("/^(?:$acceptes)$/", $epithete)) {
                        if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $epithete)) {
                                $ok = false;// Contient des espaces en trop
                        } else {
                                $mots_acceptes = $this->manuel['cultivar_gp_mots_acceptes'];
                                $mots_rejetes = $this->manuel['cultivar_gp_mots_rejetes'];
                                $mots_mineurs = $this->manuel['mots_mineurs'];
                                $mots = explode(' ', $epithete);
                                foreach ($mots as $position => $mot) {
                                        if (preg_match("/^(?:$mots_acceptes)$/i", $mot)) {
                                                continue;// Mot accepté
                                        } else if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
                                                $ok = false;// Mot rejeté
                                        } else if ($position > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot)) {
                                                continue;// Mot mineur en minuscule qui n'est pas en 1ère position
                                        } else {
                                                $mots_tiret = explode('-', $mot);
                                                foreach ($mots_tiret as $position_tiret => $mot_tiret) {
                                                        if ($position_tiret > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot_tiret)) {
                                                                continue;// Mot-tiret mineur en minuscule qui n'est pas en 1ère position dans le mot
                                                        } else if (preg_match('/^[[:upper:]][[:lower:]]+$/', $mot_tiret)) {
                                                                continue;// Mot (ou 'mot-tiret') avec lettre initiale majuscule
                                                        } else if ($position_tiret == count($mots_tiret) && preg_match('/^[:upper:][:lower:]+[:punct:]?$/', $mot_tiret)) {
                                                                continue;// Dernier mot (ou 'mot-tiret') avec lettre initiale majuscule, suivi d'un éventuel signe de ponctuation
                                                        } else {
                                                                $ok = false;
                                                        }
                                                }
                                        }
                                }
                        }
                }
                return $ok;
        }
        
        private function verifierEpitheteSp(&$epithete) {
                $ok = false;
                if (preg_match('/^[a-zëï][-a-zëï]+$/', $epithete)) {
                        $ok = true;
                } else if (preg_match('/^sp\.(?:[A-Z]|[1-9][0-9]*)$/', $epithete)) {
                        $ok = true;
                }
                return $ok;
        }
        
        private function verifierEpitheteGenre(&$epithete) {
                $ok = false;
                if (preg_match('/^[A-ZËÏ](?:[-a-zëï]+|[a-zëï]+-[A-ZËÏ][a-zëï]+)$/', $epithete)) {
                        $ok = true;
                }
                return $ok;
        }
        
        private function formaterStyleNomGenre(&$genre) {
                $genre_fmt = '';
                if (preg_match('/^\s*([x+])\s+(.+)$/i', $genre, $match)) {
                        $genre_fmt = strtolower($match[1]).' '.ucfirst(strtolower($match[2]));
                } else {
                        $genre_fmt = ucfirst(strtolower($genre));
                }
                return $genre_fmt;
        }
        
        private function repererEspace($nom_sci) {
                $nom_sci = str_replace(' ', '<span class="espace">&nbsp;</span>', $nom_sci);
                return $nom_sci;
        }
        
        private function construireSuffixeNomPltCultivee(&$nom) {
                $suffixe = array();
                $suffixe[] = $this->construireNomCultivarGroupe($nom);
                $suffixe[] = $this->construireNomCommercial($nom);
                $suffixe[] = $this->construireNomCultivar($nom);
                $suffixe = array_filter($suffixe);
                return implode(' ', $suffixe);
        }
        
        private function construireNomCultivarGroupe(&$nom) {
                $nom_groupe_cultivar = '';
                if ($nom['cultivar_groupe'] != '') {
                        if (preg_match('/ gx$/', $nom['cultivar_groupe'])) {
                                $nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].')';
                        } else {
                                $nom_groupe_cultivar =  '('.$nom['cultivar_groupe'].' Gp)';
                        }
                }
                return $nom_groupe_cultivar;
        }
        
        private function construireNomCommercial(&$nom) {
                $nom_commercial = '';
                if ($nom['nom_commercial'] != '') {
                        $nom_commercial =  strtoupper($nom['nom_commercial']);
                }
                return $nom_commercial;
        }
        
        private function construireNomCultivar(&$nom) {
                $nom_cultivar = '';
                if ($nom['cultivar'] != '') {
                        $nom_cultivar =  "'".$nom['cultivar']."'";
                }
                return $nom_cultivar;
        }
        
        private function classerNomsParNomComplet() {
                $noms_classes = array();
                foreach ($this->noms as &$nom) {
                        if (!isset($noms_classes[$nom['nom_sci']])) {
                                $noms_classes[$nom['nom_sci']] = 1;
                        } else {
                                $noms_classes[$nom['nom_sci']]++;
                        }
                }
                return $noms_classes;
        }

        private function getInfosTest($numero) {
                $info = $this->tests[$numero];
                $info['numero'] = $numero; 
                $info['resultat'] = false;
                return $info;
        }
}
?>