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
			}
500
 
501
			if (!isset($masques['masque.date'])) {
502
				$conditionsLibre[] = $this->creerFiltreDate($passe);
503
			}
504
 
505
			if (!isset($masques['masque.auteur'])) {
506
				$conditionsLibre[] = $this->creerFiltreAuteur($passe);
507
			}
508
 
509
			$conditionsObs[] = implode(' OR ', $conditionsLibre);
510
		}
511
 
512
		// nom sel
513
		if (isset($masques['masque.ns'])) {
514
			$nom_sel = $masques['masque.ns'];
515
			$conditionsObs[] = "nom_sel LIKE '$nom_sel%'";
516
		}
517
 
518
		// famille
519
		if (isset($masques['masque.famille'])) {
520
			$famille = $masques['masque.famille'];
521
			$conditionsObs[] = "famille LIKE '$famille%'";
522
		}
523
 
524
		// genre
525
		if (isset($masques['masque.genre'])) {
526
			$genre = $masques['masque.genre'];
527
			$conditionsObs[] = "nom_sel LIKE '$genre%'";
528
		}
529
 
530
		// milieu
531
		if (isset($masques['masque.milieu'])) {
532
			$milieu = $masques['masque.milieu'];
533
			$conditionsObs[] = "nom_sel LIKE '$milieu%'";
534
		}
535
 
536
		// mots_cles_texte
1320 gduche 537
		/*if (isset($masques['masque.tag'])) {
1319 gduche 538
			$motscles = $masques['masque.tag'];
539
			$conditionsObs[] = "mots_cles_texte LIKE '%$motscles%'";
1320 gduche 540
		}*/
1319 gduche 541
 
542
		// date
543
		if (isset($masques['masque.date'])) {
544
			$date = $masques['masque.date'];
545
			$conditionsObs[] = $this->creerFiltreDate($date);
546
		}
547
 
548
		// utilisateur
549
		if (isset($masques['masque.auteur'])) {
550
			$auteur = $masques['masque.auteur'];
551
			$conditionsObs[] = $this->creerFiltreAuteur($auteur);
552
		}
553
 
554
		// commune
555
		if (isset($masques['masque.commune'])) {
556
			$commune = $masques['masque.commune'];
557
			$conditionsObs[] = " zone_geo LIKE ".$this->proteger(str_replace(array('-',' '), '_', $commune).'%');
558
		}
559
 
560
		// commune
561
		if (isset($masques['masque.departement'])) {
562
			$dept = $masques['masque.departement'];
563
			$conditionsObs[] = $this->creerFiltreIdZoneGeo($dept);
564
		}
565
 
566
		if (!empty($conditionsObs)) {
567
			$where = ' WHERE '.implode(' AND ', $conditionsObs);
568
			$requeteObs .= $where;
569
		}
570
 
571
		$observations = $this->bdd->recupererTous($requeteObs);
572
 
573
		$tabIdsObs = array();
574
		foreach ($observations as $observation) {
575
			$tabIdsObs[] = $observation['id_observation'];
576
		}
577
		$idsObs = implode(',', $tabIdsObs);
578
		if ($idsObs == '') {
579
			$idsObs = "''";
580
		}
581
		//var_dump($requeteObs);
582
		// 2. Récupérer les id images
583
 
584
		$conditionsImg = array();
585
		if (isset($masques['masque.tag'])) {
586
			$tag = $masques['masque.tag'];
587
			$conditionsImg[] = " dit.tag_normalise LIKE '$tag%' ";
588
			$conditionsImg[] = " di.mots_cles_texte LIKE '%$tag%' ";
589
		}
590
 
591
		$idsImages = '';
592
		if (!empty($conditionsImg)) {
593
			$requeteImages = ' SELECT doi.id_image FROM del_obs_image doi '.
594
					' INNER JOIN del_image di ON doi.id_image = di.id_image '.
595
					' INNER JOIN del_image_tag dit ON dit.ce_image = di.id_image ';
596
 
597
			$where = ' WHERE '.implode(' OR ', $conditionsImg);
598
			$requeteImages .= $where;
599
 
600
			$images = $this->bdd->recupererTous($requeteImages);
601
 
602
			$tabIdsImages = array();
603
			foreach ($images as $image) {
604
				$tabIdsImages[] = $image['id_image'];
605
			}
606
			$idsImages = implode(',', $tabIdsImages);
607
 
608
			if ($idsImages == '') {
609
				$idsImages = "''";
610
			}
611
		}
