Rev 1838 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*** Librairie de recherche d'observations à partir de divers critères.* Encodage en entrée : utf8* Encodage en sortie : utf8** @category php 5.2* @package cel* @author Aurélien Peronnet <aurelien@tela-botania.org>* @copyright 2010 Tela-Botanica* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL* @version SVN: <svn_id>* @link /doc/jrest/*/class RechercheObservation extends Cel {public $requete_selection_observations;public function obtenirIdObservationsPourOrdre($id_utilisateur, $ordre) {$requete_selection_id = 'SELECT id_observation FROM cel_obs WHERE ordre ';if (is_array($ordre)) {$ordre = array_map(array(Cel::db(),'proteger'), $ordre);$requete_selection_id .= ' IN ('.implode(',',$ordre).') ';} else {$requete_selection_id .= ' = '.Cel::db()->proteger($ordre).' ';}$requete_selection_id .= ' AND ce_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ORDER BY id_observation';$resultat_ids = Cel::db()->executerRequete($requete_selection_id);$ids = array();if (is_array($resultat_ids)) {foreach ($resultat_ids as $resultat) {$ids[] = $resultat['id_observation'];}}return $ids;}public function rechercherObservations($id_utilisateur = null, $criteres = array(), $debut = 0, $limite = 50, $autoriser_sql_brut = FALSE) {$requete_selection_observations = 'SELECT * FROM cel_obs ';if ($id_utilisateur != null) {$requete_selection_observations .= 'WHERE ce_utilisateur = '.Cel::db()->proteger($id_utilisateur).' AND ';} else if(count($criteres) > 0) {$requete_selection_observations .= 'WHERE ';}// très mauvaise solution, mais qui permet au moins d'effectuer des requêtes complexes, sans modifier l'API// et sans pour autant introduire de problème de sécurité majeur dans toutes les fonctions appelantes qui// effectue $criteres = $_GET sans nettoyage préalable.if(isset($criteres['sql_brut']) && !$autoriser_sql_brut) unset($criteres['sql_brut']);$sous_requete_recherche = $this->fabriquerSousRequeteRecherche($id_utilisateur, $criteres);$requete_selection_observations .= $sous_requete_recherche;$requete_selection_observations = rtrim($requete_selection_observations, 'AND ');$requete_selection_observations .= $id_utilisateur == null ? ' ORDER BY id_observation, ordre ' : ' ORDER BY ordre ';$requete_selection_observations .= ($debut == 0 && $limite == 0) ? '' : ' LIMIT '.$debut.','.$limite ;$this->requete_selection_observations = $requete_selection_observations;return $this;}public function get() {if(!$this->requete_selection_observations) return FALSE;return Cel::db()->executerRequete($this->requete_selection_observations);}public function compterObservations($id_utilisateur = null, $criteres = array()) {$requete_selection_observations = 'SELECT COUNT(*) as nb_obs FROM cel_obs ';if ($id_utilisateur != null) {$requete_selection_observations .= 'WHERE ce_utilisateur = '.Cel::db()->proteger($id_utilisateur).' AND ';} else if(count($criteres) > 0) {$requete_selection_observations .= 'WHERE ';}$sous_requete_recherche = $this->fabriquerSousRequeteRecherche($id_utilisateur, $criteres);$requete_selection_observations .= $sous_requete_recherche;$requete_selection_observations = rtrim($requete_selection_observations, 'AND ');$nb_obs = '0';$resultat_requete_nombre_observations = Cel::db()->executerRequete($requete_selection_observations);if($resultat_requete_nombre_observations && is_array($resultat_requete_nombre_observations) && count($resultat_requete_nombre_observations) > 0) {$nb_obs = $resultat_requete_nombre_observations[0]['nb_obs'];}return $nb_obs;}public function formaterPourEnvoiCel(&$tableau_observations) {$ids = array();foreach ($tableau_observations as &$observation) {$observation['ce_zone_geo'] = $this->convertirCodeZoneGeoVersCodeInsee($observation['ce_zone_geo']);$ids_mots_cles = $this->getIdsMotsClesObservation($observation['id_observation']);$ids[] = $observation['id_observation'];$mots_cles_chaine = '';foreach ($ids_mots_cles as $id_mot_cle) {$mots_cles_chaine .= $id_mot_cle['id_mot_cle_obs'].';';}$mots_cles_chaine = rtrim($mots_cles_chaine,';');$observation['mots_cles'] = $mots_cles_chaine;foreach ($observation as $champ => $valeur) {if ($valeur == 'NULL') {$observation[$champ] = '';}}}$gestion_champs_etendus = new GestionChampsEtendus($this->config, 'obs');$champs_supp = $gestion_champs_etendus->consulterParLots($ids);foreach($tableau_observations as &$obs) {if(isset($champs_supp[$obs['id_observation']])) {$obs['obs_etendue'] = $champs_supp[$obs['id_observation']];}}return $tableau_observations;}public function obtenirCourrielUtilisateurPourIdObs($id_obs) {$id_obs = Cel::db()->proteger($id_obs);$requete = "SELECT courriel_utilisateur FROM cel_obs WHERE id_observation = $id_obs";$utilisateur_courriel = Cel::db()->executerRequete($requete . ' -- ' . __FILE__ . ':' . __LINE__);$retour = false;if (!empty($utilisateur_courriel) && isset($utilisateur_courriel[0]['courriel_utilisateur'])) {$retour = $utilisateur_courriel[0]['courriel_utilisateur'];}return $retour;}private function getIdsMotsClesObservation($id_observation) {$requete_selection_mots_cles = 'SELECT DISTINCT id_mot_cle_obs '.'FROM cel_obs_mots_cles '."WHERE id_observation = $id_observation ";return Cel::db()->executerRequete($requete_selection_mots_cles);}// TODO: fonction temporairepublic function parserRequeteCriteres($chaine_criteres) {$criteres_parses = array();$criteres = explode('&', $chaine_criteres) ;foreach ($criteres as &$critere) {$nom_valeur = explode('=', $critere) ;if (count($nom_valeur) >= 2) {$criteres_parses[$nom_valeur[0]] = $nom_valeur[1];}}return $criteres_parses;}private function fabriquerSousRequeteRecherche($id_utilisateur, $criteres) {$sous_requete = '';foreach ($criteres as $nom => $valeur) {if ($valeur == null || trim($nom) == '' || trim($valeur) == '') {continue;}switch ($nom) {case "mots_cles";$sous_requete .= $this->creerSousRequeteMotsCles($valeur);$sous_requete .= ' AND ';break;case 'annee':if ($valeur == "NULL") {$sous_requete .= "(date_observation IS NULL OR year(date_observation) = 0000)" ;} else {$sous_requete .= "(year(date_observation) = ".Cel::db()->proteger($valeur).")" ;}$sous_requete .= ' AND ' ;break;case 'mois':if ($valeur == "NULL") {$sous_requete .= "date_observation IS NULL OR month(date_observation) = 00" ;} else {$sous_requete .= "month(date_observation) = ".Cel::db()->proteger($valeur) ;}$sous_requete .= ' AND ' ;break;case 'jour':if ($valeur == "NULL") {$sous_requete .= "date_observation IS NULL OR day(date_observation) = 00" ;} else {$sous_requete .= "day(date_observation) = ".Cel::db()->proteger($valeur) ;}$sous_requete .= ' AND ' ;break;case 'departement':if ($valeur == "NULL") {$sous_requete .= "(ce_zone_geo IS NULL OR ce_zone_geo = '')";} else {if (strpos($valeur,',') !== false) {$dpts = explode(',',$valeur);$sous_requete .= '(';foreach($dpts as $dpt) {$sous_requete .= "ce_zone_geo LIKE ".Cel::db()->proteger('INSEE-C:'.$dpt.'___').' OR ';}$sous_requete = rtrim($sous_requete,' OR ').') ';} else {$sous_requete .= "(ce_zone_geo LIKE ".Cel::db()->proteger('INSEE-C:'.$valeur.'___').')';}}$sous_requete .= ' AND ' ;break;case 'commune':if ($valeur == "NULL") {$sous_requete .= "(zone_geo IS NULL OR zone_geo = '')";} else {$sous_requete .= "(zone_geo = ".Cel::db()->proteger($valeur).')';}$sous_requete .= ' AND ' ;break;case 'id_mots_cles':$liste_mc = '"'.str_replace(';','","',$valeur).'"';$sous_requete .= '' ;$sous_requete .= 'id_observation IN (SELECT id_observation FROM cel_obs_mots_cles WHERE id_mot_cle_obs IN ('.$liste_mc.'))';$sous_requete .= ' AND ' ;break;case 'recherche':$sous_requete .= $this->fabriquerSousRequeteRechercheGenerale($id_utilisateur, $valeur);$sous_requete .= ' AND ';break;case 'date_debut':$sous_requete .= 'date_observation >= '.Cel::db()->proteger($this->formaterEnDateMysql($valeur));$sous_requete .= ' AND ';break;case 'date_fin':$sous_requete .= 'date_observation <= '.Cel::db()->proteger($this->formaterEnDateMysql($valeur));$sous_requete .= ' AND ';break;case 'taxon':$valeur_protegee = Cel::db()->proteger($valeur."%");$sous_requete .= "( nom_sel LIKE ".$valeur_protegee." OR"." nom_ret LIKE ".$valeur_protegee." OR"." famille LIKE ".$valeur_protegee." ) AND ";break;case 'sql_brut':$sous_requete .= $valeur;$sous_requete .= ' AND ';break;default:if(!preg_match('/^[a-zA-Z0-9_-]+$/', $nom)) break;$valeur = rtrim($valeur);// TODO: pour de nombreux champs, et lorsque les webservices d'update/insert// trim() + NULLify'ront les données vides, alors nous pourrons omettre ce pénible// double-test pour la plupart des champsif ($valeur && $valeur != 'NULL') {$sous_requete .= $nom." = ".Cel::db()->proteger($valeur) ;$sous_requete .= ' AND ';}else {$sous_requete .= "($nom IS NULL OR $nom = '')";$sous_requete .= ' AND ';}break;}}$sous_requete = rtrim($sous_requete,' AND ');return $sous_requete;}private function formaterEnDateMysql($date) {$annee = substr($date, 6, 4);$mois = substr($date, 3, 2);$jour = substr($date, 0, 2);$date = $annee . '-' . $mois . '-' . $jour;return $date;}private function fabriquerSousRequeteRechercheGenerale($id_utilisateur, $valeur) {$valeur = str_replace("*","%",$valeur);$valeur = Cel::db()->proteger('%'.$valeur.'%');$sous_requete = "(nom_sel LIKE ".$valeur." OR courriel_utilisateur LIKE ".$valeur." OR prenom_utilisateur LIKE ".$valeur." OR nom_utilisateur LIKE ".$valeur." OR nom_sel LIKE ".$valeur." OR nom_sel_nn LIKE ".$valeur." OR nom_ret LIKE ".$valeur." OR nom_ret_nn LIKE ".$valeur." OR nt LIKE ".$valeur." OR famille LIKE ".$valeur." OR zone_geo LIKE ".$valeur." OR ce_zone_geo LIKE ".$valeur." OR date_observation LIKE ".$valeur." OR lieudit LIKE ".$valeur." OR station LIKE ".$valeur." OR milieu LIKE ".$valeur." OR commentaire LIKE ".$valeur." OR transmission LIKE ".$valeur." OR latitude LIKE ".$valeur." OR longitude LIKE ".$valeur." OR mots_cles_texte LIKE ".$valeur.")";return $sous_requete;}private function creerSousRequeteMotsCles($mot_cle) {$requete = '';if (preg_match('/.*OU.*/', $mot_cle)) {$mots_cles_tab = explode('OU',$mot_cle);foreach($mots_cles_tab as $mot_cle_item) {$requete .= '(mots_cles_texte LIKE '.Cel::db()->proteger('%'.$mot_cle_item.'%').') OR ';}$requete = '('.rtrim($requete,'OR ').')';} else if (preg_match('/.*ET.*/', $mot_cle)) {$mots_cles_tab = explode('ET',$mot_cle);foreach($mots_cles_tab as $mot_cle_item) {$requete .= '(mots_cles_texte LIKE '.Cel::db()->proteger('%'.$mot_cle_item.'%').') AND ';}$requete = '('.rtrim($requete, 'AND ').') ';} else {$requete = "(mots_cles_texte LIKE ".Cel::db()->proteger('%'.$mot_cle.'%').') ';}return $requete;}private function estUnvaleurZeroNulle($valeur) {return $valeur == '000null';}private function traiterRequeteValeurZeroNulle($valeur) {$champs = array('annee' => 'date_observation','mois' => 'date_observation','jour' => 'date_observation','departement' => 'ce_zone_geo','commune' => 'zone_geo');return $sous_requete .= $champs[$valeur]." = ".Cel::db()->proteger("");}}?>