Subversion Repositories eFlore/Applications.eflore-consultation

Rev

Rev 1186 | Blame | Last modification | View Log | RSS feed

<?php
class Recherche extends aControleur {
        
        //+----------------------------------------------------------------------------------------------------------------+
        // Méthodes
        protected $nom = null;
        protected $type_nom = 'nom_scientifique';
        protected $type_resultat = '';
        protected $submit = '';
        protected $acces_fiche = false;
        private $recherche_avancee;
        private $param;
        private $i18n =  array();
        
        private $parametresAvancesGeneriques = array('gen','fam','nn','nt','sp','ssp','type','sto','sti','stc');
        
        public function initialiser() {
                $this->capturerParametres();
                $this->capturerParametresAvances();     
                $this->i18n = I18n::get('Recherche-form-avancee');
        }
        
        /**
         * Fonction d'affichage par défaut
         */
        public function executerActionParDefaut() {
                $this->executerAccueil();
        }
        
        public function executerAccueil($donneesMoteur = array()) {
                
                $meta = new MetaDonnees();
                $meta->setProjet(Registre::get('parametres.referentiel'));
                $metadonnees = $meta->getMetaDonnees();
                $donneesMoteur['metadonnees_referentiel'] = $metadonnees[0];
                
                $niveau = new Niveau();
                $donnees['form_niveau'] = $niveau->afficherNiveau();
                $recherchesimple = new RechercheSimple();
                $donnees['form_nom'] = $recherchesimple->executerFormulaireNom($donneesMoteur);
                if (Registre::get('parametres.niveau') != 1) {
                        $recherche_avancee = new RechercheAvancee();
                        $donnees['form_recherche_av'] = $recherche_avancee->executerFormulaireRechercheAv($donneesMoteur);
                }
                $donnees['description'] = "";

                // le descriptif du référentiel est affiché lorsque seul le moteur est affiché (donc ni résultats, ni fiche)
                if(Registre::get('parametres.module') == 'recherche' && 
                        Registre::get('parametres.action') == 'action-par-defaut' &&
                        !Registre::get('resultats')) {
                        $referentiel = Registre::get('parametres.referentiel');
                        $wiki = new Wikini();
                        $description = $wiki->getDescriptionReferentielFormate($referentiel);
                        $donnees['description'] = $description;
                }
                $this->afficherAccueil($donnees);
        }
        
        private function afficherAccueil($donnees) {
                $donnees['i18n'] = I18n::get('Recherche-accueil');
                $this->setSortie(self::RENDU_CORPS, $this->getVue('recherche_accueil', $donnees), true);
        }

        
        //+---------------------------------------------recherche avancee-------------------------------------+ 
        public function executerRechercheAvancee() {
                $this->param = $this->nettoyerParametresDefautRechercheAvancee($this->param);
                $donnees['param'] = $this->param;
                $presence = $this->rechercherCriteresDemandes();
                if (empty($presence) && !empty($this->param)) {
                        $donnees['message_av']['attention'] = 'info_res_vide';
                } 
                $this->executerAccueil($donnees);
                if (Registre::get('resultats')) {
                        $_GET['resultat'] = $this->type_resultat;
                        $this->executerAction('Resultat', 'executerResultat');
                }
        }

        private function nettoyerParametresDefautRechercheAvancee($params) {
                $params_nettoyes = array();
                foreach ($params as $cle => $param) {
                        if(!preg_match("#^\(.*\)$#", $param)) {
                                $params_nettoyes[$cle] = $param;
                        }
                }
                return $params_nettoyes;
        }
        
        public function rechercherCriteresDemandes() {
                $noms = new Noms(Registre::get('parametres.referentiel'));
                $res = $noms->getRechercheAvancee($this->param);
                if ($res != false || $res['entete']['total'] != 0) {
                        if ($res['entete']['total'] == 1 ) {
                                $ids = array_keys($res['resultat']);
                                $nom = $res['resultat'][$ids[0]]['nom_sci'];
                                $url = $this->urls->obtenirUrlFiche($ids[0], 'nom_scientifique', $nom);
                                $this->redirigerVers($url);
                        } else {
                        $res['type'] = $this->type_nom;
                        Registre::set('resultats', $res);
                        }
                } else {
                        $res = '';
                }
                return $res;
        }
        
