* @author Jean-Pascal MILCENT * @author Aurelien PERONNET * @license GPL v3 * @license CECILL v2 * @copyright 1999-2014 Tela Botanica */ class ListeImagesDeterminationsProbables { private $indexImagesIds = array(); private $conteneur; private $navigation; private $bdd; private $erreurs = array(); private $parametres = array(); private $protocoles = array(); private $idsImagesOrdonnees = array(); private $resultats = array(); private $propositions = array(); private $votes = array(); public function __construct(Conteneur $conteneur = null) { $this->conteneur = $conteneur == null ? new Conteneur() : $conteneur; $this->navigation = $conteneur->getNavigation(); $this->bdd = $this->conteneur->getBdd(); $this->chargerProtocoles(); } private function chargerProtocoles() { $requete = 'SELECT id_protocole FROM del_image_protocole -- '.__FILE__.' : '.__LINE__; $resultats = $this->bdd->recupererTous($requete); if ($resultats) { foreach ($resultats as $infos) { $this->protocoles[] = $infos['id_protocole']; } sort($this->protocoles); } } public function consulter($parametres) { $this->parametres = $parametres; $this->verifierParametres(); // Lancement du service $this->idsImagesOrdonnees = $this->getIdsImages(); $this->modifierEnteteTotal(); $infos = $this->chargerInfos(); if ($infos) { $this->traiterResultats($infos); $this->completerResutlats(); } // Mettre en forme le résultat et l'envoyer pour affichage $resultat = new ResultatService(); $resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $this->resultats); return $resultat; } private function verifierParametres() { $this->verifierParamProtocole(); $this->verifierParamVote(); if (!empty($this->erreurs)) { $msg = "Erreur de configuration :\n".implode("\n\n", $this->erreurs); throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE); } } private function verifierParamProtocole() { if (isset($this->parametres['masque.protocole'])) { $protocoleExistant = in_array($this->parametres['masque.protocole'], $this->protocoles); if (!is_numeric($this->parametres['masque.protocole']) || $protocoleExistant === false) { $protocolesListe = implode(', ', $this->protocoles); $msg = "La valeur pour le protocole doit être un entier compris dans les numéros de protocole ". "existants : $protocolesListe"; $this->erreurs[] = $msg; } } } private function verifierParamVote() { if (isset($this->parametres['masque.valeur_min_vote'])) { $minVote = $this->parametres['masque.valeur_min_vote']; if (!is_numeric($minVote) || ($minVote < 0 && $minVote > 5)) { $this->erreurs[] = "La valeur minimum de valeur des votes doit être un entier compris entre 0 et 5."; } } } private function getIdsImages() { $whereClause = $this->getClauseWhere(); $depart = $this->navigation->getDepart(); $limite = $this->navigation->getLimite(); $requete = 'SELECT DISTINCT SQL_CALC_FOUND_ROWS di.id_image '. 'FROM del_image AS di '. ' LEFT JOIN del_image_stat AS ds ON (di.id_image = ds.ce_image) '. "$whereClause ". 'ORDER BY moyenne DESC, id_image DESC '. "LIMIT $depart, $limite ". ' -- '.__FILE__.' : '.__LINE__; //Debug::printr($requete); $resultats = $this->bdd->recupererTous($requete); $idImgs = array(); if ($resultats !== false ) { foreach ($resultats as $resultat) { $idImgs[] = $resultat['id_image']; } } return $idImgs; } private function getClauseWhere() { $where = array(); if (isset($this->parametres['masque.protocole'])) { $protocoleIdP = $this->bdd->proteger($this->parametres['masque.protocole']); $where[] = "ds.ce_protocole = $protocoleIdP "; } if (isset($this->parametres['masque.valeur_vote_min'])) { $voteP = $this->bdd->proteger($this->parametres['masque.valeur_vote_min']); $where[] = "moyenne >= $voteP"; } return (count($where) > 0) ? 'WHERE '.implode(' AND ', $where).' ' : ''; } private function chargerInfos() { $idImgsConcat = implode(',', $this->idsImagesOrdonnees); $requete = 'SELECT DISTINCT SQL_CALC_FOUND_ROWS '. 'di.id_image, di.mots_cles_texte AS mots_cles_texte_image, '. 'do.id_observation, nom_referentiel, nom_ret, '. 'nom_ret_nn, nt, famille, ce_zone_geo, zone_geo, date_observation, '. 'do.ce_utilisateur, do.nom_utilisateur, do.prenom_utilisateur, '. 'du.prenom, du.nom '. 'FROM del_image AS di '. ' INNER JOIN del_observation AS do ON (di.ce_observation = do.id_observation) '. ' LEFT JOIN del_utilisateur AS du ON (di.ce_utilisateur = du.id_utilisateur) '. ' LEFT JOIN del_image_stat AS ds ON (di.id_image = ds.ce_image) '. "WHERE di.id_image IN ($idImgsConcat) ". 'ORDER BY moyenne DESC, id_image DESC '. ' -- '.__FILE__.' : '.__LINE__; //Debug::printr($requete); return $this->bdd->recupererTous($requete); } private function modifierEnteteTotal() { $requete = 'SELECT FOUND_ROWS() AS nbre -- '.__FILE__.' : '.__LINE__; $compte = $this->bdd->recuperer($requete); $total = ($compte !== false) ? (int) $compte['nbre'] : 0; $this->navigation->setTotal($total); } /** * Retourner un tableau d'images formaté en fonction des liaisons trouvées * @param $infos les infos sur les images et observations * */ private function traiterResultats($infos) { //Debug::printr($infos); foreach ($infos as $info) { $idImage = $info['id_image']; $index = $this->formaterIndexResultat($info); $this->obsIds[] = $info['id_observation']; $this->indexImagesIds[$idImage] = $index; $this->resultats[$index] = array( 'id_image' => $idImage, 'id_observation' => $info['id_observation'], 'auteur.intitule' => $this->formaterIntituleAuteur($info), 'binaire.href' => $this->formaterBinaireHref($info), 'determination.famille' => $info['famille'], 'determination.referentiel' => $info['nom_referentiel'], 'determination.ns' => $info['nom_ret'], 'determination.nn' => $info['nom_ret_nn'], 'determination.nt' => $info['nt'], 'date_observation' => $info['date_observation'], 'localite' => $this->formaterLieu($info), 'mots_cles_image_cel' => $this->formaterMotsClesCel($info), 'mots_cles_image_del' => '' ); } } private function formaterIndexResultat($infos) { return $infos['id_image'].'-'.$infos['id_observation']; } private function formaterIntituleAuteur($infos) { if ($infos['ce_utilisateur'] == 0) { $infos['prenom'] = $infos['prenom_utilisateur']; $infos['nom'] = $infos['nom_utilisateur']; } $intitule = $infos['prenom'].' '.$infos['nom']; return $intitule; } private function formaterBinaireHref($infos) { return sprintf( $this->conteneur->getParametre('cel_img_url_tpl'), $infos['id_image'], $this->conteneur->getParametre('determinations.format_image') ); } private function formaterLieu($infos) { $lieuFormate = ''; if ($infos['ce_zone_geo']) { $lieu = $infos['zone_geo']; $id_zone_geo = $infos['ce_zone_geo']; if (strpos($infos['ce_zone_geo'], 'INSEE-C:') === 0) { $id_zone_geo = str_replace('INSEE-C:', '', $infos['ce_zone_geo']); $id_zone_geo = strlen($id_zone_geo) >= 5 ? substr($id_zone_geo, 0, 2) : $id_zone_geo; } $lieuFormate = "$lieu ($id_zone_geo)"; } return $lieuFormate; } /** * Formater les mots clés du cel en n'affichant que ceux faisant partie d'une liste définie dans le * fichier de configuration. * * @param $infos le tableau contenant les infos sur une image. * @return string la chaine filtrée */ private function formaterMotsClesCel($infos) { $motsClesAffiches = $this->conteneur->getParametreTableau('determinations.mots_cles_cel_affiches'); $motsClesCel = explode(',', $infos['mots_cles_texte_image']); $motsCles = array_intersect($motsClesAffiches, $motsClesCel); return implode(',', $motsCles); } private function completerResutlats() { $this->chargerVotes(); $this->chargerPropositions(); $this->completerMotsCles(); foreach ($this->resultats as $index => $infos) { if ($this->doitRemplacerObservationParProposition($index)) { $id_obs = $infos['id_observation']; $this->resultats[$index]['determination.famille'] = $this->propositions[$id_obs]['famille']; $this->resultats[$index]['determination.ns'] = $this->propositions[$id_obs]['nom_sel']; $this->resultats[$index]['determination.nn'] = $this->propositions[$id_obs]['nom_sel_nn']; $this->resultats[$index]['determination.nt'] = $this->propositions[$id_obs]['nt']; $this->resultats[$index]['determination.referentiel'] = $this->propositions[$id_obs]['nom_referentiel']; } $this->completerUrlFicheEflore($index); } } private function chargerVotes() { $idsObs = implode(',', $this->obsIds); $requete = 'SELECT ce_proposition, valeur, ce_utilisateur '. 'FROM del_commentaire_vote '. 'WHERE ce_proposition IN '. '( SELECT id_commentaire '. ' FROM del_commentaire '. " WHERE ce_observation IN ($idsObs) AND nom_sel IS NOT NULL ) ". 'ORDER BY ce_proposition '. ' -- '.__FILE__.' : '.__LINE__; $resultats = $this->bdd->recupererTous($requete); if ($resultats !== false) { foreach ($resultats as $vote) { if (!isset($this->votes[$vote['ce_proposition']])) { $this->votes[$vote['ce_proposition']] = 0; } $valeur = ($vote['valeur'] == 1) ? 1 : -1; $this->votes[$vote['ce_proposition']] += is_numeric($vote['ce_utilisateur']) ? 3 * $valeur : $valeur; } } } private function chargerPropositions() { $idsObs = implode(',', $this->obsIds); $requete = 'SELECT * '. 'FROM del_commentaire '. "WHERE ce_observation IN ($idsObs) ". 'AND nom_sel IS NOT NULL '. ' -- '.__FILE__.' : '.__LINE__; $resultats = $this->bdd->recupererTous($requete); foreach($resultats as $proposition) { $id_proposition = $proposition['id_commentaire']; $id_obs = $proposition['ce_observation']; $proposition['valeur'] = (isset($this->votes[$id_proposition])) ? $this->votes[$id_proposition] : -1; if (!isset($this->propositions[$id_obs])) { $this->propositions[$id_obs] = $proposition; } else { $score_actuel = $proposition['valeur']; $score_precedent = $this->propositions[$id_obs]['valeur']; if ($score_actuel >= $score_precedent) { $this->propositions[$id_obs] = $proposition; } } } } private function completerMotsCles() { $idsImages = implode(',', array_keys($this->indexImagesIds)); $requete = 'SELECT tag, ce_image '. 'FROM del_image_tag '. "WHERE ce_image IN ($idsImages) ". 'AND actif = 1 '. ' -- '.__FILE__.' : '.__LINE__; $resultats = $this->bdd->recupererTous($requete); foreach ($resultats as $info) { $index = $this->indexImagesIds[$info['ce_image']]; $tag = ($this->resultats[$index]['mots_cles_image_del'] != '') ? ','.$info['tag'] : $info['tag']; $this->resultats[$index]['mots_cles_image_del'] .= $tag ; } } private function doitRemplacerObservationParProposition($index) { $idObs = $this->resultats[$index]['id_observation']; return ((isset($this->propositions[$idObs]) && $this->propositions[$idObs] != null && $this->propositions[$idObs]['nom_sel_nn'] != 0) && ($this->propositions[$idObs]['valeur'] > 0 || $this->resultats[$index]['determination.nn'] == 0) ); } private function completerUrlFicheEflore($index) { if (isset($this->resultats[$index]['determination.nn'])) { $urlTpl = $this->conteneur->getParametre('determinations.url_fiche_eflore_tpl'); $nn = (int) $this->resultats[$index]['determination.nn']; $ref = $this->resultats[$index]['determination.referentiel']; $code_ref = $this->getCodeReferentiel($ref); if (is_int($nn) && ! isset($code_ref)) { $code_ref = 'bdtfx'; } $this->resultats[$index]['url_fiche_eflore'] = sprintf($urlTpl, $code_ref, $nn); } } private function getCodeReferentiel($ref) { $code = $ref; if ($position = strpos($ref, '_')) { $code = substr($ref, 0, $position); } else if ($position = strpos($ref, ':')) { $code = substr($ref, 0, $position); } return $code; } }