Subversion Repositories Applications.referentiel

Rev

Rev 45 | Rev 64 | 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 $resultatDao = null;
        private $traitementDao = null;
        private $tableStructureDao = null;
        private $referentielDao = null;
        
        public function executer() {
                // Récupération de paramêtres
                $this->projet = $this->getParam('p');
                $this->manuel = parse_ini_file(Config::get('chemin_appli').DS.'..'.DS.'configurations'.DS.'referentiel_v2.1.ini');
                
                $this->resultatDao = new ResultatDao();
                $this->traitementDao = new TraitementDao();
                
                // Récupération du dernier traitement demandé
                $this->traitement = $this->traitementDao->getDernierTraitement($this->projet, self::SCRIPT_NOM);
                if (isset($this->traitement)) {
                        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));
                        }
                        
                        // Lancement du test demandé
                        $cmd = $this->getParam('a');
                switch ($cmd) {
                                case 'tout' :
                                        $this->tableStructureDao = new TableStructureDao();
                                        $this->referentielDao = new ReferentielDao();
                                        Debug::printr('Départ lancement test:');
                                        $this->lancerTests();
                                        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']));
                }
    }

    public function lancerTests() {
                $donnees = array();
                $donnees['tests'] = array();
                
                // Récupération des données à tester
                $colonnes = $this->tableStructureDao->getColonnes($this->projet);
                $analyses = $this->tableStructureDao->getAnalyse($this->projet);
                $noms = $this->referentielDao->getTout($this->projet);
                Debug::printr('Nbre noms :'.count($noms));
                $noms = $this->classerNomsParNumNom($noms);
                $noms_homonymie = $this->classerNomsParNomComplet($noms);
                
                // Lancement des tests unitaires
                $this->testerNombreDeChamps($colonnes);
                $this->testerNomDesChamps($colonnes);
                $this->testerTypeDesChamps($colonnes);
                $this->testerTailleDesChamps($colonnes, $analyses);
                $this->testerNumNomClePrimaire($colonnes);
                
                $this->testerNumNomSuperieurAZero($noms);
                
                $this->testerNumNomRetenuSuperieurAZero($noms);
                $this->testerNumTaxSupEgalZeroUnique($noms);
                $this->testerTaxSupPourTaxon($noms);
                $this->testerExitenceTaxonSuperieur($noms);
                $this->testerClassificationRang($noms);         
                $this->testerClassification($noms);
                
                $this->testerRang($noms);
                
                $this->testerNomCompletSupraGenerique($noms);
                $this->testerNomCompletGenre($noms);
                $this->testerNomCompletInfraGenre($noms);
                $this->testerNomCompletEspece($noms);
                $this->testerNomCompletInfraSpecifique($noms);

                $this->testerNomSupraGeneriqueEspaces($noms);
                $this->testerNomSupraGeneriqueSyntaxe($noms);
                $this->testerNomSupraGeneriqueRang($noms);
                
                $this->testerGenreEspaces($noms);
                $this->testerGenreSyntaxe($noms);
                $this->testerGenreRang($noms);
                
                $this->testerEpitheteInfraGeneriqueEspaces($noms);
                $this->testerEpitheteInfraGeneriqueSyntaxe($noms);
                $this->testerEpitheteInfraGeneriqueRang($noms);
                
                $this->testerEpitheteSpEspaces($noms);
                $this->testerEpitheteSpSyntaxe($noms);
                $this->testerEpitheteSpRang($noms);
                
                $this->testerTypeEpitheteEspaces($noms);
                $this->testerTypeEpitheteSyntaxe($noms);
                $this->testerTypeEpitheteHybridite($noms);
                
                $this->testerEpitheteInfraSpEspaces($noms);
                $this->testerEpitheteInfraSpSyntaxe($noms);
                $this->testerEpitheteInfraSpRang($noms);
                
                $this->testerGroupeCultivarSyntaxe($noms);
                $this->testerGroupeCultivarRang($noms);         
                
                $this->testerCultivarSyntaxe($noms);
                $this->testerCultivarRang($noms);
                
                $this->testerNomCommercialSyntaxe($noms);
                $this->testerNomCommercialPresenceCultivar($noms);
                
                $this->testerAuteurSyntaxe($noms);
                
                $this->testerAnneeSyntaxe($noms);
                
                $this->testerBiblioOrigineSyntaxe($noms);
                
                $this->testerHomonymieSyntaxe($noms);
                $this->testerHomonymieExistence($noms, $noms_homonymie);
                
                $this->testerBasionymeSyntaxe($noms);
                $this->testerBasionymeExistence($noms);
                
                $this->testerSynonymeProparteSyntaxe($noms);
                $this->testerSynonymeProparteExistence($noms);
                
                $this->testerSynonymeDouteuxSyntaxe($noms);
                
                $this->testerSynonymeMalAppliqueSyntaxe($noms);
                
                $this->testerSynonymeOrthographiqueSyntaxe($noms);
                $this->testerSynonymeOrthographiqueExistence($noms);
                
                $this->testerHybrideParent01Syntaxe($noms);
                $this->testerHybrideParent01Existence($noms);
                $this->testerHybrideParent02Syntaxe($noms);
                $this->testerHybrideParent02Existence($noms);
                
                $this->testerPresenceSyntaxe($noms);
                $this->testerStatutOrigineSyntaxe($noms);
                $this->testerStatutIntroductionSyntaxe($noms);
                $this->testerStatutCultureSyntaxe($noms);
        }
        
        //+--------------------------------------------------------------------------------------------------------------+//
        // Enregistrement des résultats
        private function traiterResultatTest($info) {
                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);
        }
        
        //+--------------------------------------------------------------------------------------------------------------+//
        // TESTS
        
        private function testerStatutCultureSyntaxe($noms) {
                $info = array('nom' => 'statut_culture -> syntaxe',
                        'description' => "Le champ statut_culture peut contenir :\n".
                        " - le symbole tiret «-» une autre information non référencée...\n".
                        " - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
                        " - Cette première lettre peut être 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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerStatutIntroductionSyntaxe($noms) {
                $info = array('nom' => 'statut_introduction -> syntaxe',
                        'description' => "Le champ statut_introduction peut contenir :\n".
                        " - le symbole tiret «-» une autre information non référencée...\n".
                        " - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
                        " - Cette première lettre peut être 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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerStatutOrigineSyntaxe($noms) {
                $info = array('nom' => 'statut_origine -> syntaxe',
                        'description' => "Le champ statut_origine peut contenir :\n".
                        " - le symbole tiret «-» une autre information non référencée...\n".
                        " - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
                        " - Cette première lettre peut être 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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerPresenceSyntaxe($noms) {
                $info = array('nom' => 'presence -> syntaxe',
                        'description' => "Le champ presence contient soit :\n".
                        " - le symbole tiret «-» une autre information non référencée...\n".
                        " - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
                        " - Cette première lettre peut être 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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerHybrideParent02Existence($noms) {
                $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 ($noms as $nom) {
                        if ($nom['hybride_parent_02'] != '') {
                                if (!isset($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerHybrideParent02Syntaxe($noms) {
                $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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        
        private function testerHybrideParent01Existence($noms) {
                $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 ($noms as $nom) {
                        if ($nom['hybride_parent_01'] != '' && $nom['hybride_parent_01'] != '0') {
                                if (!isset($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerHybrideParent01Syntaxe($noms) {
                $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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeOrthographiqueExistence($noms) {
                $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 ($noms as $nom) {
                        if ($nom['synonyme_orthographique'] != '') {
                                if (!isset($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeOrthographiqueSyntaxe($noms) {
                $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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeMalAppliqueSyntaxe($noms) {
                $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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeDouteuxSyntaxe($noms) {
                $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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeProparteExistence($noms) {
                $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 ($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($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerSynonymeProparteSyntaxe($noms) {
                $info = array('nom' => 'synonyme_proparte -> syntaxe',
                        'description' => "Le champ synonyme_proparte contient soit :\n".
                        " - une valeur vide.\n".
                        " - un nombre.\n".
                        " - une suite de nombre séparés par des virgules.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerBasionymeExistence($noms) {
                $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 ($noms as $nom) {
                        if ($nom['basionyme'] != '') {
                                if (!isset($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerBasionymeSyntaxe($noms) {
                $info = array('nom' => 'basionyme -> syntaxe',
                        'description' => "Le champ basionyme contient :\n".
                        " - un nombre ou une valeur vide.\n",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerHomonymieExistence($noms, $noms_homonymie) {
                $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_complet.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['homonyme'] != '0' && $nom['homonyme'] != '') {
                                if ($noms_homonymie[$nom['nom_complet']] <= 1) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_complet']);
                                }
                        }
                }
                
                // 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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerHomonymieSyntaxe($noms) {
                $info = array('nom' => 'homonyme -> syntaxe',
                        'description' => "Le champ homonyme contient :\n".
                        " - le chiffre 1 ou une valeur vide.\n",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerBiblioOrigineSyntaxe($noms) {
                $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 global 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".
                        " - Les 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".
                        " - la page contenant la publication du nom ou un ensemble de page (première et dernière page de ".
                        "l'ensemble séparées par un tiret « - »). Quelques fois des numéros ou d'autres informations indiquant ".
                        "dans le document la position du nom. Le tiret « - » doit toujours servir à séparer un ensemble.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerAnneeSyntaxe($noms) {
                $info = array('nom' => 'annee -> syntaxe',
                        'description' => "Le champ annee doit :\n".
                        " - contenir un nombre de 4 chiffre\n".
                        " - être supérieur ou égal à 1753 ",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerAuteurSyntaxe($noms) {
                $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és à l'origine la combinaison latine courante.\n".
                " - ou débuter par le mot « sensu » et contient l'intitulé complet des noms de l'auteur ou des auteurs ayant publiés un nom dont la description ne correspond pas à celle de l'auteur ou des auteurs d'origine.\n".
                        " - 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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomCommercialSyntaxe($noms) {
                $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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomCommercialPresenceCultivar($noms) {
                $info = array('nom' => 'nom_commercial -> groupe_cultivar OU cultivar non vide',
                        'description' => "Si le champ nom_commercial contier 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 ($noms as $nom) {
                        if ($nom['nom_commercial'] != '' && ($nom['cultivar'] == '' && $nom['cultivar_groupe'] == '')) {
                                $noms_erreur[] = array($nom['num_nom'], $nom['nom_complet']);
                        }
                }
                
                // 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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerCultivarSyntaxe($noms) {
                $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 des Plantes ".
                                "Cultivées (CINPC) qui se compose de caractères alphanumériques (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 cyrillique, ".
                                "arabe, chinois...\n".
                                " - une lettre majuscule obligatoire pour le premier caractère du premier mot et pour 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 ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerCultivarRang($noms) {
                $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 ($noms as $nom) {
                        if ($nom['cultivar'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_genre']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerGroupeCultivarSyntaxe($noms) {
                $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 qui se compose 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 contir à la fin l'abréviation «gx» pour distinguer les groupes des grex.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerGroupeCultivarRang($noms) {
                $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 ($noms as $nom) {
                        if ($nom['cultivar_groupe'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_genre']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerEpitheteInfraSpEspaces($noms) {
                $info = array('nom' => 'epithete_infra_sp -> espaces en trop',
                        'description' => "Le champ epithete_infra_sp ne doit pas contenir d'espace avant ou aprés le nom.\n".
                                "Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerEpitheteInfraSpSyntaxe($noms) {
                $info = array('nom' => 'epithete_infra_sp -> syntaxe',
                        'description' => "Le champ epithete_infra_sp peut contenir :\n".
                                " - un mot unique composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
                                "       Il commence par une lettre minuscule (avec ou sans tréma).\n". 
                                "       Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
                                " - une formule d'hybridité composée d'une série de noms d'espèce ou d'infra espèce (au moins 2) séparés entre eux \n".
                                "       par la lettre x entourée de caractères espaces.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerEpitheteInfraSpRang($noms) {
                $info = array('nom' => "epithete_infra_sp -> rang > {$this->manuel['rang_sp']}",
                        'description' => "Si le champ epithete_infra_sp n'est pas vide alors le rang du nom doit être supérieur à {$this->manuel['rang_sp']}.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['epithete_infra_sp'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_sp']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerTypeEpitheteEspaces($noms) {
                $info = array('nom' => 'type_epithete -> espaces en trop',
                        'description' => "Le champ type_epithete ne doit pas contenir d'espace.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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);
        }
        
        private function testerTypeEpitheteSyntaxe($noms) {
                $info = array('nom' => 'type_epithete -> syntaxe',
                        'description' => "Le champ type_epithete doit contenir un mot unique composé de lettres minuscules sans ".
                                " accents et de tirets (-). Il commence par une lettre minuscule sans accent.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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);
        }
        
        private function testerTypeEpitheteHybridite($noms) {
                $info = array('nom' => 'type_epithete -> hybridité',
                        'description' => "Le champ type_epithete ne doit pas contenir de préfixe indiquant l'hybridité comme : \n".
                                " - «n-» \n".
                                " - «notho-» \n",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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);
        }
        
        private function testerNombreDeChamps($colonnes) {
                $info = array('nom' => 'Structure -> nombre de champs',
                        'description' => 'Le nombre de champs présent dans la table doit être supérieur ou égal à 35.',
                        'resultat' => false);
                
                $nbre_colonnes = count($colonnes);
                $info['message'] = $nbre_colonnes;
                if ($nbre_colonnes >= 35) {
                        $info['resultat'] = true;
                }
                $this->traiterResultatTest($info);
        }
        
        private function testerNomDesChamps($colonnes) {
                $info = array('nom' => 'Structure -> noms des champs',
                        'description' => 'Les champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
                        'resultat' => false);
                
                $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'] = 'Champs manquant : '.implode(', ', $champs_manquant).'.';
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerTypeDesChamps($colonnes) {
                $info = array('nom' => 'Structure -> types des champs',
                        'description' => 'Les types des champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
                        'resultat' => false);
                
                $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'] = "Champs n'ayant pas un bon type : ".implode(', ', $champs_erreur).'.';
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerTailleDesChamps($colonnes, $analyses) {
                $info = array('nom' => 'Structure -> champs tronqués',
                        'description' => "Vérifie que le risque éventuel que des données de type texte insérées ".
                                "dans la table aient pu être tronquées lors de leur insertion.\n".
                                "Un résultat de type KO ne signifie pas forcément un problème à résoudre mais attire l'attention du coordinateur ".
                                "sur un problème éventuel.",
                        'resultat' => false);
                
                $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'] = "Champs possédant des enregistrements avec une taille maximum : ".implode(', ', $champs_erreur).'.';
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNumNomClePrimaire($colonnes) {
                $info = array('nom' => 'Structure -> num_nom est clé primaire',
                        'description' => "Vérifie que le champ num_nom est bien la clé primaire de la table.",
                        'resultat' => false);
                
                foreach ($colonnes as $colonne) {
                        if ($colonne['Field'] == 'num_nom' && $colonne['Key'] == 'PRI') {
                                $info['resultat'] = true;
                        }
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNumNomSuperieurAZero($noms) {
                $info = array('nom' => 'num_nom -> supérieur à 0',
                        'description' => "Le champ num_nom doit contenir des nombres entiers supérieurs à 0.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['num_nom'] <= 0) {
                                $noms_erreur[] = $nom['num_nom'];
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = count($noms_erreur)." enregistrements contiennent dans le champ num_nom une valeur inférieure ou égale à 0.";
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNumNomRetenuSuperieurAZero($noms) {
                $info = array('nom' => 'num_nom_retenu -> supérieur à 0',
                        'description' => "Le champ num_nom_retenu doit contenir des nombres entiers supérieurs à 0 ou être vide.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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'] = count($noms_erreur)." enregistrements dont le champ num_nom_retenu est inférieur ou égal à 0 : ".implode(', ', $noms_erreur).'.';
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNumTaxSupEgalZeroUnique($noms) {
                $info = array('nom' => 'num_tax_sup -> égal à 0 unique',
                        'description' => "Un seul enregistrement doit posséder la valeur 0 dans le champ num_tax_sup. Il correspond au premier taxon de la classification.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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'] = count($noms_erreur)." enregistrements ont une valeur de 0 dans le champ num_tax_sup : ".implode(', ', $noms_erreur).'.';
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerTaxSupPourTaxon($noms) {
                $info = array('nom' => 'Classification -> uniquement pour les taxons',
                        'description' => "Seul les enregistrements représentant un taxon doivent posséder une valeur dans le champ num_tax_sup.\n".
                                "Si num_nom_retenu est différent de num_nom (= nom synonyme) alors num_tax_sup doit être vide.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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'] = count($noms_erreur)." enregistrements qui n'est pas un taxon et qui possède une valeur dans num_tax_sup : ".implode(', ', $noms_erreur).'.';
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerExitenceTaxonSuperieur($noms) {
                $info = array('nom' => 'Classification -> existence du taxon supérieur',
                        'description' => "Pour chaque enregistrement représentant un taxon doit posséder un taxon supérieur sauf la racine de la classification.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['num_nom_retenu'] == $nom['num_nom']) {
                                if ($nom['num_tax_sup'] != 0 && !isset($noms[$nom['num_tax_sup']])) {
                                        $noms_erreur[] = $nom['num_nom'];
                                } 
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = count($noms_erreur)." enregistrements dont le taxon supérieur n'existe pas : ".implode(', ', $noms_erreur).'.';
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerClassificationRang($noms) {
                $info = array('nom' => 'Classification -> taxon supérieur avec rang inférieur',
                        'description' => "Pour chaque enregistrement représentant un taxon, chaque taxon supérieur doit avoir un rang inférieur au taxon courant.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['num_nom_retenu'] == $nom['num_nom']) {
                                if (isset($noms[$nom['num_tax_sup']])) {
                                        $nom_sup = $noms[$nom['num_tax_sup']];
                                        if ($nom_sup['rang'] > $nom['rang']) {
                                                $noms_erreur[] = $nom['num_nom'];
                                        }
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = count($noms_erreur)." enregistrements avec un problème : ".implode(', ', $noms_erreur).'.';
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerClassification($noms) {
                $info = array('nom' => 'Classification -> racine liée à chaque noeud',
                        'description' => "Pour chaque enregistrement, la classification doit pouvoir être remonté jusqu'à un même nom unique possédant une valeur num_tax_sup de 0.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['num_nom_retenu'] == $nom['num_nom']) {
                                $classif_ok = $this->remonterClassif($noms, $nom);
                                if ($classif_ok === false) {
                                        $noms_erreur[] = $nom['num_nom'];
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = count($noms_erreur)." taxons dont la classification n'est pas bonne : ".implode(', ', $noms_erreur).'.';
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function remonterClassif(&$noms, $nom) {
                if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] == '0') {
                        return true;
                } else if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] != '0') {
                        return false;
                } else {
                        return $this->remonterClassif($noms, $noms[$nom['num_tax_sup']]);
                }
        }
        
        private function testerRang($noms) {
                $info = array('nom' => 'rang',
                        'description' => "Le rang doit correspondre à un valeur numérique définit dans le manuel.",
                        'resultat' => false);
                
                $rangs = array_flip(explode(',', $this->manuel['rangs']));
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if (!isset($rangs[$nom['rang']])) {
                                $noms_erreur[] = $nom['num_nom'];
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message'] = count($noms_erreur)." noms dont le rang n'est pas bon : ".implode(', ', $noms_erreur).'.';
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomCompletSupraGenerique($noms) {
                $info = array('nom' => 'nom_complet -> noms supra-génériques',
                        'description' => "Si le rang est < à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ nom_supra_generique. ".
                                "Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['rang'] < $this->manuel['rang_genre']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_complet_ideal = $this->formaterStyleNomGenre($nom['nom_supra_generique']);
                                $nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_complet'] != $nom_complet_ideal) {
                                        $nom_complet_traite = $this->repererEspace($nom['nom_complet']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomCompletGenre($noms) {
                $info = array('nom' => 'nom_complet -> noms de genres',
                        'description' => "Si le rang est = à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ genre. ".
                                "Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['rang'] == $this->manuel['rang_genre']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                $nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_complet'] != $nom_complet_ideal) {
                                        $nom_complet_traite = $this->repererEspace($nom['nom_complet']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomCompletInfraGenre($noms) {
                $info = array('nom' => 'nom_complet -> noms infra-génériques',
                        'description' => "Si le rang est > à {$this->manuel['rang_genre']} et < à {$this->manuel['rang_sp']} le nom_complet doit correspondre à une des formules suivantes : \n".
                        " genre + ' ' + type_epithete + ' ' + epithete_infra_generique \n".
                        " genre + ' ' + epithete_infra_generique + ' ' + type_epithete=agg. \n".
                        "Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['rang'] > $this->manuel['rang_genre'] && $nom['rang'] < $this->manuel['rang_sp']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_complet_ideal = '';
                                if ($nom['type_epithete'] == 'agg.') {
                                        $nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                        $nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
                                        $nom_complet_ideal .= ' '.$nom['type_epithete'];
                                } else {
                                        $nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                        $nom_complet_ideal .= ' '.$nom['type_epithete'];
                                        $nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
                                }
                                $nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_complet'] != $nom_complet_ideal) {
                                        $nom_complet_traite = $this->repererEspace($nom['nom_complet']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomCompletEspece($noms) {
                $info = array('nom' => "nom_complet -> noms d'espèce",
                        'description' => "Si le rang est = à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
                                " genre + ' ' + epithete_sp \n".
                                "Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['rang'] == $this->manuel['rang_sp']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                $nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
                                $nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_complet'] != $nom_complet_ideal) {
                                        $nom_complet_traite = $this->repererEspace($nom['nom_complet']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomCompletInfraSpecifique($noms) {
                $info = array('nom' => 'nom_complet -> noms infra-spécifiques',
                        'description' => "Si le rang est > à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
                                " genre + ' ' + epithete_sp + ' ' + type_epithete + ' ' + epithete_infra_generique\n".  
                                "Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['rang'] > $this->manuel['rang_sp']) {
                                $suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
                                $nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
                                $nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
                                $nom_complet_ideal .= ' '.strtolower($nom['type_epithete']);
                                $nom_complet_ideal .= ' '.strtolower($nom['epithete_infra_sp']);
                                $nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
                                if ($nom['nom_complet'] != $nom_complet_ideal) {
                                        $nom_complet_traite = $this->repererEspace($nom['nom_complet']);
                                        $noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomSupraGeneriqueEspaces($noms) {
                $info = array('nom' => 'nom_supra_generique -> espaces en trop',
                        'description' => "Le champ nom_supra_generique ne doit pas contenir d'espace avant ou aprés le nom.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomSupraGeneriqueSyntaxe($noms) {
                $info = array('nom' => 'nom_supra_generique -> syntaxe',
                        'description' => "Le champ nom_supra_generique contient un mot composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
                                "La première lettre (avec ou sans tréma) du mot doit être en majuscule.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerNomSupraGeneriqueRang($noms) {
                $info = array('nom' => "nom_supra_generique -> rang < {$this->manuel['rang_genre']}",
                        'description' => "Si le champ nom_supra_generique n'est pas vide alors le rang du nom doit être inférieur à {$this->manuel['rang_genre']}.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['nom_supra_generique'] != '') {
                                if ($nom['rang'] >= $this->manuel['rang_genre']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerGenreEspaces($noms) {
                $info = array('nom' => 'genre -> espaces en trop',
                        'description' => "Le champ genre ne doit pas contenir d'espace avant ou aprés le nom.\n".
                                "Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerGenreSyntaxe($noms) {
                $info = array('nom' => 'genre -> syntaxe',
                        'description' => "Le champ genre peut contenir :\n".
                                " - un mot unique composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
                                "       Il commence par une lettre majuscule (avec ou sans tréma).". 
                                "       Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
                                " - une formule d'hybridité composée d'une série de noms de genre (au moins 2) séparés entre eux \n".
                                "       par la lettre x entourée de caractères espaces.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerGenreRang($noms) {
                $info = array('nom' => "genre -> rang >= {$this->manuel['rang_genre']}",
                        'description' => "Si le champ genre 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 ($noms as $nom) {
                        if ($nom['genre'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_genre']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
                
        private function testerEpitheteInfraGeneriqueSyntaxe($noms) {
                $info = array('nom' => 'epithete_infra_generique -> syntaxe',
                        'description' => "Le champ epithete_infra_generique est composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
                                "La première lettre (avec ou sans tréma) doit être en majuscule.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerEpitheteInfraGeneriqueRang($noms) {
                $info = array('nom' => "epithete_infra_generique -> {$this->manuel['rang_genre']} < rang < {$this->manuel['rang_sp']}",
                        'description' => "Si le champ epithete_infra_generique n'est pas vide alors le rang du nom doit être compris \n".
                                "entre {$this->manuel['rang_genre']} et {$this->manuel['rang_sp']}.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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_complet'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerEpitheteInfraGeneriqueEspaces($noms) {
                $info = array('nom' => 'epithete_infra_generique -> espaces en trop',
                        'description' => "Le champ epithete_infra_generique ne doit pas contenir d'espace avant ou aprés sa valeur.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerEpitheteSpEspaces($noms) {
                $info = array('nom' => 'epithete_sp -> espaces en trop',
                        'description' => "Le champ epithete_sp ne doit pas contenir d'espace avant ou aprés le nom.\n".
                                "Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerEpitheteSpSyntaxe($noms) {
                $info = array('nom' => 'epithete_sp -> syntaxe',
                        'description' => "Le champ epithete_sp peut contenir :\n".
                                " - un mot unique composé de lettres minuscules [a-z] incluant les caractères [ëï-]. \n".
                                "       Il commence par une lettre minuscule [a-zëï].\n". 
                                "       Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
                                " - un mot contenant sp. suivi d'un ou plusieurs caractères numériques (1-9) ou d'un seul caractère majuscule (A-Z) \n".
                                " - une formule d'hybridité composée d'une série de noms d'espèce (au moins 2) séparés entre eux \n".
                                "       par la lettre x entourée de caractères espaces.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($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;
                }
                
                $this->traiterResultatTest($info);
        }
        
        private function testerEpitheteSpRang($noms) {
                $info = array('nom' => "epithete_sp -> rang >= {$this->manuel['rang_sp']}",
                        'description' => "Si le champ epithete_sp n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_sp']}.",
                        'resultat' => false);
                
                // Réalisation du test
                $noms_erreur = array();
                foreach ($noms as $nom) {
                        if ($nom['epithete_sp'] != '') {
                                if ($nom['rang'] < $this->manuel['rang_sp']) {
                                        $noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
                                }
                        }
                }
                
                // Analyse des résultats
                if (count($noms_erreur) > 0) {
                        $info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
                        $info['message']['lignes'] = $noms_erreur;
                } else {
                        $info['resultat'] = true;
                }
                
                $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_complet) {
                $nom_complet = str_replace(' ', '<span class="espace">&nbsp;</span>', $nom_complet);
                return $nom_complet;
        }
        
        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 classerNomsParNumNom($noms) {
                $noms_classes = array();
                foreach ($noms as $nom) {
                        $noms_classes[$nom['num_nom']] = $nom;
                }
                return $noms_classes;
        }
        
        private function classerNomsParNomComplet($noms) {
                $noms_classes = array();
                foreach ($noms as $nom) {
                        if (!isset($noms_classes[$nom['nom_complet']])) {
                                $noms_classes[$nom['nom_complet']] = 1;
                        } else {
                                $noms_classes[$nom['nom_complet']]++;
                        }
                }
                return $noms_classes;
        }

}
?>