* @author Samuel DUFOUR-KOWALSKI * @author Jean-Pascal MILCENT * @author Aurelien PERONNET * @license GPL v3 * @license CECILL v2 * @copyright 1999-2014 Tela Botanica */ class Changements { private $conteneur; private $navigation; private $bdd; private $parametres = array(); private $ressources = array(); private $date_defaut = '1900-01-01'; private $idsObsImg = array(); private $infosObsImg = array(); public function __construct(Conteneur $conteneur = null) { /* restore_exception_handler(); */ /* restore_error_handler(); */ /* ini_set("display_errors", "1"); */ $this->conteneur = $conteneur == null ? new Conteneur() : $conteneur; $this->navigation = $conteneur->getNavigation(); $this->bdd = $this->conteneur->getBdd(); } /** * Méthode principale de la classe. * Lance la récupération des images dans la base et les place dans un objet ResultatService * pour l'afficher. * @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2) * @param array $parametres les paramètres situés après le ? dans l'url * */ public function consulter($ressources, $parametres) { // initialiserRessourcesEtParametres() $this->ressources = $ressources; $this->parametres = $parametres; if (!isset($parametres['date'])) { $this->parametres['date'] = $this->date_defaut; } // Lancement du service $this->idsObsImg = $this->getIdsObsImg(); $infos = array(); $total = 0; if ($this->idsObsImg) { $total = $this->getTotal(); $this->infosObsImg = $this->recupererInfos(); $infos = $this->formaterInfos(); $infos = $this->chargerPropositionPlusProbable($infos); $infos = $this->orderArray($infos); } $this->navigation->setTotal($total); // Mettre en forme le résultat et l'envoyer pour affichage $resultat = new ResultatService(); $resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $infos); return $resultat; } /*------------------------------------------------------------------------------- CHARGEMENT DES IMAGES --------------------------------------------------------------------------------*/ private function getIdsObsImg() { $date_debut = "'{$this->parametres['date']}'"; $limite = @min(intval($this->parametres['navigation.limite']), 1000); $limite = $limite ? $limite : 10; // 0 => 10 $depart = intval(@$this->parametres['navigation.depart']); $requete = 'SELECT SQL_CALC_FOUND_ROWS p.id_observation, p.id_image, '. 'GROUP_CONCAT(iv.valeur) AS votes, '. 'GROUP_CONCAT(DISTINCT tag) AS tags, '. 'GREATEST('. ' IFNULL(p.date_creation, \''.$this->date_defaut.'\'), '. ' IFNULL(p.date_modification, \''.$this->date_defaut.'\'), '. ' IFNULL(MAX(it.date), \''.$this->date_defaut.'\'), '. ' IFNULL(MAX(it.date_modification), \''.$this->date_defaut.'\'), '. ' IFNULL(MAX(iv.date), \''.$this->date_defaut.'\'), '. ' IFNULL(MAX(c.date), \''.$this->date_defaut.'\'), '. ' IFNULL(MAX(cv.date), \''.$this->date_defaut.'\')) AS modif_date '. 'FROM del_plantnet AS p '. ' LEFT JOIN del_image_vote AS iv '. ' ON (id_image = iv.ce_image AND iv.ce_protocole = 3) '. ' LEFT JOIN del_image_tag AS it '. ' ON (id_image = it.ce_image AND it.actif = 1) '. ' LEFT JOIN del_commentaire AS c '. ' ON (id_observation = c.ce_observation) '. ' LEFT JOIN del_commentaire_vote AS cv '. ' ON (c.id_commentaire = cv.ce_proposition) '. 'GROUP BY id_image, id_observation '. 'HAVING MAX(p.date_creation) >= '.$date_debut.' '. ' OR MAX(p.date_modification) >= '.$date_debut.' '. ' OR MAX(it.date) >= '.$date_debut.' '. ' OR MAX(it.date_modification) >= '.$date_debut.' '. ' OR MAX(iv.date) >= '.$date_debut.' '. ' OR MAX(c.date) >= '.$date_debut.' '. ' OR MAX(cv.date) >= '.$date_debut.' '. 'ORDER BY modif_date DESC '. 'LIMIT '.$depart.', '.$limite. ' -- '.__FILE__.':'.__LINE__; //echo $requete; exit; // GROUP BY (très couteux) car multiples observations associées à une image // charlie est ici :-) // eg: 16150,16185,16245,16246,118995,129989 return $this->bdd->recupererTous($requete); } private function getTotal() { $compte = $this->bdd->recuperer('SELECT FOUND_ROWS() AS nbre'); $total = (int) $compte['nbre']; return $total; } // recupere les donnée associées (fait en 2 requetes pour optimiser) private function recupererInfos() { // recuperer les ids $idsImg = array(); foreach ($this->idsObsImg as $ids) { $id = $ids['id_image']; $idsImg[] = $id; } $idsImgConcat = implode(',', $idsImg); $requete = 'SELECT '. 'id_observation, id_image, '. 'nom_sel, '. 'nom_referentiel, nom_ret, nom_ret_nn, nt, famille, '. 'zone_geo, latitude, longitude, '. 'date_observation, date_creation, date_transmission, '. 'mots_cles_texte, '. 'ce_utilisateur, prenom_utilisateur, nom_utilisateur, courriel_utilisateur, '. 'i_mots_cles_texte AS mots_cles_texte_image, nom_original AS nom_image '. 'FROM del_plantnet AS p '. "WHERE id_image IN ($idsImgConcat) ". ' -- '.__FILE__.':'.__LINE__; // recuperer les donnees $resultats = $this->bdd->recupererTous($requete); // regroupe les données par id_image $img_data = array(); foreach ($resultats as $infos) { $idImg = $infos['id_image']; $img_data[$idImg] = $infos; } return $img_data; } /** * Retourner un tableau d'images formaté en fonction des liaisons trouvées * @param $liaisons les liaisons de la table del_obs_images */ private function formaterInfos() { // regroupe les observations $obs = array(); $imgCelTpl = $this->conteneur->getParametre('cel_img_url_tpl'); foreach ($this->idsObsImg as $ids) { $idobs = $ids['id_observation']; $idimg = $ids['id_image']; $imgdata = $this->infosObsImg[$idimg]; if (!isset($obs[$idobs])) { $obs[$idobs] = array(); } $obs[$idobs]['id_observation'] = $idobs; $obs[$idobs]['auteur_id'] = $imgdata['ce_utilisateur']; $obs[$idobs]['auteur_prenom'] = $imgdata['prenom_utilisateur']; $obs[$idobs]['auteur_nom'] = $imgdata['nom_utilisateur']; $obs[$idobs]['auteur_courriel'] = $imgdata['courriel_utilisateur']; $obs[$idobs]['mots_cles_obs_cel'] = $this->formaterMotsClesCel($imgdata['mots_cles_texte']); $obs[$idobs]['date_observation'] = $imgdata['date_observation']; $obs[$idobs]['date_publication'] = $imgdata['date_transmission']; $obs[$idobs]['date_creation'] = $imgdata['date_creation']; $obs[$idobs]['date_changement'] = $ids['modif_date']; $obs[$idobs]['nom_sel'] = $imgdata['nom_sel']; $obs[$idobs]['nom_referentiel'] = $imgdata['nom_referentiel']; $obs[$idobs]['nom_ret'] = $imgdata['nom_ret']; $obs[$idobs]['nn'] = $imgdata['nom_ret_nn']; $obs[$idobs]['nt'] = $imgdata['nt']; $obs[$idobs]['famille'] = $imgdata['famille']; $obs[$idobs]['zone_geo'] = $imgdata['zone_geo']; $obs[$idobs]['latitude'] = floatval($imgdata['latitude']); $obs[$idobs]['longitude'] = floatval($imgdata['longitude']); if (!isset($obs[$idobs]['images'])) { $obs[$idobs]['images'] = array(); } $img_obj = array( 'id_image' => $idimg, 'nom_image' => $imgdata['nom_image'], 'url' => sprintf($imgCelTpl, $idimg, 'O'), 'votes' => array_map('intval', explode(',', $ids['votes'])), 'tags' => explode(',', $ids['tags']), 'mots_cles_img_cel' => $this->formaterMotsClesCel($imgdata['mots_cles_texte_image']) ); // push $obs[$idobs]['images'][] = $img_obj; } return $obs; } /** * Charger les votes pour chaque image */ private function chargerPropositionPlusProbable(&$obs) { $obsIds = array_keys($obs); $idsObsConcat = implode(',', $obsIds); $requete = 'SELECT ce_observation, id_commentaire, valeur, nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, cv.ce_utilisateur '. 'FROM del_commentaire_vote AS cv, del_commentaire AS c '. "WHERE ce_observation IN ($idsObsConcat) ". 'AND nom_sel IS NOT NULL '. 'AND c.id_commentaire = cv.ce_proposition '. ' -- '.__FILE__.':'.__LINE__; $resultats = $this->bdd->recupererTous($requete); // calcul des votes // un vote identifié a un facteur de 3 // additionne tous les vote par ce_proposition $votes = array(); // map ce_proposition -> score foreach ($resultats as $vote) { if (!isset($votes[$vote['id_commentaire']])) { $votes[$vote['id_commentaire']] = 0; } $valeur = ($vote['valeur'] == 1) ? 1 : -1; $votes[$vote['id_commentaire']] += is_numeric($vote['ce_utilisateur']) ? 3 * $valeur : $valeur; } foreach ($resultats as $vote) { $idobs = $vote['ce_observation']; if (!isset($obs[$idobs]['determinations'])) { $obs[$idobs]['determinations'] = array(); } $obs[$idobs]['determinations'][$vote['id_commentaire']] = array('nom_sel' => $vote['nom_sel'], 'nom_ret' => $vote['nom_ret'], 'score' => $votes[$vote['id_commentaire']], 'nn' => $vote['nom_sel_nn']); } return $obs; } private function orderArray(&$obs) { $ret = array(); foreach ($obs as $o) { $ret[] = $o; } function cmp($a, $b) { return ($a['date_changement'] < $b['date_changement']) ? 1 : -1; } usort($ret, 'cmp'); return $ret; } /** * 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 $chaineMotCleCel la chaine de mots clés du cel * @return string la chaine filtrée */ private function formaterMotsClesCel($chaineMotCleCel) { $mots_cles_cel_affiches = "fleur,fleurs,feuille,feuilles,ecorce,fruit,fruits,port,plantnet,plantscan_new,plantnet-mobile"; $result = array_intersect( explode(',', $mots_cles_cel_affiches), // $tabMotsClesAffiches explode(',', $chaineMotCleCel)); // $tabMotsClesCel if (count($result) === 0) { return array(); } $ret = explode(',', implode(',', $result)); return $ret; } }