612
		//var_dump($requeteImages);exit();
613
		// 3. Récupérer la combinaison des deux
614
		$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, '.
615
		' 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, '.
616
		' 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 '.
1320 gduche 617
		' FROM del_obs_image doi '.
1319 gduche 618
		' INNER JOIN del_image di ON doi.id_image = di.id_image '.
619
		' INNER JOIN del_observation dob ON doi.id_observation = dob.id_observation '.
620
		' LEFT JOIN del_utilisateur du ON du.id_utilisateur = di.ce_utilisateur ';
621
 
622
 
1320 gduche 623
		$chaineWhere = '';
624
		if (isset($masques['masque.tag']) && sizeof($masques) == 1) {
625
			$connecteur = ' OR ';
626
		} else {
627
			$connecteur = ' AND ';
628
		}
629
 
1319 gduche 630
		$where = array();
631
		if (!empty($conditionsObs) && strlen($idsObs) > 0) {
1320 gduche 632
			$where[] = ' dob.id_observation IN ( '.$idsObs.') ';
1319 gduche 633
		}
634
 
635
		if (!empty($conditionsImg) && strlen($idsImages) > 0) {
1320 gduche 636
			$where[] = 'di.id_image IN ( '.$idsImages.') ';
1319 gduche 637
		}
638
 
1320 gduche 639
 
1319 gduche 640
		if (!empty($where)) {
1320 gduche 641
			$chaineWhere = ' WHERE '.implode($connecteur, $where);
642
			$requeteLiaisons .= $chaineWhere;
1319 gduche 643
		}
725 gduche 644
		$requeteLiaisons .= $this->gestionBdd->getLimitSql();
1319 gduche 645
 
646
		// on ne lance la requete que si on a trouvé des images ou des observations, sinon
647
		// cela signifie qu'il n'y a aucune correspondance dans la base
648
		$retour = array();
649
		if (strlen($idsObs) > 0 || strlen($idsImages) > 0) {
650
			$retour = $this->bdd->recupererTous($requeteLiaisons);
651
		}
652
 
653
		return $retour;
709 gduche 654
	}
655
 
1312 gduche 656
 
657
	/**
658
	 * Chargement depuis la bdd de toutes les liaisons entre images et observations
659
	 * */
660
	private function chargerLiaisonsSimple() {
661
 
662
		// Charger les obs images / images
663
		// récupérer les ids
664
		// récupérer les observations
665
 
1319 gduche 666
		$requeteImages = 'SELECT *, di.mots_cles_texte as mots_cles_texte_image FROM del_obs_image doi '.
1312 gduche 667
						'INNER JOIN del_image di ON doi.id_image = di.id_image '.
668
						'ORDER BY id_observation DESC'.
669
						$this->gestionBdd->getLimitSql();
670
		$liaisons = $this->bdd->recupererTous($requeteImages);
1313 gduche 671
 
1312 gduche 672
 
1313 gduche 673
		$nbImages = 'SELECT count(id_image) as nb FROM del_obs_image';
674
		$requeteNbImages = $this->bdd->recupererTous($nbImages);
675
 
676
		$total = (int) $requeteNbImages[0]['nb'];
1312 gduche 677
		$this->navigation->setTotal($total);
678
 
679
		$idsObservations = array();
680
		foreach ($liaisons as $image) {
681
			$idObs = $image['id_observation'];
682
			$idsObservations[$idObs] = $idObs;
683
		}
684
 
685
		$requeteObservations = 'SELECT * FROM del_observation dob '.
686
							'LEFT JOIN del_utilisateur du ON dob.ce_utilisateur = du.id_utilisateur '.
687
							'WHERE id_observation IN ('.implode(',', $idsObservations).')';
688
		$resultatsObservations = $this->bdd->recupererTous($requeteObservations);
689
 
690
		$observations = array();
691
		foreach ($resultatsObservations as $id => $observation) {
692
			$idObs = $observation['id_observation'];
693
			$observations[$idObs] = $observation;
694
		}
695
 
696
		foreach ($liaisons as $id => $liaison) {
697
			$idObs = $liaison['id_observation'];
698
 
699
			$observation = $observations[$idObs];
700
			foreach ($observation as $cle => $valeur) {
701
				$liaisons[$id][$cle] = $valeur;
702
			}
703
		}
704
 
705
		return $liaisons;
706
	}
