Subversion Repositories eFlore/Applications.del

Rev

Rev 1755 | Rev 1794 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1375 raphael 1
<?php
2
/**
3
 * Le web service observations récupère toutes les observations et, pour chacune d'elle, les
4
 * images qui lui sont associées.
5
 * Basée sur la classe antérieure dans ListeObservations.php de
6
 * Grégoire Duché et Aurélien Peronnet
7
 * (formaterVote, formaterDeterminations, chargerNombreCommentaire, chargerVotes, chargerDeterminations)
8
 *
9
 * @category	php 5.2
10
 * @package		del
11
 * @author		Raphaël Droz <raphael@tela-botanica.org>
12
 * @copyright	Copyright (c) 2013 Tela Botanica (accueil@tela-botanica.org)
13
 * @license	http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
14
 * @license	http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
15
 * @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=ApiIdentiplante01Observations
16
 *
17
 * TODO:
18
 * PDO::prepare()
19
 * Sphinx pour auteur, genre, ns, commune, tag et masque-général
20
 */
21
 
1490 raphael 22
require_once(dirname(__FILE__) . '/../DelTk.php');
1488 raphael 23
/*
24
  restore_error_handler();
25
  restore_exception_handler();
26
  error_reporting(E_ALL);
27
*/
1375 raphael 28
 
