Subversion Repositories eFlore/Applications.del

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
709 gduche 1
<?php
2
// declare(encoding='UTF-8');
3
/**
4
	* Le web service image récupère toutes les données de la table del_obs_images
5
 * pour retourner une liste d'images associée à une observation
6
 *
7
 * @category	php 5.2
8
 * @package	del
9
 * @subpackage images
10
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
11
 * @copyright	Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org)
12
 * @license	http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
13
 * @license	http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
14
 * @version	$Id: Bdd.php 403 2012-02-22 14:35:20Z gduche $
15
 * @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=ApiIdentiplante01Images
16
 */
17
 
751 delphine 18
class ListeImages {
709 gduche 19
 
20
	private $imageIds = array();
719 gduche 21
	private $conteneur;
725 gduche 22
	private $navigation;
23
	private $masque;
24
	private $gestionBdd;
25
	private $bdd;
759 delphine 26
	private $parametres = array();
27
	private $ressources = array();
800 aurelien 28
	private $tri = 'date_transmission';
29
	private $directionTri = 'desc';
709 gduche 30
 
719 gduche 31
	public function __construct(Conteneur $conteneur = null) {
32
		$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
791 aurelien 33
		$this->conteneur->chargerConfiguration('config_departements_bruts.ini');
798 aurelien 34
		$this->conteneur->chargerConfiguration('config_mapping_votes.ini');
775 aurelien 35
		$this->conteneur->chargerConfiguration('config_images.ini');
725 gduche 36
		$this->navigation = $conteneur->getNavigation();
37
		$this->masque = $conteneur->getMasque();
38
		$this->gestionBdd = $conteneur->getGestionBdd();
775 aurelien 39
		$this->bdd = $this->gestionBdd->getBdd();
719 gduche 40
	}
41
 
1312 gduche 42
 
1319 gduche 43
	/** Nettoyer les paramètres pour ne pas accepter les %
44
	 * */
45
	public function nettoyerParametres($parametres) {
46
		$parametresRetour = array();
47
		foreach ($parametres as $cle => $valeur) {
48
			$valSanPourcent = trim($valeur, "% ");
49
			if ($valSanPourcent != '') {
50
				$parametresRetour[$cle] = $valeur;
51
			}
52
		}
53
 
54
		return $parametresRetour;
55
	}
56
 
709 gduche 57
	/**
1312 gduche 58
	 * RequeteSansParametres
59
	 *
60
	 * permet de vérifier qu'il n'y a aucun paramètre dans la requete, excepté les informations de start et limite,
61
	 * pour ajuster la requête pour un gain de temps
62
	 * @param array $ressources les ressources telles qu'elles sont passées au script
63
	 * @param array $parametres les paramètres tels qu'il sont passés au script
64
	 * */
65
	public function requeteSansParametres($ressources, $parametres) {
1319 gduche 66
 
1312 gduche 67
		$estSansParametres = true;
68
 
69
		if (sizeof($ressources) > 0) {
70
			$estSansParametres = false;
71
		}
72
 
73
		if (sizeof($parametres) > 2) {
1319 gduche 74
 
1312 gduche 75
			// s'il y a plus de 2 paramètres, on est forcément dans le cas où on a demandé des paramètres autre que la navigation
76
			$estSansParametres = false;
77
		} else {
78
			if (sizeof($parametres) == 1) {
79
				if (!(isset($parametres['navigation.depart']) || isset($parametres['navigation.limite']))) {
80
					// s'il y a des paramètres, seul les paramètres de navigation n'interfère pas sur la requête
81
					$estSansParametres = false;
82
				}
83
			} elseif (sizeof($parametres) == 2) {
84
				// s'il y a des paramètres, seul les paramètres de navigation n'interfère pas sur la requête
85
				if (!(isset($parametres['navigation.depart']) && isset($parametres['navigation.limite']))) {
86
					$estSansParametres = false;
87
				}
88
			}
89
		}
90
 
91
		return $estSansParametres;
92
	}
93
 
94
	/**
709 gduche 95
	 * Méthode principale de la classe.
96
	 * Lance la récupération des images dans la base et les place dans un objet ResultatService
97
	 * pour l'afficher.
98
	 * @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
99
	 * @param array $parametres les paramètres situés après le ? dans l'url
100
	 * */
101
	public function consulter($ressources, $parametres) {
1312 gduche 102
 
759 delphine 103
		$this->initialiserRessourcesEtParametres($ressources, $parametres);
709 gduche 104
 
105
		// Gestion des configuration du script
106
		$this->configurer();
711 gduche 107
		$this->verifierConfiguration();
709 gduche 108
 
800 aurelien 109
		$this->verifierParametresTri();
110
		$this->initialiserTri();
111
 
1319 gduche 112
		$parametres = $this->nettoyerParametres($parametres);
1312 gduche 113
		if ($this->requeteSansParametres($ressources, $parametres)) {
114
 
115
			// Lancement du service
116
			$liaisons = $this->chargerLiaisonsSimple();
117
			$images = $this->chargerImage($liaisons);
118
			$images = $this->chargerVotes($images);
119
 
120
			// Mettre en forme le résultat et l'envoyer pour affichage
121
			$resultat = new ResultatService();
122
			$resultat->corps = array('entete' => $this->conteneur->getEntete(), 'resultats' => $images);
123
			return $resultat;
124
		} else {
125
 
126
			// Lancement du service
127
			$liaisons = $this->chargerLiaisons();
128
			$total = $this->compterImages();
129
			$this->navigation->setTotal($total);
130
			$images = $this->chargerImage($liaisons);
131
			$images = $this->chargerVotes($images);
132
 
133
			// Mettre en forme le résultat et l'envoyer pour affichage
134
			$resultat = new ResultatService();
135
			$resultat->corps = array('entete' => $this->conteneur->getEntete(), 'resultats' => $images);
136
			return $resultat;
137
 
138
		}
709 gduche 139
	}
140
 
759 delphine 141
	private function initialiserRessourcesEtParametres($ressources, $parametres) {
142
		$this->ressources = $ressources;
143
		$this->parametres = $parametres;
144
	}
800 aurelien 145
 
146
	private function verifierParametresTri() {
147
 
148
		$erreurs = array();
149
		$tris_possibles = $this->conteneur->getParametre('tris_possibles');
150
		$tris_possibles_tableau = explode(',', $tris_possibles);
151
		if(isset($this->parametres['tri']) && !in_array($this->parametres['tri'], $tris_possibles_tableau)) {
152
			$erreurs[] = '- le type de tri demandé est incorrect, les valeurs possibles sont '.$tris_possibles.' ;';
153
		}
154
 
951 aurelien 155
		if(isset($this->parametres['tri']) && $this->parametres['tri'] == "votes") {
156
			if(!isset($this->parametres['protocole']) || !is_numeric($this->parametres['protocole'])) {
157
				$erreurs[] = '- Le paramètre protocole est obligatoire en cas de tri par vote et doit être un entier ;';
158
			}
159
		}
160
 
800 aurelien 161
		$directions_tri = array('asc', 'desc');
162
		if(isset($this->parametres['ordre']) && !in_array($this->parametres['ordre'], $directions_tri)) {
163
			$erreurs[] = '- la direction du tri demandé est incorrecte, les valeurs supportées sont asc ou desc ;';
164
		}
165
 
166
		if (!empty($erreurs)) {
167
			$e = 'Erreur lors de l\'analyse des parametres du tri : '."\n";
168
			$e .= implode("\n", $erreurs);
169
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
170
		}
171
	}
172
 
173
	private function initialiserTri() {
174
		$this->tri = isset($this->parametres['tri']) ? $this->parametres['tri'] : $this->tri;
175
		$this->directionTri = isset($this->parametres['ordre']) ? $this->parametres['ordre'] : $this->directionTri;
176
	}
709 gduche 177
	/*-------------------------------------------------------------------------------
178
	 							CONFIGURATION DU SERVICE
179
	 --------------------------------------------------------------------------------*/
180
	/**
181
	 * Configuration du service en fonction du fichier de config config_del.ini
182
	 * */
183
	public function configurer() {
719 gduche 184
		$this->mappingFiltre = $this->conteneur->getParametre('mapping_masque');
185
		$this->mappingObservation = $this->conteneur->getParametre('mapping_observation');
759 delphine 186
		$this->mappingVotes = $this->conteneur->getParametre('mapping_votes');
709 gduche 187
	}
188
 
189
	/**
710 gduche 190
	 * Vérifier que le service est bien configuré
191
	 * */
192
	public function verifierConfiguration() {
728 gduche 193
 
710 gduche 194
		$erreurs = array();
728 gduche 195
		$tableauImages = $this->conteneur->getParametre('images');
196
		if (empty($tableauImages)) {
710 gduche 197
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [images] ou celui-ci est vide ;';
198
		} else {
728 gduche 199
			if ($this->conteneur->getParametre('url_service') == null) {
710 gduche 200
				$erreurs[] = '- paramètre "url_service" manquant ;';
201
			}
202
 
728 gduche 203
			if ($this->conteneur->getParametre('url_images') == null) {
710 gduche 204
				$erreurs[] = '- paramètre "url_images" manquant ;';
205
			}
206
 
207
		}
208
 
209
		if (empty($this->mappingObservation)) {
210
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [mapping_observation] ou celui-ci est vide ;';
211
		} else {
212
			$champsMappingObs = array('id_observation', 'date_observation', 'date_transmission', 'famille', 'nom_sel', 'nom_sel_nn', 'nt',
213
								'ce_zone_geo', 'lieudit', 'station', 'milieu', 'ce_utilisateur', 'nom', 'prenom');
214
			foreach ($champsMappingObs as $champ) {
215
				if (!isset($this->mappingObservation[$champ])) {
216
					$erreurs[] = '- le mapping du champ "'.$champ.'" pour l\'observation est manquant ;';
217
				}
218
			}
219
		}
220
 
221
		if (empty($this->mappingFiltre)) {
222
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [mapping_masque] ou celui-ci est vide ;';
223
		} else {
224
			$champsMappingFiltre = array('famille', 'ns', 'nn', 'date', 'tag', 'commune');
225
			foreach ($champsMappingFiltre as $champ) {
226
				if (!isset($this->mappingFiltre[$champ])) {
227
					$erreurs[] = '- le mapping du champ "'.$champ.'" pour l\'observation est manquant ;';
228
				}
229
			}
230
		}
231
 
800 aurelien 232
		$tris_possibles = $this->conteneur->getParametre('tris_possibles');
233
		if (empty($tris_possibles)) {
234
			$erreurs[] = '- le fichier de configuration ne contient pas le parametre tris_possibles ou celui-ci est vide ;';
235
		}
236
 
710 gduche 237
		if (!empty($erreurs)) {
238
			$e = 'Erreur lors de la configuration : '."\n";
239
			$e .= implode("\n", $erreurs);
711 gduche 240
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
728 gduche 241
		}
710 gduche 242
	}
243
 
709 gduche 244
 
245
 
246
	/**
247
	 * Obtenir une chaine de caractère concaténant nom et prénom séparé par une virgule
248
	 * @param String $auteurId l'identifiant de l'auteur
249
	 * @return String la chaine de concaténation
250
	 * */
251
	private function getChaineNomPrenom($auteurId) {
252
		$nomPrenom = explode(' ', $auteurId);
719 gduche 253
		$nomPrenom = $this->proteger($nomPrenom);
709 gduche 254
		$chaineNomPrenom = implode(', ', $nomPrenom);
255
		return $chaineNomPrenom;
256
	}
257
 
258
	/**
259
	* Charger la clause WHERE en fonction des paramètres de masque
260
	* */
261
	private function chargerClauseWhere() {
1319 gduche 262
 
709 gduche 263
		$where = array();
725 gduche 264
		$tableauMasque = $this->masque->getMasque();
265
		if (!empty($tableauMasque)) {
266
			foreach($tableauMasque as $idMasque => $valeurMasque) {
791 aurelien 267
				//TODO: scinder ceci en fonctions réutilisables ?
268
				// voir si c'est interessant par rapport à la recherche générale
725 gduche 269
				$idMasque = str_replace('masque.', '', $idMasque);
270
				switch ($idMasque) {
271
					// nom du masque => nom BDD
272
					case 'auteur' :
791 aurelien 273
						$whereAuteur = ' '.$this->creerFiltreAuteur($this->masque->getMasque('auteur'));
274
						if($whereAuteur != '') {
275
							$where[] = $whereAuteur;
725 gduche 276
						}
277
						break;
791 aurelien 278
					case 'date' :
279
						$whereDate = ' '.$this->creerFiltreDate($valeurMasque);
280
						if($whereDate != '') {
281
							$where[] = $whereDate;
709 gduche 282
						}
725 gduche 283
						break;
791 aurelien 284
					case 'departement' :
285
						$where[] = ' '.$this->creerFiltreIdZoneGeo($valeurMasque);
286
						break;
725 gduche 287
					case 'genre' :
719 gduche 288
						$where[] = ' '.$this->mappingFiltre['ns'].' LIKE '.$this->proteger($valeurMasque.' %');
725 gduche 289
						break;
290
					case 'tag' :
791 aurelien 291
						$where[] = ' '.$this->creerFiltreMotsCles($valeurMasque);
725 gduche 292
						break;
775 aurelien 293
					case 'ns' :
791 aurelien 294
						$where[] = ' nom_sel LIKE '.$this->proteger($valeurMasque.'%');
295
						break;
296
					case 'commune' :
297
						$where[] = ' '.$this->mappingFiltre[$idMasque].' LIKE '.$this->proteger(str_replace(array('-',' '), '_', $valeurMasque).'%');
298
					break;
299
					case 'masque' :
300
						$where[] = ' '.$this->creerFiltreMasqueGeneral($valeurMasque);
775 aurelien 301
						break;
725 gduche 302
					default:
303
						$where[] = ' '.$this->mappingFiltre[$idMasque].' = '.$this->proteger($valeurMasque);
304
					break;
305
				}
306
			}
709 gduche 307
		}
308
 
309
		if (!empty($where)) {
310
			return ' WHERE '.implode('AND', $where);
311
		} else {
312
			return;
313
		}
314
	}
315
 
791 aurelien 316
	private function creerFiltreMasqueGeneral($valeurMasque) {
317
		//TODO: affecter d'aborder les variables, puis les tester pour les
318
		// ajouter à la chaine
319
		$whereAuteur = $this->creerFiltreAuteur($valeurMasque);
320
		$whereIdZoneGeo = $this->creerFiltreIdZoneGeo($valeurMasque);
321
 
322
		$masqueGeneral = '( '.
323
                   	(($whereAuteur != '') ? $whereAuteur.' OR ' : '' ).
324
				   	(($whereIdZoneGeo != '') ? $whereIdZoneGeo.' OR ' : '' ).
325
					'zone_geo LIKE '.$this->proteger($this->remplacerParJokerCaractere($valeurMasque).'%').' OR '.
326
					$this->creerFiltreMotsCles($valeurMasque).' OR '.
327
					'nom_sel LIKE '.$this->proteger($valeurMasque.'%').' OR '.
328
					'famille LIKE '.$this->proteger($valeurMasque.'%').' OR '.
329
					'milieu LIKE '.$this->proteger($valeurMasque).' OR '.
330
					$this->mappingFiltre['ns'].' LIKE '.$this->proteger('%'.$valeurMasque.'% %').' OR '.
331
					$this->creerFiltreDate($valeurMasque).
332
					') ';
333
 
334
		return $masqueGeneral;
335
	}
336
 
337
	private function creerFiltreAuteur($valeurMasque) {
338
		$masque = '';
339
		$auteurId = $valeurMasque;
340
		if (is_numeric($auteurId)) {
341
			$masque = ' ce_utilisateur = '.$auteurId;
342
		} else {
343
			if (strpos($auteurId, '@') === false) {
344
				$tableauNomPrenom = explode(' ',$auteurId, 2);
345
				if(count($tableauNomPrenom) == 2) {
346
					// on teste potentiellement un nom prenom ou bien un prénom nom
347
					$masque = '('.
348
						          	'(nom LIKE '.$this->proteger($tableauNomPrenom[0].'%').' AND '.
349
								  	'prenom LIKE '.$this->proteger($tableauNomPrenom[1].'%').') OR '.
350
								 	'(nom LIKE '.$this->proteger($tableauNomPrenom[1].'%').' AND '.
1274 aurelien 351
								  	'prenom LIKE '.$this->proteger($tableauNomPrenom[0].'%').') OR '.
352
									'(dob.nom_utilisateur LIKE '.$this->proteger($tableauNomPrenom[0].'%').' AND '.
353
									'dob.prenom_utilisateur LIKE '.$this->proteger($tableauNomPrenom[1].'%').') OR '.
354
									'(dob.nom_utilisateur LIKE '.$this->proteger($tableauNomPrenom[1].'%').' AND '.
1319 gduche 355
									'dob.prenom_utilisateur LIKE '.$this->proteger($tableauNomPrenom[0].'%').') OR '.
356
									'(nom LIKE '.$this->proteger($valeurMasque.'%').') OR '.
357
									'(prenom LIKE '.$this->proteger($valeurMasque.'%').') OR '.
358
									'(dob.nom_utilisateur LIKE '.$this->proteger($valeurMasque.'%').') OR '.
359
									'(dob.prenom_utilisateur LIKE '.$this->proteger($valeurMasque.'%').') '.
791 aurelien 360
								  ')';
361
				} else {
362
					$masque = '(
363
						            (nom LIKE '.$this->proteger($auteurId.'%').' OR '.
1274 aurelien 364
									'prenom LIKE '.$this->proteger($auteurId.'%').' OR '.
365
									'dob.nom_utilisateur LIKE '.$this->proteger($auteurId.'%').' OR '.
366
									'dob.prenom_utilisateur LIKE '.$this->proteger($auteurId.'%').')'.
791 aurelien 367
								  ')';
368
				}
369
			} else {
1274 aurelien 370
				$masque = " courriel LIKE ".$this->proteger($valeurMasque.'%').
371
				          " OR dob.courriel_utilisateur LIKE ".$this->proteger($valeurMasque.'%')." ";
791 aurelien 372
			}
373
		}
374
		return $masque;
375
	}
376
 
377
	private function remplacerParJokerCaractere($valeurMasque) {
378
		return str_replace(array('-',' '), '_', $valeurMasque);
379
	}
380
	//TODO: déplacer les fonctions ci dessus et dessous dans une classe
381
	// utilitaire
382
	function supprimerAccents($str, $charset='utf-8')
383
	{
384
		$str = htmlentities($str, ENT_NOQUOTES, $charset);
385
 
386
		$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
387
		$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. '&oelig;'
388
		$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères
389
 
390
		return $str;
391
	}
392
 
1180 aurelien 393
	private function normaliserMotCle($mot_cle) {
394
		return mb_strtolower($this->supprimerAccents(trim($mot_cle)));
395
	}
396
 
791 aurelien 397
	private function obtenirIdDepartement($nomDpt) {
398
 
399
		$nomDpt = $this->supprimerAccents($nomDpt);
400
		$nomDpt = strtolower(str_replace(' ','-',$nomDpt));
401
 
402
		$idDpt = $this->conteneur->getParametre($nomDpt);
403
		if($idDpt == null || $idDpt == ' ') {
404
			$idDpt = ' ';
405
		}
406
		return $idDpt;
407
	}
408
 
409
	private function creerFiltreIdZoneGeo($valeurMasque) {
410
		$masque = '';
411
		$dept = $valeurMasque;
412
		if (is_numeric($dept)) {
413
			$dept = sprintf('%02s', $dept);
414
			$dept = sprintf("%-'_5s", $dept);
415
			$masque = " ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$dept);
416
		} else {
417
			$deptId = $this->conteneur->getParametre($dept);
418
			if ($deptId != null) {
419
				$masque = " ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$deptId.'%');
420
			} else {
421
				$id = $this->obtenirIdDepartement($valeurMasque);
422
				$masque = " ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$id.'%');
423
			}
424
		}
425
		return $masque;
426
	}
427
 
428
	private function creerFiltreDate($valeurMasque) {
429
		//TODO: définir dans le fichier de config un tableau contenant plusieurs format de date
430
		// autorisés pour la recherche, qui seraient ajoutés au OR
431
		$masque = '(';
432
		$masque .= (is_numeric($valeurMasque)) ? ' YEAR(date_observation) = '.$this->proteger($valeurMasque).' OR ' : '';
433
		$masque .= " DATE_FORMAT(date_observation, '%d/%m/%Y') = ".$this->proteger($valeurMasque).' '.
434
		           ')';
435
		return $masque;
436
	}
801 aurelien 437
 
791 aurelien 438
	private function creerFiltreMotsCles($valeurMasque) {
800 aurelien 439
 
440
		$mots_cles = explode(' ', $valeurMasque);
812 gduche 441
		$requeteMotsClesImg = array();
442
		$requeteMotsClesObs = array();
1180 aurelien 443
		$requeteMotsClesImgPublic = array();
801 aurelien 444
 
800 aurelien 445
		foreach($mots_cles as $mot_cle) {
1180 aurelien 446
			//TODO: rechercher sur les mots clés normalisés dans tous les cas ?
857 gduche 447
			$requeteMotsCles = $this->proteger('%'.$mot_cle.'%');
1180 aurelien 448
			$motsCleProtege = $this->proteger($this->normaliserMotCle('%'.$mot_cle.'%'));
449
			$requeteMotsClesImgPublic[] = 'di.id_image IN (SELECT ce_image FROM del_image_tag WHERE tag_normalise LIKE '.$motsCleProtege.' AND actif = 1)';
857 gduche 450
			$requeteMotsClesImg[] = 'di.mots_cles_texte LIKE '.$requeteMotsCles;
451
			$requeteMotsClesObs[] = 'dob.mots_cles_texte LIKE '.$requeteMotsCles;
800 aurelien 452
		}
1180 aurelien 453
 
454
		$requeteMotsClesImgPublic = implode(' AND ', $requeteMotsClesImgPublic);
857 gduche 455
		$requeteMotsClesImg = implode(' AND ', $requeteMotsClesImg);
456
		$requeteMotsClesObs = implode(' AND ', $requeteMotsClesObs);
800 aurelien 457
 
458
		$masque = '('.
1180 aurelien 459
					'('.$requeteMotsClesImgPublic.') OR '.
811 aurelien 460
		          	'('.$requeteMotsClesImg.') OR '.
461
		          	'('.$requeteMotsClesObs.') '.
462
		          ')';
800 aurelien 463
 
791 aurelien 464
		return $masque;
465
	}
466
 
709 gduche 467
	/*-------------------------------------------------------------------------------
468
								CHARGEMENT DES IMAGES
469
	--------------------------------------------------------------------------------*/
470
	/**
471
	* Chargement depuis la bdd de toutes les liaisons entre images et observations
472
	* */
473
	private function chargerLiaisons() {
474
 
1319 gduche 475
		// 1. Récupérer les id observation
476
		$requeteObs = ' SELECT id_observation FROM del_observation dob LEFT JOIN del_utilisateur du ON dob.ce_utilisateur = du.id_utilisateur ';
477
 
478
		$masques = $this->masque->getMasque();
479
		$conditionsObs = array();
480
 
481
		if (isset($masques['masque'])) {
482
			$conditionLibre = array();
483
			$passe = $masques['masque'];
484
 
485
			if (!isset($masques['masque.ns'])) {
486
				$conditionsLibre[] = "nom_sel LIKE '$passe%'";
487
			}
488
 
489
			if (!isset($masques['masque.famille'])) {
490
				$conditionsLibre[] = "famille LIKE '$passe%'";
491
			}
492
 
493
			if (!isset($masques['masque.milieu'])) {
494
				$conditionsLibre[] = "nom_sel LIKE '$passe%'";
495
			}
496
 
497
			if (!isset($masques['masque.tag'])) {
498
				$conditionsLibre[] = "mots_cles_texte LIKE '%$passe%'";
499
				//TODO : voir pour images
500
			}
501
 
502
			if (!isset($masques['masque.date'])) {
503
				$conditionsLibre[] = $this->creerFiltreDate($passe);
504
			}
505
 
506
			if (!isset($masques['masque.auteur'])) {
507
				$conditionsLibre[] = $this->creerFiltreAuteur($passe);
508
			}
509
 
510
			$conditionsObs[] = implode(' OR ', $conditionsLibre);
511
		}
512
 
513
		// nom sel
514
		if (isset($masques['masque.ns'])) {
515
			$nom_sel = $masques['masque.ns'];
516
			$conditionsObs[] = "nom_sel LIKE '$nom_sel%'";
517
		}
518
 
519
		// famille
520
		if (isset($masques['masque.famille'])) {
521
			$famille = $masques['masque.famille'];
522
			$conditionsObs[] = "famille LIKE '$famille%'";
523
		}
524
 
525
		// genre
526
		if (isset($masques['masque.genre'])) {
527
			$genre = $masques['masque.genre'];
528
			$conditionsObs[] = "nom_sel LIKE '$genre%'";
529
		}
530
 
531
		// milieu
532
		if (isset($masques['masque.milieu'])) {
533
			$milieu = $masques['masque.milieu'];
534
			$conditionsObs[] = "nom_sel LIKE '$milieu%'";
535
		}
536
 
537
		// mots_cles_texte
538
		if (isset($masques['masque.tag'])) {
539
			$motscles = $masques['masque.tag'];
540
			$conditionsObs[] = "mots_cles_texte LIKE '%$motscles%'";
541
		}
542
 
543
		// date
544
		if (isset($masques['masque.date'])) {
545
			$date = $masques['masque.date'];
546
			$conditionsObs[] = $this->creerFiltreDate($date);
547
		}
548
 
549
		// utilisateur
550
		if (isset($masques['masque.auteur'])) {
551
			$auteur = $masques['masque.auteur'];
552
			$conditionsObs[] = $this->creerFiltreAuteur($auteur);
553
		}
554
 
555
		// commune
556
		if (isset($masques['masque.commune'])) {
557
			$commune = $masques['masque.commune'];
558
			$conditionsObs[] = " zone_geo LIKE ".$this->proteger(str_replace(array('-',' '), '_', $commune).'%');
559
		}
560
 
561
		// commune
562
		if (isset($masques['masque.departement'])) {
563
			$dept = $masques['masque.departement'];
564
			$conditionsObs[] = $this->creerFiltreIdZoneGeo($dept);
565
		}
566
 
567
		if (!empty($conditionsObs)) {
568
			$where = ' WHERE '.implode(' AND ', $conditionsObs);
569
			$requeteObs .= $where;
570
		}
571
 
572
		$observations = $this->bdd->recupererTous($requeteObs);
573
 
574
		$tabIdsObs = array();
575
		foreach ($observations as $observation) {
576
			$tabIdsObs[] = $observation['id_observation'];
577
		}
578
		$idsObs = implode(',', $tabIdsObs);
579
		if ($idsObs == '') {
580
			$idsObs = "''";
581
		}
582
		//var_dump($requeteObs);
583
		// 2. Récupérer les id images
584
 
585
		$conditionsImg = array();
586
		if (isset($masques['masque.tag'])) {
587
			$tag = $masques['masque.tag'];
588
			$conditionsImg[] = " dit.tag_normalise LIKE '$tag%' ";
589
			$conditionsImg[] = " di.mots_cles_texte LIKE '%$tag%' ";
590
		}
591
 
592
		$idsImages = '';
593
		if (!empty($conditionsImg)) {
594
			$requeteImages = ' SELECT doi.id_image FROM del_obs_image doi '.
595
					' INNER JOIN del_image di ON doi.id_image = di.id_image '.
596
					' INNER JOIN del_image_tag dit ON dit.ce_image = di.id_image ';
597
 
598
			$where = ' WHERE '.implode(' OR ', $conditionsImg);
599
			$requeteImages .= $where;
600
 
601
			$images = $this->bdd->recupererTous($requeteImages);
602
 
603
			$tabIdsImages = array();
604
			foreach ($images as $image) {
605
				$tabIdsImages[] = $image['id_image'];
606
			}
607
			$idsImages = implode(',', $tabIdsImages);
608
 
609
			if ($idsImages == '') {
610
				$idsImages = "''";
611
			}
612
		}
613
		//var_dump($requeteImages);exit();
614
		// 3. Récupérer la combinaison des deux
615
		$requeteLiaisons = 'SELECT DISTINCT SQL_CALC_FOUND_ROWS dob.id_observation as id_observation, nom_sel, nom_sel_nn, nt, famille, ce_zone_geo, zone_geo, lieudit, station, milieu, '.
616
		' date_observation, dob.mots_cles_texte as mots_cles_texte, dob.commentaire as commentaire, di.mots_cles_texte as mots_cles_texte_image , date_transmission, '.
617
		' di.id_image as id_image, di.ce_utilisateur as ce_utilisateur, prenom, nom, courriel, dob.prenom_utilisateur, dob.nom_utilisateur, dob.courriel_utilisateur, nom_original '.
618
		' FROM del_obs_image DOI '.
619
		' INNER JOIN del_image di ON doi.id_image = di.id_image '.
620
		' INNER JOIN del_observation dob ON doi.id_observation = dob.id_observation '.
621
		' LEFT JOIN del_utilisateur du ON du.id_utilisateur = di.ce_utilisateur ';
622
 
623
 
624
		$where = array();
625
		if (!empty($conditionsObs) && strlen($idsObs) > 0) {
626
			$where[] = 'dob.id_observation IN ( '.$idsObs.') ';
627
		}
628
 
629
		if (!empty($conditionsImg) && strlen($idsImages) > 0) {
630
			$chaineWhere = 'di.id_image IN ( '.$idsImages.') ';
631
			// Si on ne cherche pas que le tag, on doit récupérer uniquement les
632
			// images qui matche avec la recherche d'observation
633
			if (isset($masques['masque.tag']) && sizeof($masques) > 1) {
634
				$chaineWhere .= ' AND doi.id_observation IN ('.$idsObs.') ';
635
			}
636
			$where[] = $chaineWhere;
637
		}
638
 
639
		if (!empty($where)) {
640
			$requeteLiaisons .= ' WHERE '.implode(' OR ', $where);
641
		}
642
 
643
		// limite de la chaine idobs = 1047389
644
		/*if (strlen($requeteLiaisons) > 1047389) {
645
			exit('requete trop longue');
646
			//return array();
647
		}*/
648
 
725 gduche 649
		$requeteLiaisons .= $this->gestionBdd->getLimitSql();
1319 gduche 650
 
651
		// on ne lance la requete que si on a trouvé des images ou des observations, sinon
652
		// cela signifie qu'il n'y a aucune correspondance dans la base
653
		$retour = array();
654
		if (strlen($idsObs) > 0 || strlen($idsImages) > 0) {
655
			$retour = $this->bdd->recupererTous($requeteLiaisons);
656
		}
657
 
658
		return $retour;
709 gduche 659
	}
660
 
1312 gduche 661
 
662
	/**
663
	 * Chargement depuis la bdd de toutes les liaisons entre images et observations
664
	 * */
665
	private function chargerLiaisonsSimple() {
666
 
667
		// Charger les obs images / images
668
		// récupérer les ids
669
		// récupérer les observations
670
 
1319 gduche 671
		$requeteImages = 'SELECT *, di.mots_cles_texte as mots_cles_texte_image FROM del_obs_image doi '.
1312 gduche 672
						'INNER JOIN del_image di ON doi.id_image = di.id_image '.
673
						'ORDER BY id_observation DESC'.
674
						$this->gestionBdd->getLimitSql();
675
		$liaisons = $this->bdd->recupererTous($requeteImages);
1313 gduche 676
 
1312 gduche 677
 
1313 gduche 678
		$nbImages = 'SELECT count(id_image) as nb FROM del_obs_image';
679
		$requeteNbImages = $this->bdd->recupererTous($nbImages);
680
 
681
		$total = (int) $requeteNbImages[0]['nb'];
1312 gduche 682
		$this->navigation->setTotal($total);
683
 
684
		$idsObservations = array();
685
		foreach ($liaisons as $image) {
686
			$idObs = $image['id_observation'];
687
			$idsObservations[$idObs] = $idObs;
688
		}
689
 
690
		$requeteObservations = 'SELECT * FROM del_observation dob '.
691
							'LEFT JOIN del_utilisateur du ON dob.ce_utilisateur = du.id_utilisateur '.
692
							'WHERE id_observation IN ('.implode(',', $idsObservations).')';
693
		$resultatsObservations = $this->bdd->recupererTous($requeteObservations);
694
 
695
		$observations = array();
696
		foreach ($resultatsObservations as $id => $observation) {
697
			$idObs = $observation['id_observation'];
698
			$observations[$idObs] = $observation;
699
		}
700
 
701
		foreach ($liaisons as $id => $liaison) {
702
			$idObs = $liaison['id_observation'];
703
 
704
			$observation = $observations[$idObs];
705
			foreach ($observation as $cle => $valeur) {
706
				$liaisons[$id][$cle] = $valeur;
707
			}
708
		}
709
 
710
		return $liaisons;
711
	}
712
 
713
 
1168 aurelien 714
	private function assemblercomptageOccurencesMotsClesCel() {
715
		$chaineMotsClesAffiches = $this->conteneur->getParametre('mots_cles_cel_affiches');
716
		$tabMotsClesAffiches = explode(',',$chaineMotsClesAffiches);
717
		$chaineSql = '';
718
 
719
		// Comptage du nombre de mots clés officiels présents dans la chaine mots clés texte
720
		foreach ($tabMotsClesAffiches as $motCle) {
721
			if($chaineSql != '') {
722
				$chaineSql .= ' + ';
723
			}
724
			$chaineSql .= 'IF(FIND_IN_SET('.$this->proteger($motCle).',di.mots_cles_texte) != 0, 1, 0)';
725
		}
726
 
727
		return '('.$chaineSql.')';
728
	}
729
 
951 aurelien 730
	private function doitJoindreTableVotes() {
731
		return ($this->tri == 'votes');
732
	}
733
 
1168 aurelien 734
	private function doitJoindreTableTags() {
735
		return ($this->tri == 'tags');
736
	}
737
 
800 aurelien 738
	private function getTri() {
739
		$order = '';
951 aurelien 740
		if($this->doitJoindreTableVotes()) {
741
			$order = ' GROUP BY dvote.ce_image, dob.id_observation ORDER BY total_votes '.$this->directionTri.', date_transmission desc ';
1168 aurelien 742
		} else if($this->doitJoindreTableTags()) {
743
			$order = ' GROUP BY doi.id_image ORDER BY total_tags '.$this->directionTri.', date_transmission desc ';
951 aurelien 744
		} else {
800 aurelien 745
			$order = ' ORDER BY '.$this->tri.' '.$this->directionTri.' ';
746
		}
747
		return $order;
748
	}
749
 
709 gduche 750
	/**
751
	* Compter le nombre total d'images dans la base pour affichage dans entete.
752
	* */
753
	private function compterImages() {
754
		$requete = 'SELECT FOUND_ROWS() AS nbre ';
719 gduche 755
		$resultats = $this->bdd->recuperer($requete);
709 gduche 756
		return (int) $resultats['nbre'];
757
	}
758
 
759
	/**
760
	* Retourner un tableau d'images formaté en fonction des liaisons trouvées
761
	* @param $liaisons les liaisons de la table del_obs_images
762
	* */
763
	private function chargerImage($liaisons) {
764
 
765
		$images = array();
766
		foreach ($liaisons as $liaison) {
736 gduche 767
			$idImage = $liaison['id_image'];
709 gduche 768
 
1274 aurelien 769
			if($liaison['ce_utilisateur'] == 0) {
770
				$liaison['prenom'] = $liaison['prenom_utilisateur'];
771
				$liaison['nom'] = $liaison['nom_utilisateur'];
772
			}
709 gduche 773
			// On enregistre l'ID de l'image pour n'effectuer qu'une seule requête par la suite
774
			$this->imageIds[] = $idImage;
800 aurelien 775
			$index = $liaison['id_image'].'-'.$liaison['id_observation'];
1025 aurelien 776
			$images[$index] = array('id_image' => $idImage, 'binaire.href' => $this->formaterLienImage($idImage),
777
						'protocoles_votes' => array(),
1017 aurelien 778
						'mots_cles_texte' => $liaison['mots_cles_texte_image'], 'observation' => $this->formaterObservation($liaison));
709 gduche 779
		}
780
		return $images;
781
	}
782
 
783
	/**
784
	* Charger les votes pour chaque image
785
	* */
786
	private function chargerVotes($images) {
760 delphine 787
			$requeteVotes = 'SELECT v.*, p.* FROM '.
788
								$this->gestionBdd->formaterTable('del_image_vote', 'v').
789
								' INNER JOIN del_image_protocole p '.
790
									'ON v.ce_protocole = p.id_protocole '.
775 aurelien 791
									$this->chargerClauseWhereVotes();
719 gduche 792
			$resultatsVotes = $this->bdd->recupererTous($requeteVotes);
709 gduche 793
 
857 gduche 794
 
795
			//TODO : faire une méthode formater vote
709 gduche 796
			$votes = $this->formaterVotes($resultatsVotes);
797
 
798
			foreach ($images as $id => $image) {
799
				if (isset($votes[$image['id_image']])) {
779 aurelien 800
					$images[$id]['protocoles_votes'] = $votes[$image['id_image']];
709 gduche 801
				}
802
			}
803
 
804
		return $images;
805
	}
806
 
759 delphine 807
	private function chargerClauseWhereVotes() {
808
		if (sizeof($this->imageIds) > 0) {
809
			$chaineImageIds = implode(',', $this->imageIds);
760 delphine 810
			$where[] = 'v.ce_image  IN ('.$chaineImageIds.')';
759 delphine 811
		}
812
		if (isset($this->parametres['protocole'])) {
760 delphine 813
			$where[] = 'v.ce_protocole = '.$this->proteger($this->parametres['protocole']);
759 delphine 814
		}
775 aurelien 815
 
816
		$where = (!empty($where)) ? 'WHERE '.implode(' AND ', $where) : '';
817
		return $where;
759 delphine 818
	}
819
 
709 gduche 820
	/*-------------------------------------------------------------------------------
821
								FORMATER ET METTRE EN FORME
822
	--------------------------------------------------------------------------------*/
823
 
824
	/**
825
	*  Formater une observation depuis une ligne liaison
826
	*  @param $liaison liaison issue de la recherche
827
	*  @return $observation l'observation mise en forme
828
	* */
829
	private function formaterObservation($liaison) {
830
		$observation = array();
831
		foreach ($this->mappingObservation as $nomOriginal => $nomFinal) {
832
			$observation[$nomFinal] = $liaison[$nomOriginal];
833
		}
834
 
835
		return $observation;
836
	}
837
 
838
	/**
839
	*  Formater une observation depuis une ligne liaison
840
	*  @param $liaison liaison issue de la recherche
841
	*  @return $observation l'observation mise en forme
842
	* */
843
	private function formaterVotes($votes) {
844
		$retour = array();
845
		foreach ($votes as $vote) {
759 delphine 846
			$retour_vote = array();
847
			foreach ($vote as $param=>$valeur) {
760 delphine 848
				if (strpos($this->mappingVotes[$param], 'protocole.') === 0) {
849
					$retour_protocole[$this->mappingVotes[$param]] = $valeur;
850
				} else {
851
					$retour_vote[$this->mappingVotes[$param]] = $valeur;
852
				}
759 delphine 853
			}
760 delphine 854
			if (!isset($retour[$vote['ce_image']][$vote['ce_protocole']])) {
855
				$retour[$vote['ce_image']][$vote['ce_protocole']] = $retour_protocole;
856
			}
857
			$retour[$vote['ce_image']][$vote['ce_protocole']]['votes'][$vote['id_vote']] = $retour_vote;
709 gduche 858
		}
859
 
860
		return $retour;
861
	}
862
 
863
	/**
864
	 * Formater le lien de l'image en fonction du fichier de config et de l'identifiant de l'image
865
	 * */
866
	private function formaterLienImage($idImage) {
867
		$idImage = sprintf('%09s', $idImage);
719 gduche 868
		$url = $this->conteneur->getParametre('url_images');
709 gduche 869
		$urlImage = str_replace('%s', $idImage, $url);
870
		return $urlImage;
871
	}
719 gduche 872
 
873
	private function proteger($valeur) {
874
		if (is_array($valeur)) {
875
			return $this->bdd->protegerTableau($valeur);
876
		} else {
877
			return $this->bdd->proteger($valeur);
709 gduche 878
		}
879
	}
880
}
881
?>