Subversion Repositories eFlore/Applications.del

Rev

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