1451 raphael 29
class ListeObservations {
1375 raphael 30
 
1793 jpm 31
	private $conteneur;
32
	private $bdd;
33
	private $parametres = array();
34
	private $ressources = array();
1375 raphael 35
 
1793 jpm 36
	static $tris_possibles = array('date_observation');
37
	// paramètres autorisés
1375 raphael 38
 
1793 jpm 39
	static $sql_fields_liaisons = array(
40
		'dob' => array('id_observation', 'nom_sel AS `determination.ns`', 'nt AS `determination.nt`',
41
			'nom_sel_nn AS `determination.nn`', 'famille AS `determination.famille`',
42
			'nom_referentiel AS `determination.referentiel`',
43
			'ce_zone_geo AS id_zone_geo', 'zone_geo', 'lieudit',
44
			'station', 'milieu', 'date_observation', 'mots_cles_texte', 'date_transmission',
45
			'ce_utilisateur AS `auteur.id`', 'prenom_utilisateur AS `auteur.prenom`',
46
			'nom_utilisateur AS `auteur.nom`', 'courriel_utilisateur AS `auteur.courriel` ',
47
			'commentaire'),
48
		'di' => array('id_image', 'date_prise_de_vue AS `date`', 'hauteur',/* 'largeur','nom_original' // apparemment inutilisés */),
49
		'du' => array('prenom', 'nom', 'courriel'),
50
		'dc' => array('commentaire')
51
	);
1375 raphael 52
 
1793 jpm 53
	public function __construct(Conteneur $conteneur = null) {
1618 mathias 54
		$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
55
		$this->conteneur->chargerConfiguration('config_departements_bruts.ini');
56
		$this->conteneur->chargerConfiguration('config_observations.ini');
57
		$this->conteneur->chargerConfiguration('config_mapping_votes.ini');
58
		$this->conteneur->chargerConfiguration('config_mapping_commentaires.ini');
59
		$this->navigation = $conteneur->getNavigation();
60
		$this->masque = $conteneur->getMasque();
1793 jpm 61
		$this->bdd = $this->conteneur->getBdd();
1494 raphael 62
    }
1375 raphael 63
 
1793 jpm 64
	static function reformateObservation($obs, $url_pattern = '') {
1618 mathias 65
		$obs = array_map('array_filter', $obs);
66
		$obs_merged = array();
1793 jpm 67
		foreach ($obs as $o) {
68
			$id = $o['id_observation'];
1666 jpm 69
 
1793 jpm 70
			// car auteur.id peut être un email, un hash, ou un annuaire_tela.U_ID
71
			// mais dans les deux premiers cas SELECT courriel AS observateur fait déjà l'affaire
72
			if (!isset($o['auteur.id']) || !is_numeric($o['auteur.id'])) $o['auteur.id'] = "0";
73
			if (!isset($o['auteur.nom'])) $o['auteur.nom'] = '[inconnu]';
1666 jpm 74
 
1793 jpm 75
			$image = array_intersect_key($o, array_flip(array('id_image', 'date', 'hauteur' , 'largeur', 'nom_original')));
76
			$image['binaire.href'] = sprintf($url_pattern, $image['id_image']);
77
			unset($o['id_image'], $o['date'], $o['hauteur'], $o['largeur'], $o['nom_original']);
78
			if (!isset($obs_merged['"' . $id . '"'])) $obs_merged['"' . $id . '"'] = $o;
79
			$obs_merged['"' . $id . '"']['images'][] = $image;
1618 mathias 80
		}
81
		return $obs_merged;
1494 raphael 82
    }
1375 raphael 83
 
1793 jpm 84
	/**
85
	 * Méthode principale de la classe.
86
	 * Lance la récupération des images dans la base et les place dans un objet ResultatService
87
	 * pour l'afficher.
88
	 * @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
89
	 * @param array $parametres les paramètres situés après le ? dans l'url
90
	 **/
91
	public function consulter($ressources, $parametres) {
1618 mathias 92
		// SELECT, à terme, pourrait affecter getInfos(), mais en aucune manière getIdObs()
93
		$req = array('select' => array(), 'join' => array(), 'where' => array(), 'groupby' => array(), 'having' => array());
1666 jpm 94
 
1618 mathias 95
		// toujours nécessaire puisque nous tapons sur v_del_image qui INNER JOIN cel_images, or nous voulons certes
96
		// toutes les images, mais nous voulons $limite observations uniques.
97
		$req['groupby'][] = 'vdi.id_observation';
1666 jpm 98
 
1618 mathias 99
		$db = $this->bdd;
1666 jpm 100
 
1618 mathias 101
		// filtrage de l'INPUT
102
		$params = DelTk::requestFilterParams($parametres, DelTk::$parametres_autorises, $this->conteneur);
1666 jpm 103
 
1618 mathias 104
		$params['masque.tag'] = DelTk::buildTagsAST(@$parametres['masque.tag'], 'OR', ',');
1666 jpm 105
 
1618 mathias 106
		// ... et paramètres par défaut
107
		$params = array_merge(DelTk::$default_params, $params);
1666 jpm 108
 
1618 mathias 109
		// création des contraintes (masques)
110
		DelTk::sqlAddConstraint($params, $db, $req);
111
		self::sqlAddConstraint($params, $db, $req, $this->conteneur);
112
		self::sqlAddMasqueConstraint($params, $db, $req, $this->conteneur);
1666 jpm 113
 
1618 mathias 114
		// 1) grunt-work: *la* requête de récupération des id valides (+ SQL_CALC_FOUND_ROWS)
115
		$idobs_tab = self::getIdObs($params, $req, $db);
116
		// idobs est une liste (toujours ordonnée) des id d'observations recherchées
117
		$idobs = array_values(array_map(create_function('$a', 'return $a["id_observation"];'), $idobs_tab));
1666 jpm 118
 
1793 jpm 119
		if ($idobs) {
120
			$total = $db->recuperer('SELECT FOUND_ROWS() AS c'); $total = intval($total['c']);
1666 jpm 121
 
1793 jpm 122
			// 2) récupération des données nécessaires pour ces observations (obs + images)
123
			// ici les champs récupérés sont issus de self::$sql_fields_liaisons mais sans préfixes
124
			// car tout provient de v_del_image
125
			$obs_unfmt = self::getInfos($idobs, $db);
1666 jpm 126
 
1793 jpm 127
			// 3) suppression, merge des données en tableau assez représentatif du futur JSON en output
128
			$observations = self::reformateObservation($obs_unfmt, $this->conteneur->getParametre('url_images'));
1666 jpm 129
 
1793 jpm 130
			// 4) récupération des données nécessaires pour ces observations (commentaires + votes)
131
			// modifie $observations
132
			$this->configurer();
133
			$this->chargerDeterminations($observations);
1666 jpm 134
 
1793 jpm 135
			// 5) restauration de l'ordre souhaité initialement
136
			$observations = self::sortArrayByArray($observations, $idobs);
1618 mathias 137
		} else {
1793 jpm 138
			$observations = array();
139
			$total = 0;
1618 mathias 140
		}
1666 jpm 141
 
1618 mathias 142
		// 6) JSON output
143
		$resultat = new ResultatService();
144
		$resultat->corps = array('entete' => DelTk::makeJSONHeader($total, $params, Config::get('url_service')),
1793 jpm 145
			'resultats' => $observations);
1666 jpm 146
 
1618 mathias 147
		return $resultat;
1793 jpm 148
	}
1375 raphael 149
 
1793 jpm 150
	static function sortArrayByArray($array, $orderArray) {
1618 mathias 151
		$ordered = array();
1793 jpm 152
		foreach ($orderArray as $key) {
153
			if (array_key_exists('"' . $key . '"', $array)) {
154
				$ordered['"' . $key . '"'] = $array['"' . $key . '"'];
155
				unset($array['"' . $key . '"']);
156
			}
1618 mathias 157
		}
158
		return $ordered + $array;
1793 jpm 159
	}
1375 raphael 160
 
1793 jpm 161
	// SQL helpers
162
	/*
163
	 * Retourne une liste ordonnée d'id d'observation correspondant aux critères
164
	 * passés dans p et aux clauses where/join présentes dans le tableau $req
165
	 *
166
	 * @param p: $params (filtrés sauf escape-string)
167
	 * @param req: le tableau représentant les composants de la requete SQL
168
	 * @param db: l'instance de db
169
	 */
170
	static function getIdObs($p, $req, $db) {
171
		$req_s = sprintf('SELECT SQL_CALC_FOUND_ROWS id_observation' .
172
			' FROM v_del_image vdi'.
173
			' %s' . // LEFT JOIN if any
174
			' WHERE %s'. // where-clause ou TRUE
175
			' %s'. // group-by
176
			' %s'. // having (si commentaires)
177
			' ORDER BY %s %s %s'.
178
			' LIMIT %d, %d -- %s',
1666 jpm 179
 
1793 jpm 180
			$req['join'] ? implode(' ', $req['join']) : '',
181
			$req['where'] ? implode(' AND ', $req['where']) : 'TRUE',
1375 raphael 182
 
1793 jpm 183
			$req['groupby'] ? ('GROUP BY ' . implode(', ', array_unique($req['groupby']))) : '',
184
			$req['having'] ? ('HAVING ' . implode(' AND ', $req['having'])) : '',
1375 raphael 185
 
1793 jpm 186
			$p['tri'], strtoupper($p['ordre']),
187
			// date_transmission peut-être NULL et nous voulons de la consistence
188
			// (sauf après r1860 de Cel)
189
			$p['tri'] == 'date_transmission' ? ', id_observation' : '',
1375 raphael 190
 
1793 jpm 191
			$p['navigation.depart'], $p['navigation.limite'], __FILE__ . ':' . __LINE__);
1379 raphael 192
 
1793 jpm 193
		$res = $db->recupererTous($req_s);
194
		$err = mysql_error();
195
		if (!$res && $err) {
196
			// http_response_code(400);
197
			// if(defined('DEBUG') && DEBUG) header("X-Debug: $req_s");
198
			throw new Exception('not found', 400);
199
		}
200
		// ordre préservé, à partir d'ici c'est important.
201
		return $res;
1375 raphael 202
	}
203
 
1793 jpm 204
	/**
205
	 * Champs récupérés:
206
	 * Pour del_images, la vue retourne déjà ce que nous recherchons de cel_obs et cel_images
207
	 * (cel_obs.* et cel_[obs_]images.{id_observation, id_image, date_prise_de_vue AS date, hauteur, largeur})
208
	 * Pour del_commentaires: nous voulons *
209
	 * Reste ensuite à formatter.
210
	 * Note: le préfixe de table utilisé ici (vdi) n'impacte *aucune* autre partie du code car rien
211
	 * n'en dépend pour l'heure. (inutilisation de $req['select'])
212
	 */
213
	static function getInfos($idobs, $db) {
214
		/*$select_fields = implode(',', array_merge(
215
		 array_map(create_function('$a', 'return "vdi.".$a;'), self::$sql_fields_liaisons['dob']),
216
		 array_map(create_function('$a', 'return "vdi.".$a;'), self::$sql_fields_liaisons['di']),
217
		 array_map(create_function('$a', 'return "du.".$a;'), self::$sql_fields_liaisons['du'])));*/
218
		$select_fields = array_merge(self::$sql_fields_liaisons['dob'], self::$sql_fields_liaisons['di']);
219
		$req_s = sprintf('SELECT %s FROM v_del_image vdi'.
220
			// ' LEFT JOIN del_commentaire AS dc ON di.id_observation = dc.ce_observation AND dc.nom_sel IS NOT NULL'.
221
			' WHERE id_observation IN (%s)',
222
			implode(',', $select_fields),
223
			implode(',', $idobs));
224
		return $db->recupererTous($req_s);
225
	}
1375 raphael 226
 
1793 jpm 227
	/**
228
	 * Complément à DelTk::sqlAddConstraint()
229
	 *
230
	 * @param $p les paramètres (notamment de masque) passés par l'URL et déjà traités/filtrés (sauf quotes)
231
	 * @param $req le tableau, passé par référence représentant les composants de la requête à bâtir
232
	 * @param $c conteneur, utilisé soit pour l'appel récursif à requestFilterParams() en cas de param "masque"
233
	 *								soit pour la définition du type (qui utilise la variable nb_commentaires_discussion)
234
	 */
235
	static function sqlAddConstraint($p, $db, &$req, Conteneur $c = NULL) {
236
		if (!empty($p['masque.tag'])) {
237
			// TODO: remove LOWER() lorsqu'on est sur que les tags sont uniformés en minuscule
238
			// i_mots_cles_texte provient de la VIEW v_del_image
239
			if (isset($p['masque.tag']['AND'])) {
240
				/* Lorsque nous interprêtons la chaîne provenant du masque général (cf: buildTagsAST($p['masque'], 'OR', ' ') dans sqlAddMasqueConstraint()),
241
				nous sommes splittés par espace. Cependant, assurons que si une virgule à été saisie, nous n'aurons pas le motif
242
				" AND CONCAT(mots_cles_texte, i_mots_cles_texte) REGEXP ',' " dans notre requête.
243
				XXX: Au 12/11/2013, une recherche sur tag depuis le masque général implique un OU, donc le problème ne se pose pas ici */
244
				$subwhere = array();
245
				foreach ($p['masque.tag']['AND'] as $tag) {
246
					if (trim($tag) == ',') continue;
1375 raphael 247
 
1793 jpm 248
					$subwhere[] = sprintf('LOWER(CONCAT(%s)) REGEXP %s',
249
						DelTk::sqlAddIfNullPourConcat(array('vdi.mots_cles_texte', 'vdi.i_mots_cles_texte')),
250
						$db->proteger(strtolower($tag)));
251
				}
252
				$req['where'][] = '(' . implode(' AND ', $subwhere) . ')';
253
			} else {
254
				$req['where'][] = sprintf('LOWER(CONCAT(%s)) REGEXP %s',
255
					DelTk::sqlAddIfNullPourConcat(array('vdi.mots_cles_texte', 'vdi.i_mots_cles_texte')),
256
					$db->proteger(strtolower(implode('|', $p['masque.tag']['OR']))));
257
			}
258
		}
1494 raphael 259
 
1793 jpm 260
		if (!empty($p['masque.type'])) {
261
			self::addTypeConstraints($p['masque.type'], $db, $req, $c);
1375 raphael 262
		}
1416 raphael 263
	}
1375 raphael 264
 
1793 jpm 265
	/** Le masque fait une recherche générique parmi de nombreux champs ci-dessus.
266
	 * Nous initialisons donc ces paramètres (excepté masque biensur), et nous rappelons
267
	 * récursivement. À la seule différence que nous n'utiliserons que $or_req['where']
268
	 * imploded par des " OR ".
269
	 */
270
	static function sqlAddMasqueConstraint($p, $db, &$req, Conteneur $c = NULL) {
271
		if (!empty($p['masque'])) {
272
			$or_params = array('masque.auteur' => $p['masque'],
273
				'masque.departement' => $p['masque'],
274
				'masque.id_zone_geo' => $p['masque'],
275
				'masque.tag' => $p['masque'],
276
				'masque.ns' => $p['masque'],
277
				'masque.famille' => $p['masque'],
278
				'masque.date' => $p['masque'],
279
				'masque.genre' => $p['masque'],
280
				/* milieu: TODO ? */ );
281
			/* Cependant les champs spécifiques ont priorité sur le masque général.
282
			Pour cette raison nous supprimons la génération de SQL du masque général sur les
283
			champ spécifiques qui feront l'objet d'un traitement avec une valeur propre. */
284
			if (isset($p['masque.auteur'])) unset($or_params['masque.auteur']);
285
			if (isset($p['masque.departement'])) unset($or_params['masque.departement']);
286
			if (isset($p['masque.id_zone_geo'])) unset($or_params['masque.id_zone_geo']);
287
			if (isset($p['masque.tag'])) unset($or_params['masque.tag']);
288
			if (isset($p['masque.famille'])) unset($or_params['masque.famille']);
289
			if (isset($p['masque.date'])) unset($or_params['masque.date']);
290
			if (isset($p['masque.genre'])) unset($or_params['masque.genre']);
1375 raphael 291
 
1498 raphael 292
 
1793 jpm 293
			$or_masque = DelTk::requestFilterParams($or_params, array_keys($or_params), $c);
294
			if (isset($or_params['masque.tag'])) {
295
				$or_masque['masque.tag'] = DelTk::buildTagsAST($p['masque'], 'OR', ' ');
296
			}
1498 raphael 297
 
1793 jpm 298
			// $or_req = array('select' => array(), 'join' => array(), 'where' => array(), 'groupby' => array(), 'having' => array());
299
			$or_req = array('join' => array(), 'where' => array());
300
			DelTk::sqlAddConstraint($or_masque, $db, $or_req);
301
			self::sqlAddConstraint($or_masque, $db, $or_req);
1498 raphael 302
 
1793 jpm 303
			if ($or_req['where']) {
304
				$req['where'][] = '(' . implode(' OR ', $or_req['where']) . ')';
305
				// utile au cas ou des jointures seraient rajoutées
306
				$req['join'] = array_unique(array_merge($req['join'], $or_req['join']));
307
			}
308
		}
309
	}
1375 raphael 310
 
1793 jpm 311
	private function configurer() {
312
		$this->mappingVotes = $this->conteneur->getParametre('mapping_votes');
313
		$this->mappingCommentaire = $this->conteneur->getParametre('mapping_commentaire');
1375 raphael 314
	}
315
 
1793 jpm 316
	/**
317
	 * @param $req: la représentation de la requête MySQL complète, à amender.
318
	 */
319
	static function addTypeConstraints($val, $db, &$req, Conteneur $c) {
320
		if (array_key_exists('adeterminer', $val)) {
321
			// On récupère toutes les observations qui on le tag "aDeterminer" *ou* qui n'ont pas de nom d'espèce
322
			// *ou* qui ont la "certitude" à ("aDeterminer" *ou* "douteux")
323
			$req['where'][] = '(' . implode(' OR ', array(
324
				'vdi.certitude = "aDeterminer"',
325
				'vdi.certitude = "douteux"',
326
				'vdi.mots_cles_texte LIKE "%aDeterminer%"',
327
				'vdi.nom_sel_nn IS NULL',
328
				'vdi.nom_sel_nn = 0', // il ne DEVRAIT pas y avoir d'entrées à 0, mais il y en a quand-même !!
329
				)) . ')';
330
		}
331
		if (array_key_exists('validees', $val)) {
332
			//On récupère toutes les observations ayant un commentaire doté de proposition_retenue = 1
333
			$req['join'][] = 'INNER JOIN del_commentaire AS dc ON vdi.id_observation = dc.ce_observation AND dc.proposition_retenue = 1';
334
		}
1375 raphael 335
 
1793 jpm 336
		// solution n°1: impraticable
337
		if (false && array_key_exists('endiscussion', $val)) {
338
			//Si on veut les observations en discussion,
339
			// on va récupérer les ids des observations dont le nombre de commentaire est supérieur à N
340
			$req['select'][] = 'COUNT(dc.id_commentaire) AS comm_count';
341
			$req['join'][] = 'INNER JOIN del_commentaire AS dc ON vdi.id_observation = dc.ce_observation';
342
			$req['groupby'][] = 'vdi.id_observation';
343
			$req['having'][] = "COUNT(id_commentaire) > " . $c->getParametre('nb_commentaires_discussion');
344
		}
1375 raphael 345
 
1793 jpm 346
		if (array_key_exists('endiscussion', $val)) {
347
			$req['where'][] = '(SELECT COUNT(id_commentaire) FROM del_commentaire AS dc'.
348
				' WHERE ce_observation = id_observation) > ' . intval($c->getParametre('nb_commentaires_discussion'));
349
		}
1375 raphael 350
	}
351
 
1793 jpm 352
	/**
353
	 * Récupérer toutes les déterminations et le nombre de commentaire au total
354
	 * @param array $observations la liste des observations à mettre à jour
355
	 */
356
	private function chargerDeterminations(&$observations) {
357
		$idObs = array_values(array_map(create_function('$a', 'return $a["id_observation"];'), $observations));
358
		$r = sprintf('SELECT * FROM del_commentaire AS dc WHERE dc.nom_sel IS NOT NULL AND ce_observation IN (%s) -- %s',
359
			implode(',',$idObs),
360
			__FILE__ . ':' . __LINE__);
361
		$propositions = $this->bdd->recupererTous($r);
362
		if (!$propositions) return;
363
		foreach ($propositions as $proposition) {
364
			$idObs = $proposition['ce_observation'];
365
			$idComment = $proposition['id_commentaire'];
366
			$comment = $this->formaterDetermination($idComment, $proposition);
367
			if ($comment) $observations['"' . $idObs . '"']['commentaires'][$idComment] = $comment;
1375 raphael 368
 
1793 jpm 369
		}
1494 raphael 370
	}
371
 
1793 jpm 372
	private function formaterDetermination($commentId, $proposition) {
373
		if (!$proposition) return NULL;
1494 raphael 374
 
1793 jpm 375
		$proposition_formatee = array('nb_commentaires' => '0');
376
		foreach ($this->mappingCommentaire as $nomOriginal => $nomFinal) {
377
			if (isset($proposition[$nomOriginal])) {
378
				$proposition_formatee[$nomFinal] = $proposition[$nomOriginal];
379
			}
380
		}
1666 jpm 381
 
1793 jpm 382
		// Charger les votes sur les déterminations
383
		$resultatsVotes = $this->bdd->recupererTous(
384
			sprintf('SELECT * FROM del_commentaire_vote WHERE ce_proposition = %d', $commentId));
1375 raphael 385
 
1793 jpm 386
		foreach ($resultatsVotes as $vote) {
387
			$proposition_formatee['votes'][$vote['id_vote']] = $this->formaterVote($vote);
388
		}
1386 raphael 389
 
1793 jpm 390
		// chargerNombreCommentaire()
391
		// Charger le nombre de commentaires (sans détermination) associé à l'observation
392
		$listeCommentaires = $this->bdd->recupererTous(sprintf(
393
			'SELECT ce_commentaire_parent, ce_proposition, COUNT( id_commentaire ) AS nb '.
394
			'FROM del_commentaire WHERE ce_proposition = %d GROUP BY ce_proposition -- %s',
395
			$commentId, __FILE__ . ':' . __LINE__));
396
		foreach ($listeCommentaires as $ligneProposition) {
397
			// ce test sert à exclure les proposition de 1er niveau qui sont elles aussi des commentaires
398
			if ($ligneProposition['ce_commentaire_parent']) {
399
				// TODO/debug: id_commentaire_parent != $commentId ??
400
				// reprendre la "logique" du code... moins de boucles, moins de requêtes, ...
401
				if ($ligneProposition['ce_commentaire_parent'] != $commentId) {
402
					// restore_error_handler();
403
					error_log(sprintf("possible error: nb_commentaires = %s: comment = %d, parent = %d, %s",
404
						$ligneProposition['nb'], $commentId, $ligneProposition['ce_commentaire_parent'], __FILE__));
405
				}
406
				$proposition_formatee['nb_commentaires'] = $ligneProposition['nb'];
407
			} else {
408
				$proposition_formatee['observation']['nb_commentaires'] = $ligneProposition['nb'];
409
			}
410
		}
1386 raphael 411
 
1793 jpm 412
		return $proposition_formatee;
1494 raphael 413
	}
1375 raphael 414
 
1793 jpm 415
	/**
416
	 * Formater un vote en fonction du fichier de configuration config_votes.ini
417
	 * @param $votes array()
418
	 */
419
	private function formaterVote($vote) {
420
		$retour = array();
421
		foreach ($vote as $param=>$valeur) {
422
			$retour[$this->mappingVotes[$param]] = $valeur;
1375 raphael 423
		}
1793 jpm 424
		return $retour;
1375 raphael 425
	}
1793 jpm 426
}