Subversion Repositories eFlore/Applications.del

Rev

Rev 1438 | Rev 1441 | Go to most recent revision | Details | Compare with Previous | 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
 
1326 gduche 18
 
19
/**
20
 * FONCTION TEMPORAIRE de debug pour afficher le contenu d'une variable en format lisible
21
 * @param $r la variable à afficher
22
 * */
23
function debug($r) {
24
	echo '<pre>'.print_r($r, true).'</pre>';
25
}
26
 
27
 
28
/**
29
 * Le service ListeImages récupère les données des tables observation et images
30
 * et les mets au format JSON pour identiplante / pictoflora
31
 * */
751 delphine 32
class ListeImages {
709 gduche 33
 
1326 gduche 34
 
35
	// Variables :
36
	// Configuration générale du service
719 gduche 37
	private $conteneur;
725 gduche 38
	private $navigation;
1326 gduche 39
	private $bdd;
725 gduche 40
	private $gestionBdd;
1326 gduche 41
 
42
	// Parametres
43
	private $ressources = array();
759 delphine 44
	private $parametres = array();
1326 gduche 45
	private $masque;
46
 
800 aurelien 47
	private $tri = 'date_transmission';
48
	private $directionTri = 'desc';
1345 aurelien 49
	private $formatRetour = 'XL';
709 gduche 50
 
1326 gduche 51
	private $imageIds = array();
52
 
53
 
54
	/**
55
	 * Constructeur de l'application
56
	 * Initialisation des variables générale de l'application
57
	 * @param Conteneu $conteneur le conteneur de classes de l'application
58
	 * */
719 gduche 59
	public function __construct(Conteneur $conteneur = null) {
60
		$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
791 aurelien 61
		$this->conteneur->chargerConfiguration('config_departements_bruts.ini');
798 aurelien 62
		$this->conteneur->chargerConfiguration('config_mapping_votes.ini');
775 aurelien 63
		$this->conteneur->chargerConfiguration('config_images.ini');
725 gduche 64
		$this->navigation = $conteneur->getNavigation();
65
		$this->masque = $conteneur->getMasque();
66
		$this->gestionBdd = $conteneur->getGestionBdd();
775 aurelien 67
		$this->bdd = $this->gestionBdd->getBdd();
719 gduche 68
	}
69
 
1326 gduche 70
 
709 gduche 71
	/**
72
	 * Méthode principale de la classe.
1326 gduche 73
	 * Lance la récupération des images dans la base et les place dans un objet ResultatService
709 gduche 74
	 * pour l'afficher.
75
	 * @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
76
	 * @param array $parametres les paramètres situés après le ? dans l'url
77
	 * */
78
	public function consulter($ressources, $parametres) {
1326 gduche 79
 
759 delphine 80
		$this->initialiserRessourcesEtParametres($ressources, $parametres);
709 gduche 81
 
82
		$this->configurer();
711 gduche 83
		$this->verifierConfiguration();
1326 gduche 84
 
800 aurelien 85
		$this->verifierParametresTri();
86
		$this->initialiserTri();
1345 aurelien 87
 
88
		$this->verifierParametreFormatRetour();
89
		$this->initialiserFormatRetour();
1326 gduche 90
 
91
		$parametres = $this->nettoyerParametres($parametres);
92
 
93
		// En fonction des paramètres de recherche, on n'effectue
94
		// pas la même requête, pour optimiser les jointures et les
95
		// rapidités d'éxécution.
96
		$type = $this->getTypeRequete($parametres);
97
 
98
		switch ($type) {
99
			case 'obs' :
100
				$liaisons = $this->chargerLiaisonsObs();
101
			break;
102
			case 'images' :
103
				$liaisons = $this->chargerLiaisonsImages();
104
			break;
105
			case 'obs-images' :
106
				$liaisons = $this->chargerLiaisons();
107
			break;
108
			default : //case simple !
109
			$liaisons = $this->chargerLiaisonsSimple();
110
		}
111
 
1439 raphael 112
		$images = array();
113
		if($liaisons) {
114
			// Partie commune à tous les cas : on complète les liaisons avec les informations des votes
115
			// et des images, puis on affiche sous forme de JSON
116
			$images = $this->chargerImage($liaisons);
117
			$images = $this->chargerVotes($images);
118
		}
1326 gduche 119
 
1321 gduche 120
		$resultat = new ResultatService();
121
		$resultat->corps = array('entete' => $this->conteneur->getEntete(), 'resultats' => $images);
1326 gduche 122
 
1321 gduche 123
		return $resultat;
709 gduche 124
	}
125
 
800 aurelien 126
 
127
 
1326 gduche 128
	/**************************************************************************************
129
	 *								FONCTION LIEES AUX REQUETES 						  *
130
	 **************************************************************************************/
709 gduche 131
 
132
	/**
1326 gduche 133
	 * Charger la clause WHERE en fonction des paramètres de masque
710 gduche 134
	 * */
1326 gduche 135
	private function chargerClauseWhere() {
728 gduche 136
 
709 gduche 137
		$where = array();
725 gduche 138
		$tableauMasque = $this->masque->getMasque();
139
		if (!empty($tableauMasque)) {
140
			foreach($tableauMasque as $idMasque => $valeurMasque) {
1326 gduche 141
				//TODO: scinder ceci en fonctions réutilisables ?
142
				// voir si c'est interessant par rapport à la recherche générale
725 gduche 143
				$idMasque = str_replace('masque.', '', $idMasque);
144
				switch ($idMasque) {
1326 gduche 145
				// nom du masque => nom BDD
725 gduche 146
					case 'auteur' :
1326 gduche 147
							$whereAuteur = ' '.$this->creerFiltreAuteur($this->masque->getMasque('auteur'));
148
									if($whereAuteur != '') {
149
										$where[] = $whereAuteur;
150
									}
151
									break;
791 aurelien 152
					case 'date' :
1326 gduche 153
					$whereDate = ' '.$this->creerFiltreDate($valeurMasque);
154
					if($whereDate != '') {
155
						$where[] = $whereDate;
156
					}
157
					break;
791 aurelien 158
					case 'departement' :
159
						$where[] = ' '.$this->creerFiltreIdZoneGeo($valeurMasque);
160
						break;
725 gduche 161
					case 'genre' :
719 gduche 162
						$where[] = ' '.$this->mappingFiltre['ns'].' LIKE '.$this->proteger($valeurMasque.' %');
725 gduche 163
						break;
164
					case 'tag' :
791 aurelien 165
						$where[] = ' '.$this->creerFiltreMotsCles($valeurMasque);
725 gduche 166
						break;
1365 aurelien 167
					case 'referentiel' :
1413 aurelien 168
						$where[] = ' dob.nom_referentiel LIKE '.$this->proteger($valeurMasque.'%');
1365 aurelien 169
						break;
775 aurelien 170
					case 'ns' :
791 aurelien 171
						$where[] = ' nom_sel LIKE '.$this->proteger($valeurMasque.'%');
1326 gduche 172
						break;
1332 aurelien 173
					case 'nn' :
174
						$where[] = ' (nom_sel_nn LIKE '.$this->proteger($valeurMasque.'%').' OR '.
175
								   ' nom_ret_nn LIKE '.$this->proteger($valeurMasque.'%').') ';
176
						break;
791 aurelien 177
					case 'commune' :
178
						$where[] = ' '.$this->mappingFiltre[$idMasque].' LIKE '.$this->proteger(str_replace(array('-',' '), '_', $valeurMasque).'%');
1326 gduche 179
						break;
791 aurelien 180
					case 'masque' :
181
						$where[] = ' '.$this->creerFiltreMasqueGeneral($valeurMasque);
775 aurelien 182
						break;
725 gduche 183
					default:
184
						$where[] = ' '.$this->mappingFiltre[$idMasque].' = '.$this->proteger($valeurMasque);
1326 gduche 185
						break;
725 gduche 186
				}
1326 gduche 187
			}
709 gduche 188
		}
1326 gduche 189
 
709 gduche 190
		if (!empty($where)) {
191
			return ' WHERE '.implode('AND', $where);
192
		} else {
193
			return;
194
		}
195
	}
196
 
1326 gduche 197
	/**
198
	 * Créer un masque général lorsque l'on souhaite utiliser le passe partout
199
	 * @param la valeur du passe partout
200
	 * */
791 aurelien 201
	private function creerFiltreMasqueGeneral($valeurMasque) {
1326 gduche 202
		//TODO: affecter d'aborder les variables, puis les tester pour les
791 aurelien 203
		// ajouter à la chaine
204
		$whereAuteur = $this->creerFiltreAuteur($valeurMasque);
1326 gduche 205
		$whereIdZoneGeo = $this->creerFiltreIdZoneGeo($valeurMasque);
206
 
791 aurelien 207
		$masqueGeneral = '( '.
1326 gduche 208
				(($whereAuteur != '') ? $whereAuteur.' OR ' : '' ).
209
				(($whereIdZoneGeo != '') ? $whereIdZoneGeo.' OR ' : '' ).
210
				'zone_geo LIKE '.$this->proteger($this->remplacerParJokerCaractere($valeurMasque).'%').' OR '.
211
				$this->creerFiltreMotsCles($valeurMasque).' OR '.
212
				'nom_sel LIKE '.$this->proteger($valeurMasque.'%').' OR '.
213
				'famille LIKE '.$this->proteger($valeurMasque.'%').' OR '.
214
				'milieu LIKE '.$this->proteger($valeurMasque).' OR '.
215
				$this->mappingFiltre['ns'].' LIKE '.$this->proteger('%'.$valeurMasque.'% %').' OR '.
216
				$this->creerFiltreDate($valeurMasque).
217
				') ';
791 aurelien 218
 
219
		return $masqueGeneral;
220
	}
221
 
1326 gduche 222
	/**
223
	 * Créer le filtre auteur en recherchant dans son nom, prénom, adresse email en fonction
224
	 * de la chaine donnée
225
	 * @param la valeur recherchée
226
	 * */
791 aurelien 227
	private function creerFiltreAuteur($valeurMasque) {
228
		$masque = '';
229
		$auteurId = $valeurMasque;
230
		if (is_numeric($auteurId)) {
231
			$masque = ' ce_utilisateur = '.$auteurId;
232
		} else {
233
			if (strpos($auteurId, '@') === false) {
234
				$tableauNomPrenom = explode(' ',$auteurId, 2);
235
				if(count($tableauNomPrenom) == 2) {
236
					// on teste potentiellement un nom prenom ou bien un prénom nom
237
					$masque = '('.
1326 gduche 238
							'(nom LIKE '.$this->proteger($tableauNomPrenom[0].'%').' AND '.
239
							'prenom LIKE '.$this->proteger($tableauNomPrenom[1].'%').') OR '.
240
							'(nom LIKE '.$this->proteger($tableauNomPrenom[1].'%').' AND '.
241
							'prenom LIKE '.$this->proteger($tableauNomPrenom[0].'%').') OR '.
242
							'(dob.nom_utilisateur LIKE '.$this->proteger($tableauNomPrenom[0].'%').' AND '.
243
							'dob.prenom_utilisateur LIKE '.$this->proteger($tableauNomPrenom[1].'%').') OR '.
244
							'(dob.nom_utilisateur LIKE '.$this->proteger($tableauNomPrenom[1].'%').' AND '.
245
							'dob.prenom_utilisateur LIKE '.$this->proteger($tableauNomPrenom[0].'%').') OR '.
246
							'(nom LIKE '.$this->proteger($valeurMasque.'%').') OR '.
247
							'(prenom LIKE '.$this->proteger($valeurMasque.'%').') OR '.
248
							'(dob.nom_utilisateur LIKE '.$this->proteger($valeurMasque.'%').') OR '.
249
							'(dob.prenom_utilisateur LIKE '.$this->proteger($valeurMasque.'%').') '.
250
							')';
791 aurelien 251
				} else {
252
					$masque = '(
253
						            (nom LIKE '.$this->proteger($auteurId.'%').' OR '.
1326 gduche 254
							            'prenom LIKE '.$this->proteger($auteurId.'%').' OR '.
255
							            'dob.nom_utilisateur LIKE '.$this->proteger($auteurId.'%').' OR '.
256
							            'dob.prenom_utilisateur LIKE '.$this->proteger($auteurId.'%').')'.
257
							            ')';
791 aurelien 258
				}
259
			} else {
1333 gduche 260
				$masque = " ( courriel LIKE ".$this->proteger($valeurMasque.'%').
261
				" OR dob.courriel_utilisateur LIKE ".$this->proteger($valeurMasque.'%').")  ";
791 aurelien 262
			}
263
		}
264
		return $masque;
265
	}
266
 
267
 
1326 gduche 268
	/**
269
	 * Obtenir une chaine de caractère concaténant nom et prénom séparé par une virgule
270
	 * @param String $auteurId l'identifiant de l'auteur
271
	 * @return String la chaine de concaténation
272
	 * */
273
	private function getChaineNomPrenom($auteurId) {
274
		$nomPrenom = explode(' ', $auteurId);
275
		$nomPrenom = $this->proteger($nomPrenom);
276
		$chaineNomPrenom = implode(', ', $nomPrenom);
277
		return $chaineNomPrenom;
791 aurelien 278
	}
279
 
1326 gduche 280
	/**
281
	 * Créer le filtre de recherche par zone géographique en fonction du masque
282
	 * @param $valeurMasque le terme de la recherche
283
	 * */
791 aurelien 284
	private function creerFiltreIdZoneGeo($valeurMasque) {
285
		$masque = '';
286
		$dept = $valeurMasque;
287
		if (is_numeric($dept)) {
288
			$dept = sprintf('%02s', $dept);
289
			$dept = sprintf("%-'_5s", $dept);
290
			$masque = " ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$dept);
291
		} else {
292
			$deptId = $this->conteneur->getParametre($dept);
293
			if ($deptId != null) {
294
				$masque = " ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$deptId.'%');
295
			} else {
296
				$id = $this->obtenirIdDepartement($valeurMasque);
297
				$masque = " ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$id.'%');
298
			}
299
		}
300
		return $masque;
301
	}
302
 
1326 gduche 303
	/**
304
	 * Générer la chaine de recherche pour la date en  fonction du masque
305
	 * @param $valeurMasque la date recherchée (AAAA ou JJ/MM/AAAA)
306
	 * */
791 aurelien 307
	private function creerFiltreDate($valeurMasque) {
308
		//TODO: définir dans le fichier de config un tableau contenant plusieurs format de date
309
		// autorisés pour la recherche, qui seraient ajoutés au OR
310
		$masque = '(';
311
		$masque .= (is_numeric($valeurMasque)) ? ' YEAR(date_observation) = '.$this->proteger($valeurMasque).' OR ' : '';
312
		$masque .= " DATE_FORMAT(date_observation, '%d/%m/%Y') = ".$this->proteger($valeurMasque).' '.
1326 gduche 313
				')';
791 aurelien 314
		return $masque;
315
	}
801 aurelien 316
 
1326 gduche 317
	/**
318
	 * Générer la chaine de recherche dans les mots clés en fonction du masque
319
	 * @param $valeurMasque le mot clé recherché
320
	 * */
791 aurelien 321
	private function creerFiltreMotsCles($valeurMasque) {
1326 gduche 322
 
800 aurelien 323
		$mots_cles = explode(' ', $valeurMasque);
812 gduche 324
		$requeteMotsClesImg = array();
325
		$requeteMotsClesObs = array();
1180 aurelien 326
		$requeteMotsClesImgPublic = array();
1326 gduche 327
 
800 aurelien 328
		foreach($mots_cles as $mot_cle) {
1180 aurelien 329
			//TODO: rechercher sur les mots clés normalisés dans tous les cas ?
857 gduche 330
			$requeteMotsCles = $this->proteger('%'.$mot_cle.'%');
1180 aurelien 331
			$motsCleProtege = $this->proteger($this->normaliserMotCle('%'.$mot_cle.'%'));
1326 gduche 332
			$requeteMotsClesImgPublic[] = 'di.id_image IN (SELECT ce_image FROM del_image_tag WHERE tag_normalise LIKE '.$motsCleProtege.' AND actif = 1)';
857 gduche 333
			$requeteMotsClesImg[] = 'di.mots_cles_texte LIKE '.$requeteMotsCles;
334
			$requeteMotsClesObs[] = 'dob.mots_cles_texte LIKE '.$requeteMotsCles;
800 aurelien 335
		}
1326 gduche 336
 
1180 aurelien 337
		$requeteMotsClesImgPublic = implode(' AND ', $requeteMotsClesImgPublic);
857 gduche 338
		$requeteMotsClesImg = implode(' AND ', $requeteMotsClesImg);
339
		$requeteMotsClesObs = implode(' AND ', $requeteMotsClesObs);
1326 gduche 340
 
800 aurelien 341
		$masque = '('.
1326 gduche 342
				'('.$requeteMotsClesImgPublic.') OR '.
343
				'('.$requeteMotsClesImg.') OR '.
344
				'('.$requeteMotsClesObs.') '.
345
				')';
791 aurelien 346
 
1326 gduche 347
		return $masque;
709 gduche 348
	}
349
 
1326 gduche 350
	// ??
1168 aurelien 351
	private function assemblercomptageOccurencesMotsClesCel() {
352
		$chaineMotsClesAffiches = $this->conteneur->getParametre('mots_cles_cel_affiches');
353
		$tabMotsClesAffiches = explode(',',$chaineMotsClesAffiches);
354
		$chaineSql = '';
1326 gduche 355
 
1168 aurelien 356
		// Comptage du nombre de mots clés officiels présents dans la chaine mots clés texte
357
		foreach ($tabMotsClesAffiches as $motCle) {
358
			if($chaineSql != '') {
359
				$chaineSql .= ' + ';
360
			}
361
			$chaineSql .= 'IF(FIND_IN_SET('.$this->proteger($motCle).',di.mots_cles_texte) != 0, 1, 0)';
362
		}
1326 gduche 363
 
1168 aurelien 364
		return '('.$chaineSql.')';
365
	}
366
 
1326 gduche 367
	private function getTri() {
800 aurelien 368
		$order = '';
951 aurelien 369
		if($this->doitJoindreTableVotes()) {
370
			$order = ' GROUP BY dvote.ce_image, dob.id_observation ORDER BY total_votes '.$this->directionTri.', date_transmission desc ';
1168 aurelien 371
		} else if($this->doitJoindreTableTags()) {
372
			$order = ' GROUP BY doi.id_image ORDER BY total_tags '.$this->directionTri.', date_transmission desc ';
951 aurelien 373
		} else {
800 aurelien 374
			$order = ' ORDER BY '.$this->tri.' '.$this->directionTri.' ';
375
		}
376
		return $order;
377
	}
378
 
709 gduche 379
	/**
1326 gduche 380
	 * Compter le nombre total d'images dans la base pour affichage dans entete.
381
	 * */
382
	private function getFoundRows() {
709 gduche 383
		$requete = 'SELECT FOUND_ROWS() AS nbre ';
719 gduche 384
		$resultats = $this->bdd->recuperer($requete);
709 gduche 385
		return (int) $resultats['nbre'];
386
	}
387
 
1326 gduche 388
 
709 gduche 389
	/**
1326 gduche 390
	 * En fonction des paramètres, générer les conditions de recherche
391
	 * des observations
392
	 * */
393
	private function getConditionsObs() {
1327 gduche 394
		$conditionsObs = array();
1326 gduche 395
		$masques = $this->masque->getMasque();
396
		if (isset($masques['masque'])) {
397
			$passe = $masques['masque'];
398
 
399
			// Si on a saisi le masque passe partout, alors on doit chercher dans tous les champs
400
			// de la table observation (OR)
401
			$conditionLibre = array();
402
 
403
			if (!isset($masques['masque.ns'])) {
404
				$conditionsLibre[] = "nom_sel LIKE '$passe%'";
405
			}
406
 
407
			if (!isset($masques['masque.famille'])) {
408
				$conditionsLibre[] = "famille LIKE '$passe%'";
409
			}
410
 
411
			if (!isset($masques['masque.milieu'])) {
412
				$conditionsLibre[] = "nom_sel LIKE '$passe%'";
413
			}
414
 
415
			if (!isset($masques['masque.date'])) {
416
				$conditionsLibre[] = $this->creerFiltreDate($passe);
417
			}
418
 
419
			if (!isset($masques['masque.auteur'])) {
420
				$conditionsLibre[] = $this->creerFiltreAuteur($passe);
421
			}
422
 
423
			/*
424
			 * FIXME : remplacer par motcle projet !
425
			* if (!isset($masques['masque.tag'])) {
426
			$conditionsLibre[] = "mots_cles_texte LIKE '%$passe%'";
427
			}*/
428
 
429
			$conditionsObs[] = implode(' OR ', $conditionsLibre);
430
		}
431
 
1366 aurelien 432
		// referentiel
433
		if (isset($masques['masque.referentiel'])) {
434
			$ref = $masques['masque.referentiel'];
1413 aurelien 435
			$conditionsObs[] = "dob.nom_referentiel LIKE '$ref%'";
1366 aurelien 436
		}
437
 
1326 gduche 438
		// nom sel
439
		if (isset($masques['masque.ns'])) {
440
			$nom_sel = $masques['masque.ns'];
441
			$conditionsObs[] = "nom_sel LIKE '$nom_sel%'";
442
		}
443
 
1332 aurelien 444
		// nom sel
445
		if (isset($masques['masque.nn'])) {
446
			$num_nom = $masques['masque.nn'];
447
			$conditionsObs[] = "(nom_sel_nn = '$num_nom' OR nom_ret_nn = '$num_nom') ";
448
		}
449
 
1326 gduche 450
		// famille
451
		if (isset($masques['masque.famille'])) {
452
			$famille = $masques['masque.famille'];
453
			$conditionsObs[] = "famille LIKE '$famille%'";
454
		}
455
 
456
		// genre
457
		if (isset($masques['masque.genre'])) {
458
			$genre = $masques['masque.genre'];
459
			$conditionsObs[] = "nom_sel LIKE '$genre%'";
460
		}
461
 
462
		// milieu
463
		if (isset($masques['masque.milieu'])) {
464
			$milieu = $masques['masque.milieu'];
465
			$conditionsObs[] = "nom_sel LIKE '$milieu%'";
466
		}
467
 
468
		// date
469
		if (isset($masques['masque.date'])) {
470
			$date = $masques['masque.date'];
471
			$conditionsObs[] = $this->creerFiltreDate($date);
472
		}
473
 
474
		// utilisateur
475
		if (isset($masques['masque.auteur'])) {
476
			$auteur = $masques['masque.auteur'];
477
			$conditionsObs[] = $this->creerFiltreAuteur($auteur);
478
		}
479
 
480
		// commune
481
		if (isset($masques['masque.commune'])) {
482
			$commune = $masques['masque.commune'];
483
			$conditionsObs[] = " zone_geo LIKE ".$this->proteger(str_replace(array('-',' '), '_', $commune).'%');
484
		}
485
 
486
		// commune
487
		if (isset($masques['masque.departement'])) {
488
			$dept = $masques['masque.departement'];
489
			$conditionsObs[] = $this->creerFiltreIdZoneGeo($dept);
490
		}
1332 aurelien 491
 
1326 gduche 492
		return $conditionsObs;
493
	}
494
 
495
	/**
496
	 * Obtenir le tableu de chaines de condition de requete images en fonction des masques
497
	 * */
498
	private function getConditionsImages() {
499
		$conditionsImg = array();
500
		$masques = $this->masque->getMasque();
501
		if (isset($masques['masque.tag'])) {
502
			$tag = $masques['masque.tag'];
503
			$conditionsImg[] = " dit.tag_normalise LIKE '$tag%' ";
504
			$conditionsImg[] = " di.mots_cles_texte LIKE '%$tag%' ";
505
		}
506
 
507
		return $conditionsImg;
508
	}
509
 
510
 
511
	/*-------------------------------------------------------------------------------
512
	 CHARGEMENT DES IMAGES
513
	--------------------------------------------------------------------------------*/
514
	/**
515
	 * Chargement depuis la bdd de toutes les liaisons entre images et observations
516
	 * Méthode appelée uniquement lorsque les paramètres sont vides
517
	 * */
518
	private function chargerLiaisonsSimple() {
519
 
520
		// On récupère d'abord les N images de del_obs_image, éventuellement triées,
521
		// Et on complète avec les informations des observations associées
522
		$requeteImages = ' SELECT *, di.mots_cles_texte as mots_cles_texte_image '.
523
						 ' FROM del_obs_image doi '.
524
						 ' INNER JOIN del_image di ON doi.id_image = di.id_image ';
525
 
526
		// Si le tri se fait par date d'observation, on récupère les identifiants de N observations triées
527
		if (isset($this->parametres['tri']) && $this->parametres['tri'] == 'date_observation') {
528
 
529
			$ordre = isset($this->parametres['ordre']) ? $this->parametres['ordre'] : 'DESC';
530
 
531
			$requeteIdObs = ' SELECT doi.id_image  as id_image '.
532
							' FROM del_obs_image doi '.
533
							' INNER JOIN del_observation dob ON dob.id_observation = doi.id_observation '.
534
							' INNER JOIN del_image di ON doi.id_image = di.id_image '.
535
							' ORDER BY date_observation '.$ordre.', dob.id_observation '.$ordre;
536
			$requeteIdObs .= $this->gestionBdd->getLimitSql();
537
 
538
			// Récupérer les N observations triées par date
1438 raphael 539
			$observations = $this->bdd->recupererTous($requeteIdObs . ' -- ' . __FILE__ . ':' . __LINE__);
1326 gduche 540
 
541
			$idsImages = array();
542
			foreach ($observations as $observation) {
543
				$idsImages[] = $observation['id_image'];
544
			}
545
 
546
			$chaineIdImages = implode(',', $idsImages);
547
			$requeteImages .= ' WHERE doi.id_image IN ('.$chaineIdImages.') '.
1328 aurelien 548
							  ' GROUP BY doi.id_image, doi.id_observation '.
1326 gduche 549
							  ' ORDER BY FIELD(doi.id_image,  '.$chaineIdImages.')'.
550
							  ' LIMIT '.$this->navigation->getLimite(); // On limite sur le nombre car les obs peuvent avoir plusieurs images
551
 
552
		} else {
1328 aurelien 553
			$requeteImages .= ' GROUP BY doi.id_image, doi.id_observation ';
1392 raphael 554
			$requeteImages .= ' ORDER BY doi.id_observation DESC';
1326 gduche 555
			$requeteImages .= $this->gestionBdd->getLimitSql();
556
		}
557
 
1438 raphael 558
		$liaisons = $this->bdd->recupererTous($requeteImages . ' -- ' . __FILE__ . ':' . __LINE__);
1326 gduche 559
 
560
		// Ce n'est pas la peine de continuer s'il n'y a pas eu de résultats dans la table del_obs_images
561
		if (!empty($liaisons)) {
562
 
563
			$idsObservations = array();
564
			foreach ($liaisons as $image) {
565
				$idObs = $image['id_observation'];
566
				$idsObservations[$idObs] = $idObs;
567
			}
568
 
569
			$chaineIdObs = implode(',', $idsObservations);
570
 
571
 
572
			// On récupère les observations qui complètent la requête précédente
573
			$requeteObservations = ' SELECT * '.
574
								   ' FROM del_observation dob '.
575
								   ' LEFT JOIN del_utilisateur du ON dob.ce_utilisateur = du.id_utilisateur '.
576
								   ' WHERE id_observation IN ('.$chaineIdObs.')';
577
 
1438 raphael 578
			$resultatsObservations = $this->bdd->recupererTous($requeteObservations . ' -- ' . __FILE__ . ':' . __LINE__);
1326 gduche 579
 
580
			// FIXME : Ca ne doit pas arriver, mais que se passe-t-il s'il n'y a pas d'observation pour l'image ?!
581
 
582
			// On range les observations dans un tableau pour pouvoir les retrouver par leur id :
583
			$observations = array();
584
			foreach ($resultatsObservations as $id => $observation) {
585
				$idObs = $observation['id_observation'];
586
				$observations[$idObs] = $observation;
587
			}
588
 
589
			// Enfin, pour chaque image préalablement récupérées, on complète avec les informations de l'observation
590
			// FIXME : peut-être peut-on utiliser un array_merge ici ?
591
			foreach ($liaisons as $id => $liaison) {
592
				$idObs = $liaison['id_observation'];
593
 
594
				$observation = $observations[$idObs];
595
				foreach ($observation as $cle => $valeur) {
596
					$liaisons[$id][$cle] = $valeur;
597
				}
598
			}
599
 
600
 
601
			// On compte à part les images issues de la jointure de del_obs_image et del_image car la fonction
602
			// SQL_CALC_FOUND_ROWS dans la fonction requete image fait passer le temps d'éxécution de 0.0011 à 15s !
1328 aurelien 603
			$requeteNbImages = 'SELECT SUM(t.nb) as nb FROM (SELECT count(DISTINCT doi.id_image) as nb '.
604
							   'FROM del_obs_image doi '.
605
							   'INNER JOIN del_image di '.
606
							   'ON di.id_image = doi.id_image '.
607
							   'GROUP BY doi.id_image, doi.id_observation) t ';
1438 raphael 608
			$resultatNbImages = $this->bdd->recupererTous($requeteNbImages . ' -- ' . __FILE__ . ':' . __LINE__);
1328 aurelien 609
 
1326 gduche 610
			$total = (int) $resultatNbImages[0]['nb'];
611
			$this->navigation->setTotal($total);
612
		}
1328 aurelien 613
 
1326 gduche 614
		return $liaisons;
615
	}
616
 
617
 
618
	/**
619
	 * Chargement depuis la bdd de toutes les liaisons entre images et observations
620
	 * Méthode appelée uniquement lorsque les paramètres concernent une observation
621
	 * */
622
	private function chargerLiaisonsObs() {
623
 
624
		// Récupérer les liaisons
1413 aurelien 625
		$requeteObs = ' SELECT SQL_CALC_FOUND_ROWS dob.id_observation as id_observation, dob.nom_referentiel, nom_sel, nom_sel_nn, nt, famille, ce_zone_geo, zone_geo, lieudit, station, milieu, '.
1326 gduche 626
				 	  ' 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, '.
627
					  ' doi.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 '.
628
					  'FROM del_observation dob '.
629
					  ' INNER JOIN del_obs_image doi ON dob.id_observation = doi.id_observation '.
630
					  ' INNER JOIN del_image di ON doi.id_image = di.id_image '.
631
					  ' LEFT JOIN del_utilisateur du ON dob.ce_utilisateur = du.id_utilisateur ';
632
 
633
		// Récupérer les conditions sous forme de tableau
634
		$conditionsObs = $this->getConditionsObs();
635
 
636
		if (!empty($conditionsObs)) {
637
			$where = ' WHERE '.implode(' AND ', $conditionsObs);
638
			$requeteObs .= $where;
639
		}
640
 
641
		// Gérer le tri (uniquement si c'est date_observation)
642
		if (isset($this->parametres['tri']) && $this->parametres['tri'] == 'date_observation') {
643
			$ordre = isset($this->parametres['ordre']) ? $this->parametres['ordre'] : 'DESC';
644
			$tri = ' ORDER BY '.$this->parametres['tri'].' '.$ordre.', doi.id_observation '.$ordre.' ';
645
			$requeteObs .= $tri;
646
		}
1332 aurelien 647
 
1326 gduche 648
		$requeteObs .= $this->gestionBdd->getLimitSql();
1438 raphael 649
		$observations = $this->bdd->recupererTous($requeteObs . ' -- ' . __FILE__ . ':' . __LINE__);
1332 aurelien 650
 
1326 gduche 651
		$total = $this->getFoundRows();
652
		$this->navigation->setTotal($total);
653
 
654
		return $observations;
655
	}
656
 
657
	/**
658
	 * Chargement depuis la bdd de toutes les liaisons entre images et observations
659
	 * Méthode appelée uniquement lorsque les paramètres concernent les images
660
	 * */
661
	private function chargerLiaisonsImages() {
662
 
663
		// FIXME : si on faisait une requete à part pour compter, ca irait plus vite
664
		// Récupérer tous les ID d'image en fonction des paramètres de recherche
665
		$requeteImages = ' SELECT SQL_CALC_FOUND_ROWS '.
1413 aurelien 666
						 ' doi.id_image as id_image, dob.id_observation as id_observation, dob.nom_referentiel, nom_sel, nom_sel_nn, nt, famille, ce_zone_geo, zone_geo, lieudit, station, milieu, '.
1326 gduche 667
						 ' 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, '.
668
						 ' di.ce_utilisateur as ce_utilisateur, prenom, nom, courriel, dob.prenom_utilisateur, dob.nom_utilisateur, dob.courriel_utilisateur, nom_original '.
669
						 ' FROM del_obs_image doi '.
670
						 ' INNER JOIN del_image di ON doi.id_image = di.id_image '.
671
						 ' INNER JOIN del_observation dob ON dob.id_observation = doi.id_observation '.
672
						 ' LEFT JOIN del_image_tag dit ON dit.ce_image = di.id_image '.
673
						 ' LEFT JOIN del_utilisateur du ON du.id_utilisateur = di.ce_utilisateur ';
1328 aurelien 674
 
1326 gduche 675
		$conditionsImg = $this->getConditionsImages();
676
 
677
		if (!empty($conditionsImg)) {
678
			$where = ' WHERE ('.implode(' OR ', $conditionsImg).') ';
679
			$where .= ' AND dit.actif = 1 ';
680
			$requeteImages .= $where;
681
		}
682
 
683
		// Gérer le tri, sur les votes ou sur les tags
684
		if (isset($this->parametres['tri'])) {
685
 
686
			$chaineTri = '';
687
			$chaineOrdre = '';
688
 
689
			if ($this->parametres['tri'] == 'votes') {
690
 
691
				$protocole = isset($this->parametres['protocole']) ? $this->parametres['protocole'] : 1;
692
 
693
				$requeteVotes = ' SELECT doi.id_image as id_image, IF(divo.ce_protocole = '.$protocole.', AVG(divo.valeur), 0) as total_votes '.
1330 aurelien 694
								' FROM del_obs_image doi '.
695
								' INNER JOIN del_image di ON doi.id_image = di.id_image '.
696
								' INNER JOIN del_observation dob ON dob.id_observation = doi.id_observation '.
1331 gduche 697
								' LEFT JOIN del_image_vote divo ON doi.id_image = divo.ce_image '.
698
                                ' AND ce_protocole = '.$protocole.' ';
1326 gduche 699
 
700
				// Et si on a cherché par tag ?
701
				if (isset($this->parametres['masque.tag'])) {
702
					$tag = $this->parametres['masque.tag'];
703
					$requeteVotes .= ' LEFT JOIN del_image_tag dit ON dit.ce_image = di.id_image ';
704
					$requeteVotes .= " WHERE (dit.tag_normalise LIKE '$tag%' OR  di.mots_cles_texte LIKE '%$tag%') AND dit.actif = 1 ";
705
				}
706
 
707
				$requeteVotes .= ' GROUP BY doi.id_image, doi.id_observation '.
1330 aurelien 708
								 ' ORDER by total_votes '.$this->directionTri .', doi.id_observation '.$this->directionTri.' '.
1326 gduche 709
						$this->gestionBdd->getLimitSql();
710
 
1331 gduche 711
 
1438 raphael 712
				$resultatsVotes = $this->bdd->recupererTous($requeteVotes . ' -- ' . __FILE__ . ':' . __LINE__);
1326 gduche 713
				$tabVotes = array();
714
				foreach ($resultatsVotes as $vote) {
715
					$tabVotes[] = $vote['id_image'];
716
				}
717
 
718
				$strVotes = empty($tabVotes) ? "''" : implode(',', $tabVotes);
719
 
720
				// Et si on a cherché par tag ?
721
				if (isset($this->parametres['masque.tag'])) {
722
					$chaineTri .= ' AND ';
723
				} else {
724
					$chaineTri .= ' WHERE ';
725
				}
726
 
727
 
728
				$chaineTri .= '  doi.id_image IN ('.$strVotes.') ';
729
				$chaineOrdre = ' ORDER BY FIELD(doi.id_image, '.$strVotes.')  ';
730
			}
1328 aurelien 731
 
1326 gduche 732
			if ($this->parametres['tri'] == 'tags') {
733
 
1328 aurelien 734
				$requetetags = ' SELECT SQL_CALC_FOUND_ROWS doi.id_image, COUNT(id_tag) as total_tags '.
1330 aurelien 735
						' FROM del_obs_image doi LEFT JOIN del_image_tag dit ON dit.ce_image = doi.id_image AND dit.actif = 1 '.
736
						 ' INNER JOIN del_image di ON doi.id_image = di.id_image '.
737
						 ' INNER JOIN del_observation dob ON dob.id_observation = doi.id_observation ';
738
 
1326 gduche 739
				if (isset($this->parametres['masque.tag'])) {
740
					// Et si on a cherché par tag ?
741
					$tag = $this->parametres['masque.tag'];
1328 aurelien 742
					$requetetags .= " WHERE (dit.tag_normalise LIKE '$tag%' OR  di.mots_cles_texte LIKE '%$tag%') ";
1326 gduche 743
				}
744
 
1330 aurelien 745
				$requetetags .= ' GROUP BY doi.id_image, doi.id_observation '.
746
						' ORDER by total_tags '.$this->directionTri.', doi.id_observation '.$this->directionTri.
1326 gduche 747
						$this->gestionBdd->getLimitSql();
1328 aurelien 748
 
1438 raphael 749
				$resultatstags = $this->bdd->recupererTous($requetetags . ' -- ' . __FILE__ . ':' . __LINE__);
1326 gduche 750
				$tabtags = array();
751
				foreach ($resultatstags as $tag) {
752
					$tabtags[] = $tag['id_image'];
753
				}
754
				$strtags = empty($tabtags) ? "''" : implode(',', $tabtags);
755
 
756
 
757
				// Et si on a cherché par tag ?
758
				if (isset($this->parametres['masque.tag'])) {
759
					$chaineTri .= ' AND ';
760
				} else {
761
					$chaineTri .= ' WHERE ';
762
				}
763
 
764
				$chaineTri .= ' doi.id_image IN ('.$strtags.') ';
765
				$chaineOrdre = ' ORDER BY FIELD(doi.id_image, '.$strtags.') ';
766
			}
1328 aurelien 767
 
1326 gduche 768
			$requeteImages .= $chaineTri.' GROUP BY doi.id_image, doi.id_observation '.$chaineOrdre;
769
		} else {
770
			$requeteImages .= ' GROUP BY doi.id_image, doi.id_observation'; // des fois, on a plusieurs observations pour la même image ...
771
			$requeteImages .= $this->gestionBdd->getLimitSql();
772
		}
1328 aurelien 773
 
1438 raphael 774
		$retour  = $this->bdd->recupererTous($requeteImages . ' -- ' . __FILE__ . ':' . __LINE__);
1326 gduche 775
		$total = $this->getFoundRows();
776
		$this->navigation->setTotal($total);
777
 
778
		return $retour;
779
	}
780
 
781
	/**
782
	 * Chargement depuis la bdd de toutes les liaisons entre images et observations
783
	 * */
784
	private function chargerLiaisons() {
785
 
1439 raphael 786
		$champs = array('dob.id_observation as id_observation', 'nom_sel', 'nom_sel_nn', 'nt', 'famille', 'dob.nom_referentiel', 'ce_zone_geo', 'zone_geo',
1326 gduche 787
				'lieudit', 'station', 'milieu', 'date_observation', 'dob.mots_cles_texte as mots_cles_texte', 'dob.commentaire as commentaire',
788
				'di.mots_cles_texte as mots_cles_texte_image ', 'date_transmission', 'di.id_image as id_image', 'di.ce_utilisateur as ce_utilisateur',
789
				'prenom', 'nom', 'courriel', 'dob.prenom_utilisateur', 'dob.nom_utilisateur', 'dob.courriel_utilisateur', 'nom_original');
790
		// Attention le LEFT JOIN est indispensable pour ramener les images n'ayant pas de votes
791
		// en cas de tri par votes
792
		$requeteLiaisons = 'SELECT DISTINCT SQL_CALC_FOUND_ROWS '.implode(', ',$champs).' '.
793
				($this->doitJoindreTableVotes() ?
794
						', IF(dvote.ce_protocole = '.$this->parametres['protocole'].', AVG(dvote.valeur), 0) as total_votes ' :
795
						''
796
				).
797
				($this->doitJoindreTableTags() ?
798
						// attention le DISTINCT est indispensable !
799
						', (COUNT(DISTINCT dtag.id_tag) + '.$this->assemblercomptageOccurencesMotsClesCel().') as total_tags ' :
800
						''
801
				).
802
				'FROM '.$this->gestionBdd->formaterTable('del_obs_image', 'doi').
803
				'INNER JOIN del_image di '.
804
				'ON doi.id_image = di.id_image '.
805
				'INNER JOIN del_observation dob '.
806
				'ON doi.id_observation = dob.id_observation '.
807
				'LEFT JOIN del_utilisateur du '.
808
				'ON du.id_utilisateur = di.ce_utilisateur '.
809
				($this->doitJoindreTableTags() ?
810
						'LEFT JOIN del_image_tag dtag '.
811
						'ON doi.id_image = dtag.ce_image AND dtag.actif = 1 ' :
812
						''
813
								).
814
								($this->doitJoindreTableVotes() ?
815
								'LEFT JOIN del_image_vote dvote '.
816
								'ON doi.id_image = dvote.ce_image AND dvote.ce_protocole = '.$this->parametres['protocole'] :
817
								''
818
										);
1332 aurelien 819
				$requeteLiaisons .= $this->chargerClauseWhere();
820
				$requeteLiaisons .= $this->getTri();
821
				$requeteLiaisons .= $this->gestionBdd->getLimitSql();
1366 aurelien 822
 
1438 raphael 823
				$retour = $this->bdd->recupererTous($requeteLiaisons . ' -- ' . __FILE__ . ':' . __LINE__);
1332 aurelien 824
				$total = $this->getFoundRows();
825
				$this->navigation->setTotal($total);
826
				return $retour;
1326 gduche 827
	}
828
 
829
 
830
	/**
831
	 * Retourner un tableau d'images formaté en fonction des liaisons trouvées
832
	 * @param $liaisons les liaisons de la table del_obs_images
833
	 * */
709 gduche 834
	private function chargerImage($liaisons) {
835
 
836
		$images = array();
837
		foreach ($liaisons as $liaison) {
736 gduche 838
			$idImage = $liaison['id_image'];
1326 gduche 839
 
1274 aurelien 840
			if($liaison['ce_utilisateur'] == 0) {
1326 gduche 841
				$liaison['prenom'] = $liaison['prenom_utilisateur'];
1274 aurelien 842
				$liaison['nom'] = $liaison['nom_utilisateur'];
843
			}
709 gduche 844
			// On enregistre l'ID de l'image pour n'effectuer qu'une seule requête par la suite
845
			$this->imageIds[] = $idImage;
800 aurelien 846
			$index = $liaison['id_image'].'-'.$liaison['id_observation'];
1025 aurelien 847
			$images[$index] = array('id_image' => $idImage, 'binaire.href' => $this->formaterLienImage($idImage),
1326 gduche 848
					'protocoles_votes' => array(),
849
					'mots_cles_texte' => $liaison['mots_cles_texte_image'], 'observation' => $this->formaterObservation($liaison));
709 gduche 850
		}
851
		return $images;
852
	}
853
 
854
	/**
1326 gduche 855
	 * Charger les votes pour chaque image
856
	 * */
709 gduche 857
	private function chargerVotes($images) {
1326 gduche 858
		$requeteVotes = 'SELECT v.*, p.* FROM '.
859
				$this->gestionBdd->formaterTable('del_image_vote', 'v').
860
				' INNER JOIN del_image_protocole p '.
861
				'ON v.ce_protocole = p.id_protocole '.
862
				$this->chargerClauseWhereVotes();
1438 raphael 863
		$resultatsVotes = $this->bdd->recupererTous($requeteVotes . ' -- ' . __FILE__ . ':' . __LINE__);
709 gduche 864
 
857 gduche 865
 
1326 gduche 866
		//TODO : faire une méthode formater vote
867
		$votes = $this->formaterVotes($resultatsVotes);
709 gduche 868
 
1326 gduche 869
		foreach ($images as $id => $image) {
870
			if (isset($votes[$image['id_image']])) {
871
				$images[$id]['protocoles_votes'] = $votes[$image['id_image']];
709 gduche 872
			}
1326 gduche 873
		}
874
 
709 gduche 875
		return $images;
876
	}
877
 
759 delphine 878
	private function chargerClauseWhereVotes() {
879
		if (sizeof($this->imageIds) > 0) {
880
			$chaineImageIds = implode(',', $this->imageIds);
760 delphine 881
			$where[] = 'v.ce_image  IN ('.$chaineImageIds.')';
759 delphine 882
		}
883
		if (isset($this->parametres['protocole'])) {
760 delphine 884
			$where[] = 'v.ce_protocole = '.$this->proteger($this->parametres['protocole']);
759 delphine 885
		}
1326 gduche 886
 
775 aurelien 887
		$where = (!empty($where)) ? 'WHERE '.implode(' AND ', $where) : '';
888
		return $where;
759 delphine 889
	}
890
 
1326 gduche 891
	/**************************************************************************************
892
	 *		    			FONCTION DE CONFIGURATION ET UTILITAIRES					  *
893
	***************************************************************************************/
894
	/**
895
	 * Enregistrer dans les variables de classe les paramètres et ressources
896
	 * @param $ressources
897
	 * @param $parametres de recherche
898
	 * */
899
	private function initialiserRessourcesEtParametres($ressources, $parametres) {
900
		$this->ressources = $ressources;
901
		$this->parametres = $parametres;
902
	}
903
 
904
	/**
905
	 * Configuration du service en fonction du fichier de config config_del.ini
906
	 * */
907
	public function configurer() {
908
		$this->mappingFiltre = $this->conteneur->getParametre('mapping_masque');
909
		$this->mappingObservation = $this->conteneur->getParametre('mapping_observation');
910
		$this->mappingVotes = $this->conteneur->getParametre('mapping_votes');
911
	}
912
 
913
	/**
914
	 * Vérifier que le service est bien configuré
915
	 * */
916
	public function verifierConfiguration() {
917
 
918
		$erreurs = array();
919
		$tableauImages = $this->conteneur->getParametre('images');
920
		if (empty($tableauImages)) {
921
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [images] ou celui-ci est vide ;';
922
		} else {
923
			if ($this->conteneur->getParametre('url_service') == null) {
924
				$erreurs[] = '- paramètre "url_service" manquant ;';
925
			}
926
 
927
			if ($this->conteneur->getParametre('url_images') == null) {
928
				$erreurs[] = '- paramètre "url_images" manquant ;';
929
			}
930
 
931
		}
932
 
933
		if (empty($this->mappingObservation)) {
934
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [mapping_observation] ou celui-ci est vide ;';
935
		} else {
936
			$champsMappingObs = array('id_observation', 'date_observation', 'date_transmission', 'famille', 'nom_sel', 'nom_sel_nn', 'nt',
937
					'ce_zone_geo', 'lieudit', 'station', 'milieu', 'ce_utilisateur', 'nom', 'prenom');
938
			foreach ($champsMappingObs as $champ) {
939
				if (!isset($this->mappingObservation[$champ])) {
940
					$erreurs[] = '- le mapping du champ "'.$champ.'" pour l\'observation est manquant ;';
941
				}
942
			}
943
		}
944
 
945
		if (empty($this->mappingFiltre)) {
946
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [mapping_masque] ou celui-ci est vide ;';
947
		} else {
948
			$champsMappingFiltre = array('famille', 'ns', 'nn', 'date', 'tag', 'commune');
949
			foreach ($champsMappingFiltre as $champ) {
950
				if (!isset($this->mappingFiltre[$champ])) {
951
					$erreurs[] = '- le mapping du champ "'.$champ.'" pour l\'observation est manquant ;';
952
				}
953
			}
954
		}
955
 
956
		$tris_possibles = $this->conteneur->getParametre('tris_possibles');
957
		if (empty($tris_possibles)) {
958
			$erreurs[] = '- le fichier de configuration ne contient pas le parametre tris_possibles ou celui-ci est vide ;';
959
		}
960
 
961
		if (!empty($erreurs)) {
962
			$e = 'Erreur lors de la configuration : '."\n";
963
			$e .= implode("\n", $erreurs);
964
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
965
		}
966
	}
967
 
968
	/**
969
	 * Verifier que les paramètres de tri sont bien autorisés et qu'ils sont au bon format.
970
	 */
971
	private function verifierParametresTri() {
972
 
973
		$erreurs = array();
974
		$tris_possibles = $this->conteneur->getParametre('tris_possibles');
975
		$tris_possibles_tableau = explode(',', $tris_possibles);
976
		if(isset($this->parametres['tri']) && !in_array($this->parametres['tri'], $tris_possibles_tableau)) {
977
			$erreurs[] = '- le type de tri demandé est incorrect, les valeurs possibles sont '.$tris_possibles.' ;';
978
		}
979
 
980
		if(isset($this->parametres['tri']) && $this->parametres['tri'] == "votes") {
981
			if(!isset($this->parametres['protocole']) || !is_numeric($this->parametres['protocole'])) {
982
				$erreurs[] = '- Le paramètre protocole est obligatoire en cas de tri par vote et doit être un entier ;';
983
			}
984
		}
985
 
986
		$directions_tri = array('asc', 'desc');
987
		if(isset($this->parametres['ordre']) && !in_array($this->parametres['ordre'], $directions_tri)) {
988
			$erreurs[] = '- la direction du tri demandé est incorrecte, les valeurs supportées sont asc ou desc ;';
989
		}
990
 
991
		if (!empty($erreurs)) {
992
			$e = 'Erreur lors de l\'analyse des parametres du tri : '."\n";
993
			$e .= implode("\n", $erreurs);
994
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
995
		}
996
	}
1345 aurelien 997
 
998
	private function verifierParametreFormatRetour() {
999
		$erreurs = array();
1000
		$formats_possibles_str = $this->conteneur->getParametre('formats_possibles');
1001
		$formats_possibles = explode(',',$formats_possibles_str);
1326 gduche 1002
 
1345 aurelien 1003
		if(isset($this->parametres['format']) && !in_array($this->parametres['format'], $formats_possibles)) {
1004
			$erreurs[] = "- le format d'image demandé n'est pas supporté ; Les format supportés sont : ".$formats_possibles_str;
1005
		}
1006
 
1007
		if (!empty($erreurs)) {
1008
			$e = 'Erreur lors de l\'analyse du format de retour demandé : '."\n";
1009
			$e .= implode("\n", $erreurs);
1010
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
1011
		}
1012
	}
1013
 
1014
	private function initialiserFormatRetour() {
1015
		$this->formatRetour = isset($this->parametres['format']) ? $this->parametres['format'] : $this->formatRetour;
1016
	}
1017
 
1326 gduche 1018
	/**
1019
	 * Initialiser les variables de tri depuis les paramètres
1020
	 * */
1021
	private function initialiserTri() {
1022
		$this->tri = isset($this->parametres['tri']) ? $this->parametres['tri'] : $this->tri;
1023
		$this->directionTri = isset($this->parametres['ordre']) ? $this->parametres['ordre'] : $this->directionTri;
1024
	}
1025
 
1026
	/** Pour eviter les requêtes trop gourmandes, on supprime les caractères passe-partout
1027
	 * @param les paramètres de l'application
1028
	 * */
1029
	public function nettoyerParametres($parametres) {
1030
		$parametresRetour = array();
1031
		foreach ($parametres as $cle => $valeur) {
1032
			$valSansPourcent = trim($valeur, "% ");
1033
			if ($valSansPourcent != '') {
1034
				$parametresRetour[$cle] = $valeur;
1035
			}
1036
		}
1037
 
1038
		return $parametresRetour;
1039
	}
1040
 
1041
	/**
1042
	 * Nettoyer les jokers
1043
	 * @param la valeur du masque
1044
	 * */
1045
	private function remplacerParJokerCaractere($valeurMasque) {
1046
		return str_replace(array('-',' '), '_', $valeurMasque);
1047
	}
1048
 
1049
	//TODO: déplacer les fonctions ci dessus et dessous dans une classe
1050
	// utilitaire
1051
 
1052
	/**
1053
	 * Supprimer les accents des chaines de caractères
1054
	 * */
1055
	function supprimerAccents($str, $charset='utf-8')
1056
	{
1057
		$str = htmlentities($str, ENT_NOQUOTES, $charset);
1058
 
1059
		$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
1060
		$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. '&oelig;'
1061
		$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères
1062
 
1063
		return $str;
1064
	}
1065
 
1066
	/**
1067
	 * Normaliser en supprimant les accents et en mettant en minuscule
1068
	 * @param $mot_cle le mot recherché
1069
	 * */
1070
	private function normaliserMotCle($mot_cle) {
1071
		return mb_strtolower($this->supprimerAccents(trim($mot_cle)));
1072
	}
1073
 
1074
	/**
1075
	 * Récupérer le numéro du département d'un fichier de configuration
1076
	 * */
1077
	private function obtenirIdDepartement($nomDpt) {
1078
 
1079
		$nomDpt = $this->supprimerAccents($nomDpt);
1080
		$nomDpt = strtolower(str_replace(' ','-',$nomDpt));
1081
 
1082
		$idDpt = $this->conteneur->getParametre($nomDpt);
1083
		if($idDpt == null || $idDpt == ' ') {
1084
			$idDpt = ' ';
1085
		}
1086
		return $idDpt;
1087
	}
1088
 
1089
 
1090
	/**
1091
	 * Obtenir le type de requête à exécuter en fonction des paramètres de recherche
1092
	 * @param $parametres les paramètres de l'application
1093
	 * */
1094
	private function getTypeRequete($parametres) {
1095
 
1096
 
1097
		$typeRequete = 'simple';
1098
 
1099
		// Dans ce cas précis, les informations concernant le depart, la limite ou l'ordre ne
1100
		// rentre pas en compte dans le type de requête ; ce ne sont que des compléments.
1101
		unset($parametres['navigation.depart']);
1102
		unset($parametres['navigation.limite']);
1103
		unset($parametres['ordre']);
1104
 
1105
		// En revanche, chaque masque est associé à un type de requête particulier.
1366 aurelien 1106
		$masquesObservation = array('masque', 'masque.departement', 'masque.ns', 'masque.genre', 'masque.date', 'masque.commune', 'masque.famille', 'masque.auteur', 'masque.nn', 'masque.referentiel');
1326 gduche 1107
		$masquesImage = array('masque', 'masque.tag');
1108
 
1109
		// Le type de requête est défini par les tables qu'il doit inclure (observation, image, ou les deux)
1110
		$requeteSimple = false;
1111
		$pourObservation = false;
1112
		$pourImage = false;
1113
 
1114
		// S'il n'y a aucun paramètre, on lance une requête simple
1115
		if (empty($parametres)) {
1116
			$requeteSimple = true;
1117
		}
1118
 
1119
		// Si l'un des masques demandé concerne l'observation
1120
		foreach ($masquesObservation as $masque) {
1121
			if (isset($parametres[$masque])) {
1122
				$pourObservation = true;
1123
				break;
1124
			}
1125
		}
1126
 
1127
		// Si l'un des masques demandé concerne les images
1128
		foreach ($masquesImage as $masque) {
1129
			if (isset($parametres[$masque])) {
1130
				$pourImage = true;
1131
				break;
1132
			}
1133
		}
1134
 
1135
		// Selon les tri
1136
		if (isset($parametres['tri'])) {
1137
			switch ($parametres['tri']) {
1138
				case 'votes' :
1139
				case 'tags' :
1140
					$pourImage = true;
1141
					break;
1142
				default : //case 'date_observation' :
1143
					if (sizeof($parametres) > 1) {
1144
						$pourObservation = true;
1145
					}
1146
			}
1147
		}
1148
 
1149
		// Vérifier la combinaison des booléens pour en déduire le type de requête
1150
		if ($pourObservation && $pourImage) {
1151
			$typeRequete = 'obs-images';
1152
		} else {
1153
			if ($pourImage) {
1154
				$typeRequete = 'images';
1155
			} else if ($pourObservation) {
1156
				$typeRequete = 'obs';
1157
			} else { // if ($requeteSimple)
1158
				$typeRequete = 'simple';
1159
			}
1160
		}
1161
 
1162
		return $typeRequete;
1163
	}
1164
 
1165
 
1166
	private function doitJoindreTableVotes() {
1167
		return ($this->tri == 'votes');
1168
	}
1169
 
1170
	private function doitJoindreTableTags() {
1171
		return ($this->tri == 'tags');
1172
	}
1173
 
709 gduche 1174
	/*-------------------------------------------------------------------------------
1175
								FORMATER ET METTRE EN FORME
1176
	--------------------------------------------------------------------------------*/
1177
 
1178
	/**
1179
	*  Formater une observation depuis une ligne liaison
1180
	*  @param $liaison liaison issue de la recherche
1181
	*  @return $observation l'observation mise en forme
1182
	* */
1183
	private function formaterObservation($liaison) {
1184
		$observation = array();
1185
		foreach ($this->mappingObservation as $nomOriginal => $nomFinal) {
1186
			$observation[$nomFinal] = $liaison[$nomOriginal];
1187
		}
1188
 
1189
		return $observation;
1190
	}
1191
 
1192
	/**
1193
	*  Formater une observation depuis une ligne liaison
1194
	*  @param $liaison liaison issue de la recherche
1195
	*  @return $observation l'observation mise en forme
1196
	* */
1197
	private function formaterVotes($votes) {
1198
		$retour = array();
1199
		foreach ($votes as $vote) {
759 delphine 1200
			$retour_vote = array();
1201
			foreach ($vote as $param=>$valeur) {
760 delphine 1202
				if (strpos($this->mappingVotes[$param], 'protocole.') === 0) {
1203
					$retour_protocole[$this->mappingVotes[$param]] = $valeur;
1204
				} else {
1205
					$retour_vote[$this->mappingVotes[$param]] = $valeur;
1206
				}
759 delphine 1207
			}
760 delphine 1208
			if (!isset($retour[$vote['ce_image']][$vote['ce_protocole']])) {
1209
				$retour[$vote['ce_image']][$vote['ce_protocole']] = $retour_protocole;
1210
			}
1211
			$retour[$vote['ce_image']][$vote['ce_protocole']]['votes'][$vote['id_vote']] = $retour_vote;
709 gduche 1212
		}
1213
 
1214
		return $retour;
1215
	}
1216
 
1217
	/**
1218
	 * Formater le lien de l'image en fonction du fichier de config et de l'identifiant de l'image
1219
	 * */
1220
	private function formaterLienImage($idImage) {
1221
		$idImage = sprintf('%09s', $idImage);
719 gduche 1222
		$url = $this->conteneur->getParametre('url_images');
1345 aurelien 1223
		$urlImage = sprintf($url, $idImage, $this->formatRetour);
709 gduche 1224
		return $urlImage;
1225
	}
719 gduche 1226
 
1227
	private function proteger($valeur) {
1228
		if (is_array($valeur)) {
1229
			return $this->bdd->protegerTableau($valeur);
1230
		} else {
1231
			return $this->bdd->proteger($valeur);
709 gduche 1232
		}
1233
	}
1234
}
1235
?>