Subversion Repositories eFlore/Applications.del

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
720 gduche 1
<?php
2
// declare(encoding='UTF-8');
3
/**
737 gduche 4
	* Le web service observations récupère toutes les observations et, pour chacune d'elle, les
5
	* images qui lui sont associées.
720 gduche 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 $
737 gduche 15
 * @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=ApiIdentiplante01Observations
720 gduche 16
 */
17
 
18
class Observations {
19
 
20
	private $conteneur;
726 gduche 21
	private $navigation;
22
	private $masque;
737 gduche 23
	private $gestionBdd;
24
	private $bdd;
720 gduche 25
 
26
	public function __construct(Conteneur $conteneur = null) {
27
		$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
737 gduche 28
		$this->conteneur->chargerConfiguration('config_departements.ini');
726 gduche 29
		$this->navigation = $conteneur->getNavigation();
30
		$this->masque = $conteneur->getMasque();
737 gduche 31
		$this->gestionBdd = $conteneur->getGestionBdd();
32
		$this->bdd = $this->gestionBdd->getBdd();
720 gduche 33
	}
34
 
35
	/**
36
	 * Méthode principale de la classe.
37
	 * Lance la récupération des images dans la base et les place dans un objet ResultatService
38
	 * pour l'afficher.
39
	 * @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
40
	 * @param array $parametres les paramètres situés après le ? dans l'url
41
	 * */
42
	public function consulter($ressources, $parametres) {
43
 
44
		// Gestion des configuration du script
45
		$this->configurer();
46
		$this->verifierConfiguration();
47
 
48
		// Lancement du service
49
		$liaisons = $this->chargerLiaisons();
737 gduche 50
		$total = $this->compterObservations();
726 gduche 51
		$this->navigation->setTotal($total);
737 gduche 52
		$images = $this->chargerObservations($liaisons);
53
		$images = $this->chargerImages($images);
720 gduche 54
 
55
		// Mettre en forme le résultat et l'envoyer pour affichage
56
		$resultat = new ResultatService();
57
		$resultat->corps = array('entete' => $this->conteneur->getEntete(), 'resultats' => $images);
58
		return $resultat;
59
	}
60
 
61
	/*-------------------------------------------------------------------------------
62
	 							CONFIGURATION DU SERVICE
63
	 --------------------------------------------------------------------------------*/
64
	/**
65
	 * Configuration du service en fonction du fichier de config config_del.ini
66
	 * */
67
	public function configurer() {
68
		$this->mappingFiltre = $this->conteneur->getParametre('mapping_masque');
69
		$this->mappingObservation = $this->conteneur->getParametre('mapping_observation');
70
	}
71
 
72
	/**
73
	 * Vérifier que le service est bien configuré
74
	 * */
75
	public function verifierConfiguration() {
737 gduche 76
 
720 gduche 77
		$erreurs = array();
737 gduche 78
		$tableauImages = $this->conteneur->getParametre('images');
79
		if (empty($tableauImages)) {
720 gduche 80
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [images] ou celui-ci est vide ;';
81
		} else {
737 gduche 82
			if ($this->conteneur->getParametre('url_service') == null) {
720 gduche 83
				$erreurs[] = '- paramètre "url_service" manquant ;';
84
			}
85
 
737 gduche 86
			if ($this->conteneur->getParametre('url_images') == null) {
720 gduche 87
				$erreurs[] = '- paramètre "url_images" manquant ;';
88
			}
89
 
90
		}
91
 
92
		if (empty($this->mappingObservation)) {
93
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [mapping_observation] ou celui-ci est vide ;';
94
		} else {
95
			$champsMappingObs = array('id_observation', 'date_observation', 'date_transmission', 'famille', 'nom_sel', 'nom_sel_nn', 'nt',
737 gduche 96
								'ce_zone_geo', 'zone_geo', 'lieudit', 'station', 'courriel', 'ce_utilisateur', 'nom', 'prenom');
97
 
720 gduche 98
			foreach ($champsMappingObs as $champ) {
99
				if (!isset($this->mappingObservation[$champ])) {
100
					$erreurs[] = '- le mapping du champ "'.$champ.'" pour l\'observation est manquant ;';
101
				}
102
			}
103
		}
104
 
105
		if (empty($this->mappingFiltre)) {
106
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [mapping_masque] ou celui-ci est vide ;';
107
		} else {
108
			$champsMappingFiltre = array('famille', 'ns', 'nn', 'date', 'tag', 'commune');
109
			foreach ($champsMappingFiltre as $champ) {
110
				if (!isset($this->mappingFiltre[$champ])) {
111
					$erreurs[] = '- le mapping du champ "'.$champ.'" pour l\'observation est manquant ;';
112
				}
113
			}
114
		}
115
 
116
		if (!empty($erreurs)) {
117
			$e = 'Erreur lors de la configuration : '."\n";
118
			$e .= implode("\n", $erreurs);
119
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
737 gduche 120
		}
720 gduche 121
	}
122
 
123
 
124
 
125
	/**
126
	 * Obtenir une chaine de caractère concaténant nom et prénom séparé par une virgule
127
	 * @param String $auteurId l'identifiant de l'auteur
128
	 * @return String la chaine de concaténation
129
	 * */
130
	private function getChaineNomPrenom($auteurId) {
131
		$nomPrenom = explode(' ', $auteurId);
132
		$nomPrenom = $this->proteger($nomPrenom);
133
		$chaineNomPrenom = implode(', ', $nomPrenom);
134
		return $chaineNomPrenom;
135
	}
136
 
137
	/**
138
	* Charger la clause WHERE en fonction des paramètres de masque
139
	* */
140
	private function chargerClauseWhere() {
141
		$where = array();
737 gduche 142
		$tableauMasque = $this->masque->getMasque();
143
		// FIXME : Les communes avec une apostrophe (ex: saint michel d'euzet) arrivent dans les paramètres sans l'apostrophe
144
		if (!empty($tableauMasque)) {
145
			foreach($tableauMasque as $idMasque => $valeurMasque) {
146
 
147
				$idMasque = str_replace('masque.', '', $idMasque);
148
				switch ($idMasque) {
149
					// nom du masque => nom BDD
150
					case 'auteur' :
151
						$auteurId = $this->masque->getMasque('auteur');
152
						if (is_numeric($auteurId)) {
153
							$where[] = ' ce_utilisateur = '.$auteurId;
154
						} else {
155
							if (strpos($auteurId, '@') === false) {
156
								$chaineNomPrenom = $this->getChaineNomPrenom($auteurId);
157
								$where[] = '((nom IN ('.$chaineNomPrenom.')) OR (prenom IN ('.$chaineNomPrenom.')))';
158
							} else {
159
								$where[] = " courriel LIKE ".$this->proteger($this->masque->getMasque('auteur').'%')." ";
160
							}
161
						}
162
						break;
720 gduche 163
 
737 gduche 164
						//TODO : gérer le format de la date ?
165
						// rechercher sur LIKE DATE % ?
166
						// TODO : recherche sur JOUR MOIS ou ANNEE
167
					case 'departement' :
168
						$dept = $valeurMasque;
169
						if (is_numeric($dept)) {
744 gduche 170
							$dept = sprintf('%02s', $dept);
171
							$dept = sprintf("%-'_5s", $dept);
172
							$where[] = " ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$dept);
720 gduche 173
						} else {
737 gduche 174
 
175
							//FIXME : et les apostrophes dans les départements ?
176
 
177
							$deptId = $this->conteneur->getParametre($dept);
178
							if ($deptId != null) {
179
								$where[] = " ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$deptId.'%');
180
							}
720 gduche 181
						}
737 gduche 182
						break;
183
					case 'genre' :
744 gduche 184
						$where[] = ' '.$this->mappingFiltre['ns'].' LIKE '.$this->proteger('%'.$valeurMasque.'% %');
737 gduche 185
						break;
186
					case 'tag' :
744 gduche 187
						$where[] = " mots_cles_texte LIKE ".$this->proteger($valeurMasque);
737 gduche 188
						break;
744 gduche 189
					case 'nn' :
190
						$where[] = ' '.$this->mappingFiltre['nn'].'  = '.$this->proteger($valeurMasque);
740 gduche 191
						break;
737 gduche 192
					default:
744 gduche 193
						$where[] = ' '.$this->mappingFiltre[$idMasque].' LIKE '.$this->proteger('%'.$valeurMasque.'%');
737 gduche 194
				}
195
			}
720 gduche 196
		}
197
 
198
		if (!empty($where)) {
199
			return ' WHERE '.implode('AND', $where);
200
		} else {
201
			return;
202
		}
203
	}
204
 
205
	/*-------------------------------------------------------------------------------
206
								CHARGEMENT DES IMAGES
207
	--------------------------------------------------------------------------------*/
208
	/**
209
	* Chargement depuis la bdd de toutes les liaisons entre images et observations
210
	* */
211
	private function chargerLiaisons() {
212
 
213
		$requeteLiaisons = 'SELECT SQL_CALC_FOUND_ROWS * '.
737 gduche 214
						   'FROM '.$this->gestionBdd->formaterTable('del_observation', 'dob').
215
						   'INNER JOIN '.$this->gestionBdd->formaterTable('del_obs_images', 'doi').
216
						   'ON doi.id_observation = dob.id_observation '.
720 gduche 217
						   'INNER JOIN del_utilisateur du '.
737 gduche 218
						   'ON du.id_utilisateur = doi.id_utilisateur ';
720 gduche 219
		$requeteLiaisons .= $this->chargerClauseWhere();
737 gduche 220
		$requeteLiaisons .=  ' GROUP BY doi.id_observation';
221
		$requeteLiaisons .= ' ORDER BY date_transmission DESC ';
222
		$requeteLiaisons .= $this->gestionBdd->getLimitSql();
223
 
720 gduche 224
		return $this->bdd->recupererTous($requeteLiaisons);
225
	}
226
 
227
	/**
228
	* Compter le nombre total d'images dans la base pour affichage dans entete.
229
	* */
737 gduche 230
	private function compterObservations() {
720 gduche 231
		$requete = 'SELECT FOUND_ROWS() AS nbre ';
232
		$resultats = $this->bdd->recuperer($requete);
233
		return (int) $resultats['nbre'];
234
	}
235
 
236
	/**
237
	* Retourner un tableau d'images formaté en fonction des liaisons trouvées
238
	* @param $liaisons les liaisons de la table del_obs_images
239
	* */
737 gduche 240
	private function chargerObservations($liaisons) {
720 gduche 241
 
737 gduche 242
		$observations = array();
720 gduche 243
		foreach ($liaisons as $liaison) {
737 gduche 244
			$idObs = $liaison[$this->mappingObservation['id_observation']];
720 gduche 245
 
737 gduche 246
			$observation = array();
247
			foreach ($this->mappingObservation as $id => $champ) {
248
				$observation[$champ] = $liaison[$id];
249
			}
250
			$observation['images'] = array();
251
			$observations[$idObs] = $observation;
720 gduche 252
		}
737 gduche 253
		return $observations;
720 gduche 254
	}
255
 
256
	/**
737 gduche 257
	 * Sélectionner toutes les images de chaque observation
258
	 * @param array $observations la liste des observations
259
	 * */
260
	public function chargerImages($observations) {
720 gduche 261
 
737 gduche 262
		foreach ($observations as $id => $observation) {
720 gduche 263
 
737 gduche 264
			$requeteImages = 'SELECT * FROM '. $this->gestionBdd->formaterTable('del_obs_images', 'doi').
265
							 'INNER JOIN '.$this->gestionBdd->formaterTable('del_image', 'di').
266
							 'ON doi.id_image = di.id_image '.
267
							 'WHERE doi.id_observation = '.$observation['id_observation'];
720 gduche 268
 
737 gduche 269
			$images = $this->bdd->recupererTous($requeteImages);
270
			$images = $this->formaterImages($images);
271
			$observations[$id]['images'] = $images;
720 gduche 272
		}
273
 
737 gduche 274
		return $observations;
720 gduche 275
	}
276
 
737 gduche 277
 
278
 
720 gduche 279
	/*-------------------------------------------------------------------------------
280
								FORMATER ET METTRE EN FORME
281
	--------------------------------------------------------------------------------*/
282
 
283
	/**
737 gduche 284
	 * Formater les images d'une observation
285
	 * @param array $images les images de l'observation
286
	 * */
287
	private function formaterImages($images) {
288
		$imagesRetour = array();
289
		foreach ($images as $image) {
290
			$imageCourante = array();
291
			$imageCourante['id_image'] = $image['id_image'];
292
			$imageCourante['date'] = $image['date_prise_de_vue'];
293
			$imageCourante['binaire.href'] = $this->formaterLienImage($image['id_image']);
294
			$imageCourante['hauteur'] = $image['hauteur'];
295
			$imageRetour['largeur'] = $image['largeur'];
296
 
297
			$imagesRetour[] = $imageCourante;
298
		}
299
 
300
		return $imagesRetour;
301
	}
302
 
303
	/**
720 gduche 304
	*  Formater une observation depuis une ligne liaison
305
	*  @param $liaison liaison issue de la recherche
306
	*  @return $observation l'observation mise en forme
307
	* */
308
	private function formaterObservation($liaison) {
309
		$observation = array();
310
 
311
		foreach ($this->mappingObservation as $nomOriginal => $nomFinal) {
312
			$observation[$nomFinal] = $liaison[$nomOriginal];
313
		}
314
 
315
		return $observation;
316
	}
317
 
318
	/**
319
	*  Formater une observation depuis une ligne liaison
320
	*  @param $liaison liaison issue de la recherche
321
	*  @return $observation l'observation mise en forme
322
	* */
323
	private function formaterVotes($votes) {
324
		$retour = array();
325
		foreach ($votes as $vote) {
326
			$idImage = $vote['ce_image'];
327
			$id = $vote['id_vote_image'];
328
			$id_protocole = $vote['ce_protocole'];
329
			$auteur_id = $vote['ce_utilisateur'];
330
			$valeur = $vote['valeur_vote'];
331
			$date = $vote['date_vote_image'];
332
 
333
			$retour[$idImage]['valeur'] = $valeur;
334
			$retour[$idImage]['protocole'] = $id_protocole;
335
			$retour[$idImage]['auteur_id'] = $auteur_id;
336
			$retour[$idImage]['date'] = $auteur_id;
337
		}
338
 
339
		return $retour;
340
	}
341
 
342
	/**
343
	 * Formater le lien de l'image en fonction du fichier de config et de l'identifiant de l'image
344
	 * */
345
	private function formaterLienImage($idImage) {
346
		$idImage = sprintf('%09s', $idImage);
347
		$url = $this->conteneur->getParametre('url_images');
348
		$urlImage = str_replace('%s', $idImage, $url);
349
		return $urlImage;
350
	}
351
 
352
	private function proteger($valeur) {
353
		if (is_array($valeur)) {
354
			return $this->bdd->protegerTableau($valeur);
355
		} else {
356
			return $this->bdd->proteger($valeur);
357
		}
358
	}
359
}
360
?>