Rev 1933 | Rev 2049 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php// declare(encoding='UTF-8');/*** Web service récupèrant toutes les observations et, pour chacune d'elle, les images qui lui sont associées.** ATTENTION : le web service commence par récupérer seulement les id des obs (1er requete SQL), puis dans une* deuxième requête SQL récupère les informations complémentaires. Il s'avère qu'en procédant ainsi le web service* est 3 fois plus rapide !** @category DEL* @package Services* @subpackage Observations* @version 0.1* @author Mathias CHOUET <mathias@tela-botanica.org>* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>* @author Aurelien PERONNET <aurelien@tela-botanica.org>* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>* @copyright 1999-2014 Tela Botanica <accueil@tela-botanica.org>*/class ListeObservations {private $conteneur;private $bdd;private $navigation;private $filtrage;private $sql;private $mappings = array();private $paramsFiltres = array();private $idsObsOrdonnees = array();private $infosObs = array();private $infosObsOrdonnee = array();public function __construct(Conteneur $conteneur) {$this->conteneur = $conteneur;$this->conteneur->chargerConfiguration('config_departements_bruts.ini');$this->bdd = $this->conteneur->getBdd();$this->filtrage = $this->conteneur->getParametresFiltrage();$this->sql = $this->conteneur->getSql();$this->navigation = $this->conteneur->getNavigation();$this->mappings['votes'] = $this->conteneur->getParametreTableau('votes.mapping');$this->mappings['commentaires'] = $this->conteneur->getParametreTableau('commentaires.mapping');}public function consulter($ressources, $parametres) {$this->paramsFiltres = $this->filtrage->filtrerUrlParamsAppliObs();$this->sql->setAppli(Sql::APPLI_OBS);$this->sql->setParametres($this->paramsFiltres);$this->sql->ajouterContraintes();$this->sql->ajouterConstrainteAppliObs();$this->sql->definirOrdreSqlAppliObs();$this->idsObsOrdonnees = $this->getIdObs();$this->navigation->setTotal($this->sql->getTotalLignesTrouvees());// Ce n'est pas la peine de continuer s'il n'y a pas eu de résultats$resultat = new ResultatService();$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => array());if (count($this->idsObsOrdonnees) > 0) {// 2) récupération des données nécessaires pour ces observations (obs + images)$this->infosObs = $this->getInfosObs();// 3) suppression, merge des données en tableau assez représentatif du futur JSON en output$this->infosObsOrdonnees = $this->formaterObservations();// 4) Ajouter commentaires + votes à $this->infosObsOrdonnees$this->chargerDeterminations();$resultat->corps = array('entete' => $this->navigation->getEntete(),// 5) Applatissage du tableau afin de garder l'ordre de tri// (qui n'est pas garanti dans un objet json)'resultats' => array_values($this->infosObsOrdonnees));}return $resultat;}// SQL helpers/** Retourne une liste ordonnée d'id d'observation correspondant aux critères* passés dans p et aux clauses where/join présentes dans le tableau $req** @param p: $params (filtrés sauf escape-string)* @param req: le tableau représentant les composants de la requete SQL* @param db: l'instance de db*/private function getIdObs() {$requete = 'SELECT SQL_CALC_FOUND_ROWS id_observation '.'FROM del_observation AS do '.$this->sql->getJoin().'WHERE '.$this->sql->getWhere().$this->sql->getGroupBy().$this->sql->getOrderBy().$this->sql->getLimit().' -- '.__FILE__.':'.__LINE__;//Debug::printr($requete);$resultats = $this->bdd->recupererTous($requete);$idObs = array();if ($resultats !== false ) {foreach ($resultats as $resultat) {$idObs[] = $resultat['id_observation'];}}return $idObs;}/*** Après avoir récupérer seulement les ids dans une première requête, nous récupérons maintenant les infos.* Le web service est ainsi 3 fois plus rapide.*/private function getInfosObs() {$idsObsConcat = implode(',', $this->idsObsOrdonnees);$requete = "SELECT id_observation, nom_sel AS `determination.ns`, nt AS `determination.nt`, ".'nom_sel_nn AS `determination.nn`, famille AS `determination.famille`, '.'nom_referentiel AS `determination.referentiel`, ce_zone_geo AS id_zone_geo, '.'zone_geo, lieudit, station, milieu, date_observation, do.mots_cles_texte, '.'do.date_transmission, do.commentaire, '.'do.ce_utilisateur AS `auteur.id`, do.prenom_utilisateur AS `auteur.prenom`, '.'do.nom_utilisateur AS `auteur.nom`, do.courriel_utilisateur AS `auteur.courriel`, '.'id_image, date_prise_de_vue AS `date`, hauteur, largeur, nom_original '.'FROM del_observation AS do '.' LEFT JOIN del_image AS di ON (do.id_observation = di.ce_observation) '."WHERE id_observation IN ($idsObsConcat) ".' -- '.__FILE__.':'.__LINE__;//Debug::printr($requete);return $this->bdd->recupererTous($requete);}/*** Les informations étant extraites d'une vue dont les infos des obs sont dupliquées pour chaque image,* il nous faut maintenant récupérer qu'une seule fois les données d'observations et y intégrer les données* des images.*/private function formaterObservations() {$observations = array_map('array_filter', $this->infosObs);$obsFormatees = array_flip($this->idsObsOrdonnees);// Permet de garder l'ordre de sortie !foreach ($observations as &$obs) {$this->nettoyerAuteur($obs);$id = $obs['id_observation'];// ATTENTION : la requête retourne de nombreuses lignes avec les mêmes données (test de l'existence nécessaire)if (is_array($obsFormatees[$id]) === false) {$obsFormatees[$id] = $obs;}$obsFormatees[$id]['images'][] = $this->extraireInfosImage($obs);}return $obsFormatees;}private function nettoyerAuteur(&$obs) {// car auteur.id peut être un email, un hash, ou un annuaire_tela.U_ID// mais dans les deux premiers cas SELECT courriel AS observateur fait déjà l'affaireif (!isset($obs['auteur.id']) || !is_numeric($obs['auteur.id'])) {$obs['auteur.id'] = "0";}if (!isset($obs['auteur.nom'])) {$obs['auteur.nom'] = '[inconnu]';}}private function extraireInfosImage(&$obs) {$champsImageAffichables = array('id_image', 'date', 'hauteur' , 'largeur', 'nom_original');$image = array_intersect_key($obs, array_flip($champsImageAffichables));$urlImgTpl = $this->conteneur->getParametre('cel_img_url_tpl');$image['binaire.href'] = sprintf($urlImgTpl, $image['id_image'], 'XL');unset($obs['id_image'], $obs['date'], $obs['hauteur'], $obs['largeur'], $obs['nom_original']);return $image;}/*** Récupérer toutes les déterminations et le nombre de commentaire au total* @param array $observations la liste des observations à mettre à jour*/private function chargerDeterminations() {$idObsConcat = implode(',', $this->idsObsOrdonnees);$requete = 'SELECT * '.'FROM del_commentaire AS dc '.'WHERE dc.nom_sel IS NOT NULL '."AND ce_observation IN ($idObsConcat) ".'-- '.__FILE__.':'.__LINE__;$commentaires = $this->chargerNombreCommentaireObs();$propositions = $this->bdd->recupererTous($requete);if ($propositions) {foreach ($propositions as $proposition) {$idObs = $proposition['ce_observation'];$idComment = $proposition['id_commentaire'];$comment = $this->formaterDetermination($idComment, $proposition);if ($comment) {$this->infosObsOrdonnees[$idObs]['commentaires'][$idComment] = $comment;}$this->infosObsOrdonnees[$idObs]['nb_commentaires'] = isset($commentaires[$idObs]) ? $commentaires[$idObs] : 0;}}}private function formaterDetermination($propositionId, $propositionInfos) {if (!$propositionInfos) return NULL;$propositionFormatee = array();foreach ($this->mappings['commentaires'] as $nomChamp => $nomAttributJson) {if (isset($propositionInfos[$nomChamp])) {$propositionFormatee[$nomAttributJson] = $propositionInfos[$nomChamp];}}// Charger les votes sur les déterminations$requete = "SELECT * FROM del_commentaire_vote WHERE ce_proposition = $propositionId".'-- '.__FILE__.':'.__LINE__;$resultatsVotes = $this->bdd->recupererTous($requete);foreach ($resultatsVotes as $vote) {$propositionFormatee['votes'][$vote['id_vote']] = $this->formaterVote($vote);}$propositionFormatee['nb_commentaires'] = $this->chargerNombreCommentaire($propositionId);return $propositionFormatee;}/*** Formater un vote en fonction du fichier de configuration config_votes.ini* @param $votes array()*/private function formaterVote($vote) {$voteFormate = array();foreach ($vote as $nomChamp => $valeur) {$voteFormate[$this->mappings['votes'][$nomChamp]] = $valeur;}return $voteFormate;}private function chargerNombreCommentaireObs() {$idObsConcat = implode(',', $this->idsObsOrdonnees);$requete = 'SELECT ce_observation, COUNT( id_commentaire ) AS nb '.'FROM del_commentaire '."WHERE ce_observation IN ($idObsConcat) ".'GROUP BY ce_observation '.'-- '.__FILE__.':'.__LINE__;$commentaires = $this->bdd->recupererTous($requete);$commentaires_par_obs = array();foreach($commentaires as $commentaire) {$commentaires_par_obs[$commentaire['ce_observation']] = $commentaire['nb'];}return $commentaires_par_obs;}private function chargerNombreCommentaire($propositionId) {$requete = 'SELECT COUNT( id_commentaire ) AS nb '.'FROM del_commentaire '."WHERE ce_proposition = $propositionId ".'GROUP BY ce_proposition '.'-- '.__FILE__.':'.__LINE__;$commentaires = $this->bdd->recuperer($requete);return $commentaires ? $commentaires['nb'] : 0;}}