* @author Jean-Pascal MILCENT * @copyright 2010 Tela-Botanica * @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL * @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL * @version SVN: $Id: Recherche.php 147 2010-09-06 09:37:22Z jpm $ */ class Recherche extends AppliControleur { private $chaine_recherche = null; private static $url_recherche = null; private static $url_fiche_taxon = null; private $referentiel = null; private $donnees_par_page; private $donnees_par_page_choix; //+----------------------------------------------------------------------------------------------------------------+ // Méthodes /** * Fonction d'affichage par défaut */ public function executerActionParDefaut() { return $this->rechercher(); } /** * Charge le moteur de recherche et l'envoie à la vue. */ public function chargerMoteurRecherche($ref = null, $affiche_rech_avancee = null) { $donnees = array(); $this->referentiel = $ref; // Gestion des données de la requête $donnees['recherche'] = htmlspecialchars($this->obtenirChaineRecherche()); // Gestion des urls $donnees['url_form'] = $this->obtenirUrlRecherche($this->referentiel); $donnees['url_referentiel'] = $this->referentiel; $referentielDao = new ReferentielDao(); $donnees['nom_referentiel'] = strtolower($referentielDao->getNom($this->referentiel)); $donnees['code_referentiel'] = strtoupper($this->referentiel); $donnees['date_miseajour'] = $referentielDao->getDateMiseAJour($this->referentiel); $donnees['forum_referentiel'] = Config::get('forum.'.$this->referentiel); $donnees['site_referentiel'] = Config::get('site.'.$this->referentiel); $donnees['url_module'] = 'Recherche'; $donnees['url_action'] = 'rechercher'; $donnees['affiche_moteur'] = $affiche_rech_avancee; self::$url_recherche = $this->obtenirUrlRecherche('%s','%s'); self::$url_fiche_taxon = $this->obtenirUrlFicheTaxon($this->referentiel, '%s'); // Gestion du squelette et de la sortie $this->setSortie(self::RENDU_TETE, $this->getVue('moteur', $donnees)); } private function obtenirChaineRecherche() { $chaine = ''; if (!is_null($this->chaine_recherche)) { $chaine = $this->chaine_recherche; } else if (isset($_GET['recherche'])) { // Pré-traitement de la chaine de recherche $chaine = $_GET['recherche']; // Suppression des slash ajouté automatiquement par PHP devant les guillemets $chaine = stripslashes($chaine); // Mémorisation de la chaine $this->memoriserChaineRecherche($chaine); // Stockage dans la classe pour éviter d'effectuer à nouveau le traitement ci-dessus $this->chaine_recherche = $chaine; } else if (isset($_SESSION['ref']['recherche'])) { $chaine = $_SESSION['ref']['recherche']; } return $chaine; } private function memoriserChaineRecherche($chaine) { $_SESSION['ref']['recherche'] = $chaine; } // url pour les exemples du moteur de recherche public static function getUrlRecherche($chaine, $referentiel = null) { $url = ''; if ($referentiel == null) $referentiel = $this->referentiel; if (!is_null(self::$url_recherche)) { // L'utilisation d'urlencode nécessiate de pré-encodé la chaine dans le format de sortie si nécessaire if (Config::get('sortie_encodage') != Config::get('appli_encodage')) { $chaine = mb_convert_encoding($chaine, Config::get('sortie_encodage'), Config::get('appli_encodage')); } $chaine = urlencode($chaine); $url = sprintf(self::$url_recherche, $referentiel, $chaine); } return $url; } public static function getUrlFicheTaxon($taxon) { $url = ''; if (!is_null(self::$url_fiche_taxon)) { $url = sprintf(self::$url_fiche_taxon, $taxon['num_nom']); } return $url; } /** * Recherche sur référentiel. * @return string la vue correspondante */ public function rechercher() { // Paramétres de pagination par défault $this->donnees_par_page = Config::get('resultat_par_page_defaut'); $this->donnees_par_page_choix = Config::get('resultat_par_page_choix'); $donnees = array(); $rechercheDao = new RechercheDao(); $parametres = array('mots' => '*'); // code du référentiel courant if (isset($_GET['ref'])) { $this->referentiel = strtolower($_GET['ref']); } // Gestion des squelettes $this->definirCommeModulePrincipal(get_class($this)); $this->construireMenu($this->referentiel); $this->construireFilAriane($this->referentiel); $this->chargerMoteurRecherche($this->referentiel, 10); // Récupération des paramètres de l'url $chaine_de_recherche = $this->obtenirChaineRecherche(); if (!empty($chaine_de_recherche)) { $this->url->setVariablesRequete(array('module' => 'Recherche', 'action' => 'rechercher', 'ref' => $this->referentiel, 'recherche' => $chaine_de_recherche)); } $parametres = $this->parserChaineDeRecherche($chaine_de_recherche); $parametres['ref'] = $this->referentiel; // requête spéciale de recherche de tous les synonymes et du nom retenu d'un paramétre if (isset($parametres['tax']) && ($parametres['tax'] == 1)) { $resultat = $this->chercherSynonymes($rechercheDao, $parametres); } else if (isset($parametres['classif'])) { $this->chargerTableauManuel('presence'); $donnees['valeur_presence'] = $this->tableau_manuel['presence']; $donnees['referentiel'] = $this->referentiel; $donnees['fragmenteur'] = $this->gererFragmenteur($rechercheDao, $parametres, 'NombreClassif'); $donnees['resultats'] = $rechercheDao->chercher('Classification', $parametres); $resultat = $this->getVue('resultat_recherche', $donnees); } else { $this->chargerTableauManuel('presence'); $donnees['valeur_presence'] = $this->tableau_manuel['presence']; $donnees['referentiel'] = $this->referentiel; $donnees['fragmenteur'] = $this->gererFragmenteur($rechercheDao, $parametres); $donnees['resultats'] = $rechercheDao->chercher('ParDefaut', $parametres); $resultat = $this->getVue('resultat_recherche', $donnees); } $this->setSortie(self::RENDU_CORPS, $resultat); } private function chercherSynonymes($rechercheDao, $parametres){ $this->donnees_par_page = 2; $this->donnees_par_page_choix = '1,2,5,10'; $donnees['referentiel'] = $this->referentiel; $donnees['fragmenteur'] = $this->gererFragmenteur($rechercheDao, $parametres, 'NombreTaxon'); $resultats = $rechercheDao->chercher('ParTaxon', $parametres); foreach ($resultats as $res) { if ($res['num_nom'] == $res['num_nom_retenu']) { $donnees['resultats']['nom_retenu'][$res['num_nom_retenu']] = $res; } else { $donnees['resultats'][$res['num_nom_retenu']][$res['num_nom']] = $res; } } $resultat = $this->getVue('resultat_recherche_taxon', $donnees); return $resultat; } private function gererFragmenteur($rechercheDao, $parametres, $type = 'Nombre') { // Gestion du nombre de résultats $donnees_total = $rechercheDao->chercherStructureNbre($type, $parametres); // Gestion du fragmenteur $options = array( 'url' => $this->url, 'donnees_total' => $donnees_total, 'donnees_par_page' => $this->donnees_par_page, 'donnees_par_page_choix' => $this->donnees_par_page_choix); $fragmenteur = Composant::fabrique('fragmenteur', $options); $donnees['fragmenteur'] = $fragmenteur->executer(); list($de, $a) = $fragmenteur->getDeplacementParPageId(); $this->url->unsetVariablesRequete(array('recherche', 'page')); // Gestion de l'accès aux données $rechercheDao->setLimitation(($de - 1), $fragmenteur->getDonneesParPage()); $rechercheDao->setDistinction(1); return $donnees['fragmenteur']; } private function parserChaineDeRecherche($chaine) { $mots = preg_split('/ /i', $chaine, -1, PREG_SPLIT_NO_EMPTY); $parametres = array('mots' => ''); $cle_precedente = null; foreach ($mots as $mot) { if (preg_match('/^(sg|gen|sp|ssp|au|an|nn|bib|nr|tax|pre|taxref|classif|rg):(.*)$/', $mot, $match)) { $cle = $match[1]; $cle_precedente = $cle; $valeur = $match[2]; $parametres[$cle] = $valeur; } else if (!is_null($cle_precedente)) { $parametres[$cle_precedente] .= ' '.$mot; } else if (is_null($cle_precedente)) { if (empty($parametres['mots'])) { $parametres['mots'] = $mot; } else { $parametres['mots'] .= ' '.$mot; } } } return $parametres; } // charger tableau de $this->manuel private function chargerTableauManuel($titreTableau) { $champs = explode(',', $this->manuel[$titreTableau]); foreach ($champs as $champ) { list($champ_nom, $type) = explode('=', trim($champ)); $this->tableau_manuel[$titreTableau][$champ_nom] = $type; } } }