Subversion Repositories eFlore/Applications.del

Rev

Go to most recent revision | Details | 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
 
829 aurelien 18
class VotesImage extends RestService {
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
						');';
77
 
78
		$resultat = $this->bdd->requeter($insertion);
79
		if ($resultat == false) {
80
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
782 delphine 81
		} else {
1428 raphael 82
			self::updateStats($this->bdd, $ressources[0],$parametres['protocole']);
782 delphine 83
			RestServeur::envoyerEnteteStatutHttp(RestServeur::HTTP_CODE_CREATION_OK);
84
		}
85
	}
86
 
829 aurelien 87
	public function modifier($ressources, $parametres) {
88
 
89
		$this->verifierParametresAjoutModif($ressources, $parametres);
90
 
91
		//TODO: est il nécessaire de tester si ça existe et renoyer une erreur 404
92
		// si l'on vote ? Cela peut ralentir considérablement les choses
93
		// une contrainte d'unicité sur le triplet image, protocole, vote existe,
94
		// ça suffira pour provoquer une erreur 500
95
		$modification = 'UPDATE del_image_vote '.
96
							'SET valeur = '.$this->proteger($parametres['valeur']).', '.
97
							'    date = NOW() '.
98
						'WHERE '.
99
							'ce_image = '.$this->proteger($ressources[0]).' AND '.
100
							'ce_protocole = '.$this->proteger($parametres['protocole']).' AND '.
101
							'ce_utilisateur = '.$this->proteger($parametres['utilisateur']).' ';
102
		$resultat = $this->bdd->requeter($modification);
103
		if ($resultat == false) {
104
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
105
		} else {
1428 raphael 106
			self::updateStats($this->bdd, $ressources[0],$parametres['protocole']);
829 aurelien 107
			RestServeur::envoyerEnteteStatutHttp(RestServeur::HTTP_CODE_OK);
108
		}
109
	}
110
 
1428 raphael 111
	static function updateStats($db, $id_image, $id_proto) {
112
		$id_image = intval($id_image);
113
		$id_proto = intval($id_proto);
114
		if(!$id_image || !$id_proto) throw new Exception("Ne peut mettre à jour les statistiques de vote",
115
														 RestServeur::HTTP_CODE_ERREUR);
116
		/* REPLACE ... SELECT: réinitalise les champs non-défini (MySQL 5.1)
117
		   REPLACE ... SET a=b, c=d: idem ou plusieurs requête
118
		   Du coup il faut récupérer les données actuelles mais REPLACE ne le permet pas
119
		   (http://dev.mysql.com/doc/refman/5.5/en/replace.html :
120
		   You cannot refer to values from the current row and use them in the new row.)
121
		   D'où INSERT ... ON DUPLICATE KEY UPDATE. Notons que VALUES() récupère la valeur
122
		   *associée* au champ passé en paramètre, c'est à dire VALUES(moyenne) == divo.moyenne */
123
		$db->requeter(sprintf('INSERT INTO del_image_stat (ce_image, ce_protocole, moyenne, nb_votes)'.
124
							  ' SELECT ce_image, ce_protocole, AVG(valeur) AS moyenne, COUNT(valeur) AS nb_votes'.
125
							  ' FROM del_image_vote divo'.
126
							  ' WHERE ce_image = %d AND ce_protocole = %d GROUP BY ce_image, ce_protocole'.
127
							  ' ON DUPLICATE KEY UPDATE moyenne = VALUES(moyenne), nb_votes = VALUES(nb_votes)',
128
							  $id_image, $id_proto));
129
 
130
 
131
	}
132
 
751 delphine 133
	/*-------------------------------------------------------------------------------
134
	 							CONFIGURATION DU SERVICE
135
	 --------------------------------------------------------------------------------*/
136
	/**
137
	 * Configuration du service en fonction du fichier de config config_del.ini
138
	 * */
139
	public function configurer() {
140
		$this->mappingFiltre = $this->conteneur->getParametre('mapping_masque');
141
		$this->mappingVotes = $this->conteneur->getParametre('mapping_votes');
142
	}
143
 
144
	/**
145
	 * Vérifier que le service est bien configuré
146
	 * */