707
 
708
 
1168 aurelien 709
	private function assemblercomptageOccurencesMotsClesCel() {
710
		$chaineMotsClesAffiches = $this->conteneur->getParametre('mots_cles_cel_affiches');
711
		$tabMotsClesAffiches = explode(',',$chaineMotsClesAffiches);
712
		$chaineSql = '';
713
 
714
		// Comptage du nombre de mots clés officiels présents dans la chaine mots clés texte
715
		foreach ($tabMotsClesAffiches as $motCle) {
716
			if($chaineSql != '') {
717
				$chaineSql .= ' + ';
718
			}
719
			$chaineSql .= 'IF(FIND_IN_SET('.$this->proteger($motCle).',di.mots_cles_texte) != 0, 1, 0)';
720
		}
721
 
722
		return '('.$chaineSql.')';
723
	}
724
 
951 aurelien 725
	private function doitJoindreTableVotes() {
726
		return ($this->tri == 'votes');
727
	}
728
 
1168 aurelien 729
	private function doitJoindreTableTags() {
730
		return ($this->tri == 'tags');
731
	}
732
 
800 aurelien 733
	private function getTri() {
734
		$order = '';
951 aurelien 735
		if($this->doitJoindreTableVotes()) {
736
			$order = ' GROUP BY dvote.ce_image, dob.id_observation ORDER BY total_votes '.$this->directionTri.', date_transmission desc ';
1168 aurelien 737
		} else if($this->doitJoindreTableTags()) {
738
			$order = ' GROUP BY doi.id_image ORDER BY total_tags '.$this->directionTri.', date_transmission desc ';
951 aurelien 739
		} else {
800 aurelien 740
			$order = ' ORDER BY '.$this->tri.' '.$this->directionTri.' ';
741
		}
742
		return $order;
743
	}
744
 
709 gduche 745
	/**
746
	* Compter le nombre total d'images dans la base pour affichage dans entete.
747
	* */
748
	private function compterImages() {
749
		$requete = 'SELECT FOUND_ROWS() AS nbre ';
719 gduche 750
		$resultats = $this->bdd->recuperer($requete);
709 gduche 751
		return (int) $resultats['nbre'];
752
	}
753
 
754
	/**
755
	* Retourner un tableau d'images formaté en fonction des liaisons trouvées
756
	* @param $liaisons les liaisons de la table del_obs_images
757
	* */
758
	private function chargerImage($liaisons) {
759
 
760
		$images = array();
761
		foreach ($liaisons as $liaison) {
736 gduche 762
			$idImage = $liaison['id_image'];
709 gduche 763
 
1274 aurelien 764
			if($liaison['ce_utilisateur'] == 0) {
765
				$liaison['prenom'] = $liaison['prenom_utilisateur'];
766
				$liaison['nom'] = $liaison['nom_utilisateur'];
767
			}
709 gduche 768
			// On enregistre l'ID de l'image pour n'effectuer qu'une seule requête par la suite
769
			$this->imageIds[] = $idImage;
800 aurelien 770
			$index = $liaison['id_image'].'-'.$liaison['id_observation'];
1025 aurelien 771
			$images[$index] = array('id_image' => $idImage, 'binaire.href' => $this->formaterLienImage($idImage),
772
						'protocoles_votes' => array(),
1017 aurelien 773
						'mots_cles_texte' => $liaison['mots_cles_texte_image'], 'observation' => $this->formaterObservation($liaison));
709 gduche 774
		}
775
		return $images;
776
	}
777
 
778
	/**
779
	* Charger les votes pour chaque image
780
	* */
