Subversion Repositories eFlore/Applications.del

Rev

Rev 1681 | Rev 1793 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1593 samuel 1
<?php
2
/**
1663 samuel 3
 * Le web service plantnet récupère toutes les image de la table v_del_image
4
 * ordonées par date de modification
5
 * Les images sont regroupées en observations
6
 * Les tags, les votes et les propositions de determinations sont intégrés à l'observation
7
 *
1593 samuel 8
 *
9
 * @category	php 5.2
1663 samuel 10
 * @author	Samuel Dufour-Kowalski <samuel.dufour@cirad.fr>
11
 * @author	Mathias Chouet <mathias@tela-botanica.org>
12
 * @author	Raphaël Droz <raphael@tela-botanica.org>
13
 * @author	Aurélien Peronnet <aurelien@tela-botanica.org>
14
 
15
 
1593 samuel 16
 * @license	http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
17
 * @license	http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
18
 * @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=ApiIdentiplante01Images
19
 */
20
 
21
class Changements {
22
 
23
	private $indexImagesIds = array();
24
	private $conteneur;
25
	private $navigation;
26
	private $masque;
27
	private $gestionBdd;
28
	private $bdd;
29
	private $parametres = array();
30
	private $ressources = array();
31
	private $date_defaut = '1900-01-01';
32
 
33
	public function __construct(Conteneur $conteneur = null) {
34
 
35
          /* restore_exception_handler(); */
36
          /* restore_error_handler(); */
37
          /* ini_set("display_errors", "1"); */
38
 
39
		$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
40
		$this->conteneur->chargerConfiguration('config_plantnet.ini');
41
		$this->navigation = $conteneur->getNavigation();
42
		$this->masque = $conteneur->getMasque();
43
		$this->gestionBdd = $conteneur->getGestionBdd();
44
		$this->bdd = $this->gestionBdd->getBdd();
45
	}
46
 
47
	/**
48
	 * Méthode principale de la classe.
49
	 * Lance la récupération des images dans la base et les place dans un objet ResultatService
50
	 * pour l'afficher.
51
	 * @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
52
	 * @param array $parametres les paramètres situés après le ? dans l'url
53
	 * */
54
	public function consulter($ressources, $parametres) {
55
 
56
 
57
		// initialiserRessourcesEtParametres()
58
		$this->ressources = $ressources;
59
		$this->parametres = $parametres;
60
 
61
 
62
		if(!isset($parametres['date'])) {
63
			$this->parametres['date'] = $this->date_defaut;
64
		}
65
 
66
 
67
		// Lancement du service
68
		$liaisons = $this->chargerLiaisons();
69
                $images = array();
70
		$total = 0;
71
 
72
		if($liaisons) {
73
                  $compte = $this->bdd->recuperer('SELECT FOUND_ROWS() AS nbre');
74
                  $total = (int) $compte['nbre'];
75
 
1681 samuel 76
                  $imgdata = $this->recupererDonneeObs($liaisons);
77
                  $obs = $this->regrouperObs($liaisons, $imgdata);
78
 
1640 samuel 79
                  $obs = $this->chargerPropositionPlusProbable($obs);
1643 samuel 80
                  $obs = $this->orderArray($obs);
1593 samuel 81
		}
82
 
83
		$this->navigation->setTotal($total);
84
 
85
		// Mettre en forme le résultat et l'envoyer pour affichage
86
		$resultat = new ResultatService();
87
		//$resultat->corps = array('entete' => $this->conteneur->getEntete(), 'resultats' => $images);
88
                $resultat->corps = array('entete' => $this->conteneur->getEntete(), 'resultats' => $obs);
89
 
90
		return $resultat;
91
	}
92
 
1643 samuel 93
 
94
        private function orderArray(&$obs) {
95
 
96
          $ret = array();
97
 
98
          foreach ($obs as $o) {
99
            $ret[] = $o;
100
          }
101
 
102
          function cmp($a, $b) {
103
            return ($a['date_changement'] < $b['date_changement']) ? 1 : -1;
104
          }
105
 
106
          usort($ret, 'cmp');
107
          return $ret;
108
        }
1593 samuel 109
	/*-------------------------------------------------------------------------------
110
								CHARGEMENT DES IMAGES
111
	--------------------------------------------------------------------------------*/
112
	private function chargerLiaisons() {
113
 
114
          $date_debut = $this->parametres['date'];
1642 samuel 115
          $date_debut = '\'' . $date_debut . '\'';
1593 samuel 116
          $limite = @min(intval($this->parametres['navigation.limite']), 1000);
117
          $limite = $limite ? $limite : 10; // 0 => 10
118
          $depart = intval(@$this->parametres['navigation.depart']);
119
 
120
 
1642 samuel 121
 
1593 samuel 122
          $requete_sql =
123
            'select SQL_CALC_FOUND_ROWS vdi.id_observation, vdi.id_image, '.
124
 
125
            'GROUP_CONCAT(del_image_vote.valeur) as votes, GROUP_CONCAT(DISTINCT tag) as tags, '.
126
 
1701 samuel 127
            'GREATEST('.
128
            'IFNULL(vdi.date_creation, \''.$this->date_defaut.'\'), '.
129
            'IFNULL(vdi.date_modification, \''.$this->date_defaut.'\'), '.
130
            'IFNULL(MAX(del_image_tag.date), \''.$this->date_defaut.'\'), '.
131
            'IFNULL(MAX(del_image_tag.date_modification), \''.$this->date_defaut.'\'), '.
132
            'IFNULL(MAX(del_image_vote.date), \''.$this->date_defaut.'\'), '.
133
            'IFNULL(MAX(del_commentaire.date), \''.$this->date_defaut.'\'), '.
134
            'IFNULL(MAX(del_commentaire_vote.date), \''.$this->date_defaut.'\')) as modif_date '.
1593 samuel 135
 
136
            'from v_del_image as vdi '.
137
 
1701 samuel 138
            'left join del_image_vote on del_image_vote.ce_image=id_image and del_image_vote.ce_protocole=3 '.
139
            'left join del_image_tag on del_image_tag.ce_image=id_image and del_image_tag.actif=1 '.
1593 samuel 140
            'left join del_commentaire on del_commentaire.ce_observation=id_observation '.
141
            'left join del_commentaire_vote on del_commentaire_vote.ce_proposition=del_commentaire.id_commentaire '.
142
 
143
            'group by id_image, id_observation '.
144
 
145
            'having MAX(vdi.date_creation) >= '.$date_debut.' or '.
146
            '       MAX(vdi.date_modification) >= '.$date_debut.' or '.
147
            '       MAX(del_image_tag.date) >= '.$date_debut.' or '.
148
            '       MAX(del_image_tag.date_modification) >= '.$date_debut.' or '.
149
            '       MAX(del_image_vote.date) >= '.$date_debut.' or '.
150
            '       MAX(del_commentaire.date) >= '.$date_debut.' or '.
151
            '       MAX(del_commentaire_vote.date) >= '.$date_debut.' '.
152
            'order by modif_date DESC '.
153
            'limit '.$depart.', '.$limite.' -- '.__FILE__.':'.__LINE__;
154
 
1643 samuel 155
          //echo $requete_sql; exit;
156
 
1593 samuel 157
          return $this->bdd->recupererTous($requete_sql);
158
 
159
 
160
 
1663 samuel 161
          // GROUP BY (très couteux) car multiples observations associées à une image
162
          // charlie est ici :-)
163
          // eg: 16150,16185,16245,16246,118995,129989
1593 samuel 164
 
165
	}
166
 
1681 samuel 167
 
168
        // recupere les donnée associées (fait en 2 requetes pour optimiser)
169
        private function recupererDonneeObs(&$liaisons) {
170
 
171
          // recuperer les ids
172
          $ids = array();
173
          foreach ($liaisons as $img) {
174
            $id = $img['id_image'];
175
            $ids[] = $id;
176
          }
177
 
178
          // recuperer les donnees
179
          $resultats = $this->bdd->recupererTous(sprintf(
180
                  'SELECT  '.
181
                  'vdi.id_observation, vdi.id_image, '.
182
                  'vdi.nom_sel, '.
183
                  'vdi.nom_referentiel, vdi.nom_ret, vdi.nom_ret_nn, vdi.nt, vdi.famille, '.
184
                  'vdi.zone_geo, vdi.latitude, vdi.longitude, '.
185
                  'vdi.date_observation, vdi.date_creation, vdi.date_transmission, '.
186
                  'vdi.mots_cles_texte as mots_cles_texte, '.
187
                  'vdi.i_mots_cles_texte as mots_cles_texte_image, '.
188
 
189
                  'vdi.ce_utilisateur as ce_utilisateur, '.
190
                  'vdi.prenom_utilisateur, vdi.courriel_utilisateur, vdi.nom_utilisateur, vdi.nom_original as nom_image '.
191
 
192
                  'FROM v_del_image as vdi '.
193
                  'WHERE vdi.id_image IN (%s) '.
194
                  '', implode(',', $ids)));
195
 
196
          // regroupe les données par id_image
197
          $img_data = array();
198
          foreach ($resultats as $img) {
199
            $id = $img['id_image'];
200
            $img_data[$id] = $img;
201
          }
202
          return $img_data;
203
        }
204
 
1593 samuel 205
	/**
206
	* Retourner un tableau d'images formaté en fonction des liaisons trouvées
207
	* @param $liaisons les liaisons de la table del_obs_images
208
	* */
1681 samuel 209
	private function regrouperObs(&$liaisons, &$imgdatas) {
1593 samuel 210
 
211
          // regroupe les observations
212
          $obs = array();
213
          foreach ($liaisons as $img) {
214
            $idobs = $img['id_observation'];
1681 samuel 215
            $idimg = $img['id_image'];
1593 samuel 216
 
1681 samuel 217
            $imgdata = $imgdatas[$idimg];
218
 
1593 samuel 219
            if (!isset($obs[$idobs])) {
220
              $obs[$idobs] = array();
221
            }
222
 
223
            $obs[$idobs]['id_observation'] = $idobs;
1681 samuel 224
            $obs[$idobs]['auteur_id'] = $imgdata['ce_utilisateur'];
225
            $obs[$idobs]['auteur_prenom'] = $imgdata['prenom_utilisateur'];
226
            $obs[$idobs]['auteur_nom'] = $imgdata['nom_utilisateur'];
227
            $obs[$idobs]['auteur_courriel'] = $imgdata['courriel_utilisateur'];
1593 samuel 228
 
1681 samuel 229
            $obs[$idobs]['mots_cles_obs_cel'] = $this->formaterMotsClesCel($imgdata['mots_cles_texte']);
1640 samuel 230
 
1681 samuel 231
            $obs[$idobs]['date_observation'] = $imgdata['date_observation'];
232
            $obs[$idobs]['date_publication'] = $imgdata['date_transmission'];
233
            $obs[$idobs]['date_creation'] = $imgdata['date_creation'];
1640 samuel 234
            $obs[$idobs]['date_changement'] = $img['modif_date'];
235
 
1681 samuel 236
            $obs[$idobs]['nom_sel'] = $imgdata['nom_sel'];
237
            $obs[$idobs]['nom_referentiel'] = $imgdata['nom_referentiel'];
238
            $obs[$idobs]['nom_ret'] = $imgdata['nom_ret'];
239
            $obs[$idobs]['nn'] = $imgdata['nom_ret_nn'];
240
            $obs[$idobs]['nt'] = $imgdata['nt'];
241
            $obs[$idobs]['famille'] = $imgdata['famille'];
1640 samuel 242
 
1681 samuel 243
            $obs[$idobs]['zone_geo'] = $imgdata['zone_geo'];
244
            $obs[$idobs]['latitude'] = floatval($imgdata['latitude']);
245
            $obs[$idobs]['longitude'] = floatval($imgdata['longitude']);
1640 samuel 246
 
247
 
1593 samuel 248
            if (!isset($obs[$idobs]['images'])) {
249
              $obs[$idobs]['images'] = array();
250
            }
251
 
1640 samuel 252
            $img_obj = array(
253
                             'id_image' => $img['id_image'],
1681 samuel 254
                             'nom_image' => $imgdata['nom_image'],
1652 samuel 255
                             'url' => sprintf('http://api.tela-botanica.org/img:%09dO.jpg', $img['id_image']),
1640 samuel 256
                             'votes' => array_map('intval', explode(',', $img['votes'])),
257
                             'tags' => explode(',', $img['tags']),
1681 samuel 258
                             'mots_cles_img_cel' => $this->formaterMotsClesCel($imgdata['mots_cles_texte_image'])
1640 samuel 259
                             );
260
            // push
261
            $obs[$idobs]['images'][] = $img_obj;
1593 samuel 262
 
263
          }
264
 
265
          return $obs;
266
 
267
	}
268
 
269
	/**
1640 samuel 270
         * Charger les votes pour chaque image
271
         **/
272
	private function chargerPropositionPlusProbable(&$obs) {
1593 samuel 273
 
1640 samuel 274
          $obsIds = array_keys($obs);
1593 samuel 275
 
1640 samuel 276
          $resultats = $this->bdd->recupererTous(sprintf(
1657 samuel 277
                  'SELECT ce_observation, id_commentaire, valeur, nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, del_commentaire_vote.ce_utilisateur '.
1640 samuel 278
                  'FROM del_commentaire_vote, del_commentaire '.
279
                  'WHERE ce_observation IN (%s) '.
280
                  'AND nom_sel IS NOT NULL '.
281
                  'AND del_commentaire.id_commentaire=del_commentaire_vote.ce_proposition '.
282
                  '', implode(',', $obsIds)));
1593 samuel 283
 
284
 
285
          $votes = array(); // map ce_proposition -> score
286
 
287
          // calcul des votes
288
          // un vote identifié a un facteur de 3
1640 samuel 289
          // additionne tous les vote par ce_proposition
290
          foreach($resultats as $vote) {
291
            if(!isset($votes[$vote['id_commentaire']])) {
292
              $votes[$vote['id_commentaire']] = 0;
1593 samuel 293
            }
294
            $valeur = ($vote['valeur'] == 1) ? 1 : -1;
1640 samuel 295
            $votes[$vote['id_commentaire']] += is_numeric($vote['ce_utilisateur']) ? 3 * $valeur : $valeur;
1593 samuel 296
          }
1640 samuel 297
 
298
          foreach($resultats as $vote) {
299
            $idobs = $vote['ce_observation'];
1593 samuel 300
 
1640 samuel 301
            if(!isset($obs[$idobs]['determinations'])) {
302
              $obs[$idobs]['determinations'] = array();
1593 samuel 303
            }
304
 
1640 samuel 305
            $obs[$idobs]['determinations'][$vote['id_commentaire']] =
306
              array('nom_sel' => $vote['nom_sel'],
1657 samuel 307
                    'nom_ret' => $vote['nom_ret'],
1640 samuel 308
                    'score' => $votes[$vote['id_commentaire']],
309
                    'nn' => $vote['nom_sel_nn']
310
                    );
1593 samuel 311
          }
312
 
313
 
1640 samuel 314
          return $obs;
1593 samuel 315
	}
316
 
1640 samuel 317
 
1593 samuel 318
	/*-------------------------------------------------------------------------------
319
								FORMATER ET METTRE EN FORME
320
	--------------------------------------------------------------------------------*/
321
	/**
322
	*  Formater les mots clés du cel en n'affichant que ceux faisant partie
323
	*  d'une liste définie dans le fichier de configuration
324
	*  @param $chaineMotCleCel la chaine de mots clés du cel
325
	*  @return string la chaine filtrée
326
	* */
327
	private function formaterMotsClesCel($chaineMotCleCel) {
1652 samuel 328
 
329
          $mots_cles_cel_affiches = "fleur,fleurs,feuille,feuilles,ecorce,fruit,fruits,port,plantnet,plantscan_new";
330
 
331
 
332
          $result = array_intersect(
333
                                 explode(',', $mots_cles_cel_affiches), // $tabMotsClesAffiches
334
                                 explode(',', $chaineMotCleCel)); // $tabMotsClesCel
335
 
1681 samuel 336
          if (count($result) === 0) {
337
            return array();
338
          }
339
          $ret = explode(',', implode(',', $result));
340
          return $ret;
1593 samuel 341
	}
342
 
343
}