147
	public function verifierConfiguration() {
148
 
149
		$erreurs = array();
150
		$tableauImages = $this->conteneur->getParametre('images');
151
		if (empty($tableauImages)) {
152
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [images] ou celui-ci est vide ;';
153
		} else {
154
			if ($this->conteneur->getParametre('url_service') == null) {
155
				$erreurs[] = '- paramètre "url_service" manquant ;';
156
			}
157
		}
158
 
159
		if (empty($this->mappingVotes)) {
759 delphine 160
			$erreurs[] = '- le fichier de configuration ne contient pas le tableau [mapping_votes] ou celui-ci est vide ;';
751 delphine 161
		} else {
162
			$champsMappingObs = array('ce_protocole','id_vote','valeur','ce_image', 'ce_utilisateur', 'nom', 'prenom');
163
			foreach ($champsMappingObs as $champ) {
164
				if (!isset($this->mappingVotes[$champ])) {
759 delphine 165
					$erreurs[] = '- le mapping du champ "'.$champ.'" pour le vote est manquant ;';
751 delphine 166
				}
167
			}
168
		}
169
 
170
 
171
		if (!empty($erreurs)) {
172
			$e = 'Erreur lors de la configuration : '."\n";
173
			$e .= implode("\n", $erreurs);
174
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
175
		}
176
	}
829 aurelien 177
 
178
 
179
	public function verifierParametresAjoutModif($ressources, $parametres) {
180
		$erreurs = array();
181
		if (!is_numeric($ressources[0])) {
182
			$erreurs[] = '- le paramètre indiquant l\'identifiant de l\'image doit être numérique ;';
183
		}
184
 
185
		if (!isset($parametres['utilisateur'])) {
186
			$erreurs[] = '- paramètre "utilisateur" manquant ;';
187
		}
188
 
189
		if (!isset($parametres['protocole'])) {
190
			$erreurs[] = '- paramètre "id_protocole" manquant ;';
191
		} else {
192
			if (!is_numeric($parametres['protocole'])) {
193
				$erreurs[] = '- le paramètre "protocole" doit être numérique ;';
194
			}
195
		}
196
 
197
		if (!isset($parametres['valeur'])) {
198
			$erreurs[] = '- paramètre "valeur" manquant ;';
199
		} else {
200
			if (!is_numeric($parametres['valeur'])) {
201
				$erreurs[] = '- le paramètre "valeur" doit être numérique ;';
202
			}
203
		}
204
 
205
		if (!empty($erreurs)) {
206
			$e = 'Erreur lors de la configuration : '."\n";
207
			$e .= implode("\n", $erreurs);
208
			throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
209
		}
210
	}
751 delphine 211
 
212
 
213
	/**
214
	* Charger la clause WHERE en fonction des paramètres de masque
215
	* */
216
	private function chargerClauseWhere() {
758 delphine 217
		$where[] = 'WHERE ce_image = '.$this->proteger($this->ressources[0]);
786 delphine 218
		if (isset($this->parametres['protocole'])) {
219
			$where[] = 'ce_protocole = '.$this->proteger($this->parametres['protocole']);
758 delphine 220
		}
221
		return implode(' AND ', $where);
829 aurelien 222
	}
751 delphine 223
	/*-------------------------------------------------------------------------------
224
								CHARGEMENT DES IMAGES
225
	--------------------------------------------------------------------------------*/
226
	/**
227
	* Charger les votes pour chaque image
228
	* */
229
	private function chargerVotes() {
230
		$requeteVotes = 'SELECT * FROM '.
231
						$this->gestionBdd->formaterTable('del_image_vote').
232
						$this->chargerClauseWhere();
233
		$resultatsVotes = $this->bdd->recupererTous($requeteVotes);
234
		$votes = $this->formaterVotes($resultatsVotes);
235
		return $votes;
236
	}
237
 
238
	/**
239
	* Compter le nombre total d'images dans la base pour affichage dans entete.
240
	* */
241
	private function compterVotes() {
242
		$requete = 'SELECT FOUND_ROWS() AS nbre ';
243
		$resultats = $this->bdd->recuperer($requete);
244
		return (int) $resultats['nbre'];
829 aurelien 245
	}
751 delphine 246
 
247
 
248
	/*-------------------------------------------------------------------------------
249
								FORMATER ET METTRE EN FORME
250
	--------------------------------------------------------------------------------*/
251
 
252
	/**
253
	*  Formater une observation depuis une ligne liaison
254
	*  @param $liaison liaison issue de la recherche
255
	*  @return $observation l'observation mise en forme
256
	* */
257
	private function formaterVotes($votes) {
258
		$retour = array();
259
		foreach ($votes as $vote) {
260
			foreach ($vote as $p=>$valeur) {
261
				$retour[$vote['id_vote']][$this->mappingVotes[$p]] = $valeur;
262
			}
263
		}
264
 
265
		return $retour;
266
	}
267
 
268
	private function proteger($valeur) {
269
		if (is_array($valeur)) {
270
			return $this->bdd->protegerTableau($valeur);
271
		} else {
272
			return $this->bdd->proteger($valeur);
273
		}
274
	}
275
}
276
?>