781
	private function chargerVotes($images) {
760 delphine 782
			$requeteVotes = 'SELECT v.*, p.* FROM '.
783
								$this->gestionBdd->formaterTable('del_image_vote', 'v').
784
								' INNER JOIN del_image_protocole p '.
785
									'ON v.ce_protocole = p.id_protocole '.
775 aurelien 786
									$this->chargerClauseWhereVotes();
719 gduche 787
			$resultatsVotes = $this->bdd->recupererTous($requeteVotes);
709 gduche 788
 
857 gduche 789
 
790
			//TODO : faire une méthode formater vote
709 gduche 791
			$votes = $this->formaterVotes($resultatsVotes);
792
 
793
			foreach ($images as $id => $image) {
794
				if (isset($votes[$image['id_image']])) {
779 aurelien 795
					$images[$id]['protocoles_votes'] = $votes[$image['id_image']];
709 gduche 796
				}
797
			}
798
 
799
		return $images;
800
	}
801
 
759 delphine 802
	private function chargerClauseWhereVotes() {
803
		if (sizeof($this->imageIds) > 0) {
804
			$chaineImageIds = implode(',', $this->imageIds);
760 delphine 805
			$where[] = 'v.ce_image  IN ('.$chaineImageIds.')';
759 delphine 806
		}
807
		if (isset($this->parametres['protocole'])) {
760 delphine 808
			$where[] = 'v.ce_protocole = '.$this->proteger($this->parametres['protocole']);
759 delphine 809
		}
775 aurelien 810
 
811
		$where = (!empty($where)) ? 'WHERE '.implode(' AND ', $where) : '';
812
		return $where;
759 delphine 813
	}
814
 
709 gduche 815
	/*-------------------------------------------------------------------------------
816
								FORMATER ET METTRE EN FORME
817
	--------------------------------------------------------------------------------*/
818
 
819
	/**
820
	*  Formater une observation depuis une ligne liaison
821
	*  @param $liaison liaison issue de la recherche
822
	*  @return $observation l'observation mise en forme
823
	* */
824
	private function formaterObservation($liaison) {
825
		$observation = array();
826
		foreach ($this->mappingObservation as $nomOriginal => $nomFinal) {
827
			$observation[$nomFinal] = $liaison[$nomOriginal];
828
		}
829
 
830
		return $observation;
831
	}
832
 
833
	/**
834
	*  Formater une observation depuis une ligne liaison
835
	*  @param $liaison liaison issue de la recherche
836
	*  @return $observation l'observation mise en forme
837
	* */
838
	private function formaterVotes($votes) {
839
		$retour = array();
840
		foreach ($votes as $vote) {
759 delphine 841
			$retour_vote = array();
842
			foreach ($vote as $param=>$valeur) {
760 delphine 843
				if (strpos($this->mappingVotes[$param], 'protocole.') === 0) {
844
					$retour_protocole[$this->mappingVotes[$param]] = $valeur;
845
				} else {
846
					$retour_vote[$this->mappingVotes[$param]] = $valeur;
847
				}
759 delphine 848
			}
760 delphine 849
			if (!isset($retour[$vote['ce_image']][$vote['ce_protocole']])) {
850
				$retour[$vote['ce_image']][$vote['ce_protocole']] = $retour_protocole;
851
			}
852
			$retour[$vote['ce_image']][$vote['ce_protocole']]['votes'][$vote['id_vote']] = $retour_vote;
709 gduche 853
		}
854
 
855
		return $retour;
856
	}
857
 
858
	/**
859
	 * Formater le lien de l'image en fonction du fichier de config et de l'identifiant de l'image
860
	 * */
861
	private function formaterLienImage($idImage) {
862
		$idImage = sprintf('%09s', $idImage);
719 gduche 863
		$url = $this->conteneur->getParametre('url_images');
709 gduche 864
		$urlImage = str_replace('%s', $idImage, $url);
865
		return $urlImage;
866
	}
719 gduche 867
 
868
	private function proteger($valeur) {
869
		if (is_array($valeur)) {
870
			return $this->bdd->protegerTableau($valeur);
871
		} else {
872
			return $this->bdd->proteger($valeur);
709 gduche 873
		}
874
	}
875
}
876
?>