        //+---------------------------------------------recherche simple-------------------------------------+
        /*
          grep-friendly: ICI->executerRechercheSimple()
          En effet, cette méthode n'est jamais invoquée explicitement.
          Le processus est le suivant:
          * URL = index.php?type_nom=...&referentiel=..&module=recherche&action=rechercheSimple
          * AppControleur::initialiser()
          * `-> AppControleur::$parametres['action'] = $_GET['action']
          * `-> AppControleur::executerModule()
          *      `-> effecture $module->$action()
          * qui nous appelle ici
         */
        public function executerRechercheSimple() {
                $donnees['type_nom'] = $this->type_nom;
                $donnees['nom'] = $this->nom;
                if (strlen($donnees['nom']) < 3) {
                        $donnees['message']['attention'] = 'info_nb_lettres';
                } else {
                        $presence = $this->rechercherNom();
                        if ($presence == '') { // s'il n'y a pas de nom
                                $donnees['message']['attention'] = 'info_sp_abs';
                        } elseif ($presence == 'sans_correspondance') {
                                $res = Registre::get('resultats');
                                $id = array_keys($res['resultat']);
                                $donnees['message']['nom_ss_corresp']['id'] = $id[0];
                                $nom = array_shift($res['resultat']);
                                $donnees['message']['nom_ss_corresp']['nom'] = $nom['nom_sci'];
                        } elseif ($presence != 'ok') { // s'il y a des noms approchés
                                if (!Registre::get('resultats')) { // s'il n'y a aucun nom exact
                                        $donnees['message']['attention'] = 'info_sp_abs';
                                }
                                $donnees['message']['nom_approche'] = $presence;
                        }
                }

                $this->executerAccueil($donnees);
                if (Registre::get('resultats')) {
                        $_GET['resultat'] = $this->type_resultat;
                        $this->executerAction('Resultat', 'executerResultat');
                }
        }
        
        
        // regarde si il y a des résultats correspondant au nom recherché sinon recherche un nom approché
        // $noms classe métier nom ou nom
        private function rechercherNom() {
                $noms = ($this->type_nom == 'nom_vernaculaire') 
                                ? new NomsVernaculaires(Config::get(Registre::get('parametres.referentiel').'.referentielVerna')) 
                                : new Noms(Registre::get('parametres.referentiel'));
                $approche = '';
                $res = $noms->getRechercheEtendue($this->nom, $this->type_resultat);
                $form = I18n::get('Recherche-form-nom');

                if ($res == false || $res['entete']['total'] === 0) { // recherche nom approché
                        $approche = $this->rechercherNomApproche($noms);
                } elseif ($res['entete']['total'] == 1 || $this->acces_fiche) { // renvoie à la fiche
                        $approche = $this->traiterAccesFiche($res);
                } else { // affiche les résultats
                        $res['type'] = $this->type_nom;
                        Registre::set('resultats', $res);
                        $approche = 'ok';
                        if ($res['entete']['total'] < 3) { // si moins de 16 noms affiche en plus un nom approché
                                $approche = $this->rechercherNomApproche($noms);
                        }
                }
                
                // suppression des nomps en doublons + du nom déjà dans le moteur de recherche
                // TODO: comprendre d'ou viennent les noms en doublons. Peut-être une histoire de noms similaires avec un nom d'auteur
                // différent, qui une fois supprimé se retrouvent à être les même ? 
                if(is_array($approche)) {
                        $approche_sans_doublons = array();
                        foreach($approche as $element) {
                                if(!in_array($element, $approche_sans_doublons) && $element['nom'] != $this->nom) {
                                        $approche_sans_doublons[] = $element;
                                }
                        }
                        $approche = $approche_sans_doublons;
                }
                return $approche;
        }
        
        private function traiterAccesFiche($res) {
                $ids = array_keys($res['resultat']);
                if ($this->type_nom == 'nom_vernaculaire') {
                        $id = explode(':',$res['resultat'][$ids[0]]['nom_retenu.code']);
                        $id = $id[1];
                } else {
                        if ($res['resultat'][$ids[0]]['retenu'] == 'absent') { // dans le cas d'un nom sans correspondance
                                $res['type'] = $this->type_nom;
                                Registre::set('resultats', $res);
                                $approche = 'sans_correspondance';
                                return $approche;
                        } else {
                                $id = $ids[0];
                        }
                }
                $url = $this->urls->obtenirUrlFiche($id, $this->type_nom, $this->nom);
                $this->redirigerVers($url);
        }
        
        private function rechercherNomApproche($noms) {
                $approche = '';
                $res = $noms->getRechercheFloue($this->nom);
                if (!($res == false || $res['entete']['total'] === 0)) {
                        for ($i = 0; $i < 3; $i++) {
                                $nom_proche = array_shift($res['resultat']);
                                $approche[$i]['nom'] = ($this->type_nom == 'nom_vernaculaire') ? $nom_proche['nom'] : $nom_proche['nom_sci'];
                                $approche[$i]['url_nom_approche'] = $this->urls->obtenirUrlRechercheSimple($approche[$i]['nom'], $this->type_nom);
                        }
                }
                return $approche;
        }
        
        //+-----------------------------------------------méthodes utiles---------------------------------+
        
