Subversion Repositories eFlore/Applications.del

Rev

Rev 1472 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
751 delphine 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
 
1472 aurelien 18
class VotesImage {
751 delphine 19
 
20
	private $imageIds = array();
21
	private $conteneur;
22
	private $navigation;
23
	private $masque;
829 aurelien 24
	protected $gestionBdd;
25
	protected $bdd;
758 delphine 26
	private $ressources;
27
	private $parametres;
751 delphine 28
 
29
	public function __construct(Conteneur $conteneur = null) {
30
		$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
31
		$this->conteneur->chargerConfiguration('config_votes.ini');
796 aurelien 32
		$this->conteneur->chargerConfiguration('config_mapping_votes.ini');
751 delphine 33
		$this->navigation = $conteneur->getNavigation();
34
		$this->masque = $conteneur->getMasque();
35
		$this->gestionBdd = $conteneur->getGestionBdd();
36
		$this->bdd = $this->gestionBdd->getBdd();
37
	}
38
 
39
	/**
40
	 * Méthode principale de la classe.
41
	 * Lance la récupération des images dans la base et les place dans un objet ResultatService
42
	 * pour l'afficher.
43
	 * @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
44
	 * @param array $parametres les paramètres situés après le ? dans l'url
45
	 * */
46
	public function consulter($ressources, $parametres) {
47
		// Gestion des configuration du script
48
		$this->ressources = $ressources;
758 delphine 49
		$this->parametres = $parametres;
751 delphine 50
		$this->configurer();
51
		$this->verifierConfiguration();
52
 
53
		// Lancement du service
54
		$votes = $this->chargerVotes();
55
		$total = $this->compterVotes();
56
		$this->navigation->setTotal($total);
57
 
58
		// Mettre en forme le résultat et l'envoyer pour affichage
59
		$resultat = new ResultatService();
60
		$resultat->corps = array('entete' => $this->conteneur->getEntete(), 'resultats' => $votes);
61
		return $resultat;
62
	}
63
 
782 delphine 64
	public function ajouter($ressources, $parametres) {
829 aurelien 65
 
66
		$this->verifierParametresAjoutModif($ressources, $parametres);
67
 
68
		$insertion = 'INSERT INTO del_image_vote '.
69
						'(ce_image, ce_protocole, ce_utilisateur, valeur, date) '.
70
						'VALUES ('.
71
							$this->proteger($ressources[0]).','.
72
							$this->proteger($parametres['protocole']).','.
73
							$this->proteger($parametres['utilisateur']).','.
74
							$this->proteger($parametres['valeur']).', '.
75
						'NOW()'.
76
						');';
1472 aurelien 77
 
829 aurelien 78
		$resultat = $this->bdd->requeter($insertion);
79
		if ($resultat == false) {
80
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
782 delphine 81
		} else {
1472 aurelien 82
			$retour = $this->bdd->recupererIdDernierAjout();
83
 
84
			$resultat = new ResultatService();
85
			$resultat->corps = array('id_vote' => $retour);
86
 
1428 raphael 87
			self::updateStats($this->bdd, $ressources[0],$parametres['protocole']);
1472 aurelien 88
 
89
			return $resultat;
782 delphine 90
		}
91
	}
92
 
829 aurelien 93
	public function modifier($ressources, $parametres) {
94
 
95
		$this->verifierParametresAjoutModif($ressources, $parametres);
96
 
97
		//TODO: est il nécessaire de tester si ça existe et renoyer une erreur 404
98
		// si l'on vote ? Cela peut ralentir considérablement les choses
99
		// une contrainte d'unicité sur le triplet image, protocole, vote existe,
100
		// ça suffira pour provoquer une erreur 500
101
		$modification = 'UPDATE del_image_vote '.
102
							'SET valeur = '.$this->proteger($parametres['valeur']).', '.
103
							'    date = NOW() '.
104
						'WHERE '.
105
							'ce_image = '.$this->proteger($ressources[0]).' AND '.
106
							'ce_protocole = '.$this->proteger($parametres['protocole']).' AND '.
107
							'ce_utilisateur = '.$this->proteger($parametres['utilisateur']).' ';
108
		$resultat = $this->bdd->requeter($modification);
109
		if ($resultat == false) {
110
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
111
		} else {
1428 raphael 112
			self::updateStats($this->bdd, $ressources[0],$parametres['protocole']);
829 aurelien 113
			RestServeur::envoyerEnteteStatutHttp(RestServeur::HTTP_CODE_OK);
114
		}
115
	}
116
 
1472 aurelien 117
	public function supprimer($ressources) {
118
 
119
		$id_image = $ressources[0];
120
		$id_vote = $ressources[2];
121
		$id_vote_p = $this->proteger($id_vote);
122
 
123
		$requete_infos_vote = 'SELECT * FROM del_image_vote '.
124
		                'WHERE id_vote = '.$id_vote_p;
125
 
126
		$infos_vote = $this->bdd->recuperer($requete_infos_vote);
127
		if ($infos_vote == false) {
128
			throw new Exception("Aucun vote ne correspond à cet identifiant", RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
129
		}
130
 
131
		$controle_acces = new ControleAcces($this->conteneur);
132
		$utilisateur = 	$controle_acces->getInfosUtilisateurConnecte();
133
 
134
		if($utilisateur['id_utilisateur'] != $infos_vote['ce_utilisateur'] &&
135
			$controle_acces->getIdAnonymeTemporaire() != $infos_vote['ce_utilisateur']) {
136
			throw new Exception("Vous n'êtes pas autorisé à supprimer ce vote",
137
			RestServeur::HTTP_CODE_ACCES_NON_AUTORISE);
138
		}
139
 
140
		$suppression = 'DELETE FROM del_image_vote '.
141
							'WHERE id_vote = '.$id_vote_p;
142
 
143
		$resultat = $this->bdd->requeter($suppression);
144
		if ($resultat == false) {
145
			throw new Exception("Impossible de supprimer le vote", RestServeur::HTTP_CODE_ERREUR);
146
		} else {
147
			self::updateStats($this->bdd, $ressources[0],$infos_vote['ce_protocole']);
148
		}
149
	}
150
 
1428 raphael 151
	static function updateStats($db, $id_image, $id_proto) {
152
		$id_image = intval($id_image);
153
		$id_proto = intval($id_proto);
154
		if(!$id_image || !$id_proto) throw new Exception("Ne peut mettre à jour les statistiques de vote",
155
														 RestServeur::HTTP_CODE_ERREUR);
156
		/* REPLACE ... SELECT: réinitalise les champs non-défini (MySQL 5.1)
157
		   REPLACE ... SET a=b, c=d: idem ou plusieurs requête
158
		   Du coup il faut récupérer les données actuelles mais REPLACE ne le permet pas
159
		   (http://dev.mysql.com/doc/refman/5.5/en/replace.html :
160
		   You cannot refer to values from the current row and use them in the new row.)
161
		   D'où INSERT ... ON DUPLICATE KEY UPDATE. Notons que VALUES() récupère la valeur
162
		   *associée* au champ passé en paramètre, c'est à dire VALUES(moyenne) == divo.moyenne */
163
		$db->requeter(sprintf('INSERT INTO del_image_stat (ce_image, ce_protocole, moyenne, nb_votes)'.
164
							  ' SELECT ce_image, ce_protocole, AVG(valeur) AS moyenne, COUNT(valeur) AS nb_votes'.
165
							  ' FROM del_image_vote divo'.
166
							  ' WHERE ce_image = %d AND ce_protocole = %d GROUP BY ce_image, ce_protocole'.
167
							  ' ON DUPLICATE KEY UPDATE moyenne = VALUES(moyenne), nb_votes = VALUES(nb_votes)',
168
							  $id_image, $id_proto));
169
 
170
 
171
	}
172
 
751 delphine 173
	/*-------------------------------------------------------------------------------
174
	 							CONFIGURATION DU SERVICE
175
	 --------------------------------------------------------------------------------*/
176
	/**
177
	 * Configuration du service en fonction du fichier de config config_del.ini
178
	 * */
179
	public function configurer() {
180
		$this->mappingFiltre = $this->conteneur->getParametre('mapping_masque');
181
		$this->mappingVotes = $this->conteneur->getParametre('mapping_votes');
182
	}
183
 
184
	/**
185
	 * Vérifier que le service est bien configuré
186
	 * */
187
	public function verifierConfiguration() {
188
 
189
		$erreurs = array();
190
		$tableauImages = $this->conteneur->getParametre('images');
191
		if (empty($tableauImages)) {
192
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [images] ou celui-ci est vide ;';
193
		} else {
194
			if ($this->conteneur->getParametre('url_service') == null) {
195
				$erreurs[] = '- paramètre "url_service" manquant ;';
196
			}
197
		}
198
 
199
		if (empty($this->mappingVotes)) {
759 delphine 200
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [mapping_votes] ou celui-ci est vide ;';
751 delphine 201
		} else {
202
			$champsMappingObs = array('ce_protocole','id_vote','valeur','ce_image', 'ce_utilisateur', 'nom', 'prenom');
203
			foreach ($champsMappingObs as $champ) {
204
				if (!isset($this->mappingVotes[$champ])) {
759 delphine 205
					$erreurs[] = '- le mapping du champ "'.$champ.'" pour le vote est manquant ;';
751 delphine 206
				}
207
			}
208
		}
209
 
210
 
211
		if (!empty($erreurs)) {
212
			$e = 'Erreur lors de la configuration : '."\n";
213
			$e .= implode("\n", $erreurs);
214
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
215
		}
216
	}
829 aurelien 217
 
218
 
219
	public function verifierParametresAjoutModif($ressources, $parametres) {
220
		$erreurs = array();
221
		if (!is_numeric($ressources[0])) {
222
			$erreurs[] = '- le paramètre indiquant l\'identifiant de l\'image doit être numérique ;';
223
		}
224
 
225
		if (!isset($parametres['utilisateur'])) {
226
			$erreurs[] = '- paramètre "utilisateur" manquant ;';
227
		}
228
 
229
		if (!isset($parametres['protocole'])) {
230
			$erreurs[] = '- paramètre "id_protocole" manquant ;';
231
		} else {
232
			if (!is_numeric($parametres['protocole'])) {
233
				$erreurs[] = '- le paramètre "protocole" doit être numérique ;';
234
			}
235
		}
236
 
237
		if (!isset($parametres['valeur'])) {
238
			$erreurs[] = '- paramètre "valeur" manquant ;';
239
		} else {
240
			if (!is_numeric($parametres['valeur'])) {
241
				$erreurs[] = '- le paramètre "valeur" doit être numérique ;';
242
			}
243
		}
244
 
245
		if (!empty($erreurs)) {
246
			$e = 'Erreur lors de la configuration : '."\n";
247
			$e .= implode("\n", $erreurs);
248
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
249
		}
250
	}
751 delphine 251
 
1472 aurelien 252
	public function verifierParametresSuppression($ressources, $parametres) {
253
		$erreurs = array();
254
		if (!is_numeric($ressources[0])) {
255
			$erreurs[] = '- le paramètre indiquant l\'identifiant de l\'image doit être numérique ;';
256
		}
257
 
258
		/*if (!is_numeric($parametres['id_protocole'])) {
259
			$erreurs[] = '- le paramètre indiquant l\'identifiant du vote doit être numérique ;';
260
		}*/
261
 
262
		if (!empty($erreurs)) {
263
			$e = 'Erreur lors de la configuration : '."\n";
264
			$e .= implode("\n", $erreurs);
265
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
266
		}
267
	}
268
 
751 delphine 269
	/**
270
	* Charger la clause WHERE en fonction des paramètres de masque
271
	* */
272
	private function chargerClauseWhere() {
758 delphine 273
		$where[] = 'WHERE ce_image = '.$this->proteger($this->ressources[0]);
786 delphine 274
		if (isset($this->parametres['protocole'])) {
275
			$where[] = 'ce_protocole = '.$this->proteger($this->parametres['protocole']);
758 delphine 276
		}
277
		return implode(' AND ', $where);
829 aurelien 278
	}
751 delphine 279
	/*-------------------------------------------------------------------------------
280
								CHARGEMENT DES IMAGES
281
	--------------------------------------------------------------------------------*/
282
	/**
283
	* Charger les votes pour chaque image
284
	* */
285
	private function chargerVotes() {
286
		$requeteVotes = 'SELECT * FROM '.
287
						$this->gestionBdd->formaterTable('del_image_vote').
288
						$this->chargerClauseWhere();
289
		$resultatsVotes = $this->bdd->recupererTous($requeteVotes);
290
		$votes = $this->formaterVotes($resultatsVotes);
291
		return $votes;
292
	}
293
 
294
	/**
295
	* Compter le nombre total d'images dans la base pour affichage dans entete.
296
	* */
297
	private function compterVotes() {
298
		$requete = 'SELECT FOUND_ROWS() AS nbre ';
299
		$resultats = $this->bdd->recuperer($requete);
300
		return (int) $resultats['nbre'];
829 aurelien 301
	}
751 delphine 302
 
303
 
304
	/*-------------------------------------------------------------------------------
305
								FORMATER ET METTRE EN FORME
306
	--------------------------------------------------------------------------------*/
307
 
308
	/**
309
	*  Formater une observation depuis une ligne liaison
310
	*  @param $liaison liaison issue de la recherche
311
	*  @return $observation l'observation mise en forme
312
	* */
313
	private function formaterVotes($votes) {
314
		$retour = array();
315
		foreach ($votes as $vote) {
316
			foreach ($vote as $p=>$valeur) {
317
				$retour[$vote['id_vote']][$this->mappingVotes[$p]] = $valeur;
318
			}
319
		}
320
 
321
		return $retour;
322
	}
323
 
324
	private function proteger($valeur) {
325
		if (is_array($valeur)) {
326
			return $this->bdd->protegerTableau($valeur);
327
		} else {
328
			return $this->bdd->proteger($valeur);
329
		}
330
	}
331
}
332
?>