        private function capturerParametres() {
                if (isset($_REQUEST['nom'])) {
                        $this->nom = $this->convertirEncodageEntree(urldecode($_REQUEST['nom']));
                }
                if (isset($_GET['type_nom'])) {
                        $this->type_nom = $this->convertirEncodageEntree(urldecode($_GET['type_nom']));
                }
                if (isset($_GET['submit'])) {
                        $this->submit = $this->convertirEncodageEntree(urldecode($_GET['submit']));
                }
                if(isset($_GET['acces_fiche'])) {
                        $this->acces_fiche = true;
                }
                if (isset($_GET['niveau'])) {
                        Registre::set('parametres.niveau', $this->convertirEncodageEntree($_GET['niveau']));
                }
                if (isset($_GET['resultat'])) {
                        $this->type_resultat = $this->convertirEncodageEntree(urldecode($_GET['resultat']));
                } else {
                        $onglet_resultat = $this->recupererTableauConfig('affich_resultats');
                        $this->type_resultat = $onglet_resultat[Registre::get('parametres.niveau').'_'.$this->type_nom];
                }
        }
        
        private function capturerParametresAvances() {
                $this->capturerParametresAvancesGeneriques();
                $this->capturerParametresAvancesDependantsLangage();
                $this->capturerParametresAvancesPresenceSpecifiques();
        }
        
        private function capturerParametresAvancesGeneriques() {
                foreach($this->parametresAvancesGeneriques as $param) {
                        if (isset($_GET[$param]) && $_GET[$param] != '') {
                                $this->param[$param] = $this->convertirEncodageEntree(urldecode($_GET[$param]));
                        }
                }
        }
        
        private function capturerParametresAvancesDependantsLangage() {
                if (isset($_GET['au']) && $_GET['au'] != ''
                && $_GET['au'] != $this->convertirEncodageEntree(urlencode($this->i18n['valeur-form-auteur']))) {
                        $this->param['au'] = $this->convertirEncodageEntree(urldecode($_GET['au']));
                }
                if (isset($_GET['bib']) && $_GET['bib'] != ''
                && $_GET['bib'] != $this->convertirEncodageEntree(urlencode($this->i18n['valeur-form-bib']))) {
                        $this->param['bib'] = $this->convertirEncodageEntree(urldecode($_GET['bib']));
                }
                if (isset($_GET['and']) && $_GET['and'] != ''
                && $_GET['and'] != $this->convertirEncodageEntree(urlencode($this->i18n['valeur-form-date']))) {
                        $this->param['and'] = $this->convertirEncodageEntree(urldecode($_GET['and']));
                }
                if (isset($_GET['anf']) && $_GET['anf'] != ''
                && $_GET['anf'] != urlencode($this->i18n['valeur-form-date'])) {
                        $this->param['anf'] = $this->convertirEncodageEntree(urldecode($_GET['anf']));
                }
        }
        
        private function capturerParametresAvancesPresenceSpecifiques()  {
                $champs_presence = $this->obtenirChampsPresence();
                foreach($champs_presence as $champ) {
                        $param = $champ['param'];
                        if (isset($_GET[$param]) && $_GET[$param] != '') {
                                $this->param[$param] = $this->convertirEncodageEntree(urldecode($_GET[$param]));
                        }
                }
        }
        
        private function obtenirChampsPresence() {
                $tableau_champs_presence = array();
                $referentiel = Registre::get('parametres.referentiel');
                $champs_presence_spl = explode('|', Config::get($referentiel.'.champsPresence'));
                foreach($champs_presence_spl as $champ) {
                        $label_param_champ = explode(':', $champ);
                        if(count($label_param_champ) >= 2) {
                                $tableau_champs_presence[] = array('param' => $label_param_champ[1],
                                                                                                                'label' => $label_param_champ[0]);
                        }
                }
                return $tableau_champs_presence;
        }
        
        protected function recupererTableauConfig($param) {
                $tableau = array();
                $tableauPartiel = explode(',', Config::get($param));
                $tableauPartiel = array_map('trim', $tableauPartiel);
                foreach ($tableauPartiel as $champ) {
                        if (strpos($champ, '=') === false) {
                                $tableau[] = $champ;
                        } else {
                                list($cle, $val) = explode('=', $champ);
                                $tableau[$cle] = $val;
                        }
                }
                return $tableau;
        }


         /**
         * Convertion des valeurs de requête dans l'encodage de l'application (voir fichier config.ini : appli_encodage),
         * A cause d'un bug en cours d'investigation, celle ci utilise des paramètres différents de la fonction de conversion 
         * D'encodage de sortie
         * Cette convertion a lieu seulement si les formats sont différents.
         */
        private function convertirEncodageEntree($contenu) {
                if (Config::get('sortie_encodage') != Config::get('appli_encodage')) {
                        $contenu = mb_convert_encoding($contenu, Config::get('appli_encodage'), Config::get('sortie_encodage'));
                }
                return $contenu;
        }
        
}
?>