Subversion Repositories eFlore/Applications.del

Rev

Rev 1487 | Rev 1489 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1487 Rev 1488
Line 24... Line 24...
24
// SELECT MAX(num_taxonomique) FROM bdtfx_v2_00;
24
// SELECT MAX(num_taxonomique) FROM bdtfx_v2_00;
25
define('_LISTE_OBS_MAX_BDTFX_NT', 44378 + 1000);
25
define('_LISTE_OBS_MAX_BDTFX_NT', 44378 + 1000);
26
// SELECT MAX(num_nom) FROM bdtfx_v2_00;
26
// SELECT MAX(num_nom) FROM bdtfx_v2_00;
27
define('_LISTE_OBS_MAX_BDTFX_NN', 103386 + 10000);
27
define('_LISTE_OBS_MAX_BDTFX_NN', 103386 + 10000);
Line -... Line 28...
-
 
28
 
-
 
29
require_once(dirname(__FILE__) . '/../images/ListeImages2.php');
28
 
30
/*
29
restore_error_handler();
31
  restore_error_handler();
30
restore_exception_handler();
32
  restore_exception_handler();
-
 
33
  error_reporting(E_ALL);
Line 31... Line 34...
31
error_reporting(E_ALL);
34
*/
Line 32... Line 35...
32
 
35
 
33
class ListeObservations {
36
class ListeObservations {
Line 39... Line 42...
39
	private $ressources = array();
42
	private $ressources = array();
Line 40... Line 43...
40
 
43
 
41
	static $tris_possibles = array('date_observation');
44
	static $tris_possibles = array('date_observation');
42
	// paramètres autorisés
45
	// paramètres autorisés
43
	static $parametres_autorises = array('masque', 'masque.famille', 'masque.nn', 'masque.referentiel', // taxon
46
	static $parametres_autorises = array('masque', 'masque.famille', 'masque.nn', 'masque.referentiel', // taxon
44
										 'masque.genre', 'masque.espece', 'masque.ns', // nom_sel
47
	'masque.genre', 'masque.espece', 'masque.ns', // nom_sel
45
										 'masque.commune', 'masque.departement', 'masque.id_zone_geo', // loc
48
	'masque.commune', 'masque.departement', 'masque.id_zone_geo', // loc
46
										 'masque.auteur', 'masque.date', 'masque.tag', 'masque.type', // autres
49
	'masque.auteur', 'masque.date', 'masque.tag', 'masque.type', // autres
47
										 // tri, offset
50
	// tri, offset
48
										 'navigation.depart', 'navigation.limite',
51
	'navigation.depart', 'navigation.limite',
49
										 'tri', 'ordre', // TODO: 'total=[yes]', 'fields=[x,y,...]'
52
	'tri', 'ordre', // TODO: 'total=[yes]', 'fields=[x,y,...]'
50
										 // TODO: masque.annee, masque.insee (!= departement)
53
	// TODO: masque.annee, masque.insee (!= departement)
Line 51... Line 54...
51
	);
54
	);
52
 
55
 
Line 53... Line 56...
53
	static $default_params = array('navigation.depart' => 0, 'navigation.limite' => 10,
56
	static $default_params = array('navigation.depart' => 0, 'navigation.limite' => 10,
54
								   'tri' => 'date_transmission', 'ordre' => 'desc');
57
	'tri' => 'date_transmission', 'ordre' => 'desc');
55
 
58
 
56
	static $sql_fields_liaisons = array(
59
	static $sql_fields_liaisons = array(
57
		'dob' => array('id_observation', 'nom_sel AS `determination.ns`', 'nt AS `determination.nt`',
60
		'dob' => array('id_observation', 'nom_sel AS `determination.ns`', 'nt AS `determination.nt`',
58
					   'nom_sel_nn AS `determination.nn`', 'famille AS `determination.famille`',
61
		'nom_sel_nn AS `determination.nn`', 'famille AS `determination.famille`',
59
					   'nom_referentiel AS `determination.referentiel`',
62
		'nom_referentiel AS `determination.referentiel`',
60
					   'ce_zone_geo AS id_zone_geo', 'zone_geo', 'lieudit',
63
		'ce_zone_geo AS id_zone_geo', 'zone_geo', 'lieudit',
61
					   'station', 'milieu', 'date_observation', 'mots_cles_texte', 'date_transmission',
64
		'station', 'milieu', 'date_observation', 'mots_cles_texte', 'date_transmission',
62
					   'ce_utilisateur AS `auteur.id`', 'prenom_utilisateur AS `auteur.prenom`',
65
		'ce_utilisateur AS `auteur.id`', 'prenom_utilisateur AS `auteur.prenom`',
63
					   'nom_utilisateur AS `auteur.nom`', 'courriel_utilisateur AS observateur',
66
		'nom_utilisateur AS `auteur.nom`', 'courriel_utilisateur AS observateur',
64
					   'commentaire'),
67
		'commentaire'),
65
		'di' => array('id_image', 'date_prise_de_vue AS `date`', 'hauteur',/* 'largeur','nom_original' // apparemment inutilisés */),
68
		'di' => array('id_image', 'date_prise_de_vue AS `date`', 'hauteur',/* 'largeur','nom_original' // apparemment inutilisés */),
Line 163... Line 166...
163
 
166
 
Line 164... Line 167...
164
		$db = $this->bdd;
167
		$db = $this->bdd;
165
 
168
 
-
 
169
		// filtrage de l'INPUT
-
 
170
		$params = self::requestFilterParams($parametres, self::$parametres_autorises, $this->conteneur);
-
 
171
 
166
		// filtrage de l'INPUT
172
		$params['masque.tag'] = ListeImages2::buildTagsAST(@$parametres['masque.tag'], 'OR', ',');
167
		$params = self::requestFilterParams($parametres, self::$parametres_autorises, $this->conteneur);
173
 
Line 168... Line 174...
168
		// ... et paramètres par défaut
174
		// ... et paramètres par défaut
169
		$params = array_merge(self::$default_params, $params);
175
		$params = array_merge(self::$default_params, $params);
Line 201... Line 207...
201
		}
207
		}
Line 202... Line 208...
202
 
208
 
203
		// 6) JSON output
209
		// 6) JSON output
204
		$resultat = new ResultatService();
210
		$resultat = new ResultatService();
205
		$resultat->corps = array('entete' => self::makeJSONHeader($total, $params, Config::get('url_service')),
211
		$resultat->corps = array('entete' => self::makeJSONHeader($total, $params, Config::get('url_service')),
Line 206... Line 212...
206
								 'resultats' => $observations);
212
		'resultats' => $observations);
207
		
213
		
Line 208... Line 214...
208
		return $resultat;
214
		return $resultat;
Line 228... Line 234...
228
	 * @param req: le tableau représentant les composants de la requete SQL
234
	 * @param req: le tableau représentant les composants de la requete SQL
229
	 * @param db: l'instance de db
235
	 * @param db: l'instance de db
230
	 */
236
	 */
231
	static function getIdObs($p, $req, $db) {
237
	static function getIdObs($p, $req, $db) {
232
		$req_s = sprintf('SELECT SQL_CALC_FOUND_ROWS id_observation' .
238
		$req_s = sprintf('SELECT SQL_CALC_FOUND_ROWS id_observation' .
233
						 ' FROM v_del_image vdi'.
239
		' FROM v_del_image vdi'.
234
						 ' %s' . // LEFT JOIN if any
240
		' %s' . // LEFT JOIN if any
235
						 ' WHERE %s'. // where-clause ou TRUE
241
		' WHERE %s'. // where-clause ou TRUE
236
						 ' %s'. // group-by
242
		' %s'. // group-by
237
						 ' %s'. // having (si commentaires)
243
		' %s'. // having (si commentaires)
238
						 ' ORDER BY %s %s %s'.
244
		' ORDER BY %s %s %s'.
239
						 ' LIMIT %d, %d -- %s',
245
		' LIMIT %d, %d -- %s',
Line 240... Line 246...
240
						 
246
						 
241
						 $req['join'] ? implode(' ', $req['join']) : '',
247
		$req['join'] ? implode(' ', $req['join']) : '',
Line 242... Line 248...
242
						 $req['where'] ? implode(' AND ', $req['where']) : 'TRUE',
248
		$req['where'] ? implode(' AND ', $req['where']) : 'TRUE',
243
 
249
 
Line 244... Line 250...
244
						 $req['groupby'] ? ('GROUP BY ' . implode(', ', array_unique($req['groupby']))) : '',
250
		$req['groupby'] ? ('GROUP BY ' . implode(', ', array_unique($req['groupby']))) : '',
245
						 $req['having'] ? ('HAVING ' . implode(' AND ', $req['having'])) : '',
251
		$req['having'] ? ('HAVING ' . implode(' AND ', $req['having'])) : '',
246
 
252
 
247
						 $p['tri'], strtoupper($p['ordre']),
253
		$p['tri'], strtoupper($p['ordre']),
Line 248... Line 254...
248
						 // date_transmission peut-être NULL et nous voulons de la consistence
254
		// date_transmission peut-être NULL et nous voulons de la consistence
Line 249... Line 255...
249
						 // (sauf après r1860 de Cel)
255
		// (sauf après r1860 de Cel)
250
						 $p['tri'] == 'date_transmission' ? ', id_observation' : '',
256
		$p['tri'] == 'date_transmission' ? ', id_observation' : '',
251
 
257
 
252
						 $p['navigation.depart'], $p['navigation.limite'], __FILE__ . ':' . __LINE__);
258
		$p['navigation.depart'], $p['navigation.limite'], __FILE__ . ':' . __LINE__);
Line 271... Line 277...
271
	  Note: le préfixe de table utilisé ici (vdi) n'impacte *aucune* autre partie du code car rien
277
	  Note: le préfixe de table utilisé ici (vdi) n'impacte *aucune* autre partie du code car rien
272
	  n'en dépend pour l'heure. (inutilisation de $req['select'])
278
	  n'en dépend pour l'heure. (inutilisation de $req['select'])
273
	*/
279
	*/
274
	static function getInfos($idobs, $db) {
280
	static function getInfos($idobs, $db) {
275
		/*$select_fields = implode(',', array_merge(
281
		/*$select_fields = implode(',', array_merge(
276
			array_map(create_function('$a', 'return "vdi.".$a;'), self::$sql_fields_liaisons['dob']),
282
		  array_map(create_function('$a', 'return "vdi.".$a;'), self::$sql_fields_liaisons['dob']),
277
			array_map(create_function('$a', 'return "vdi.".$a;'), self::$sql_fields_liaisons['di']),
283
		  array_map(create_function('$a', 'return "vdi.".$a;'), self::$sql_fields_liaisons['di']),
278
			array_map(create_function('$a', 'return "du.".$a;'), self::$sql_fields_liaisons['du'])));*/
284
		  array_map(create_function('$a', 'return "du.".$a;'), self::$sql_fields_liaisons['du'])));*/
279
		$select_fields = array_merge(self::$sql_fields_liaisons['dob'],
285
		$select_fields = array_merge(self::$sql_fields_liaisons['dob'],
280
									 self::$sql_fields_liaisons['di']);
286
		self::$sql_fields_liaisons['di']);
281
		$req_s = sprintf('SELECT %s FROM v_del_image vdi'.
287
		$req_s = sprintf('SELECT %s FROM v_del_image vdi'.
282
						 // ' LEFT JOIN del_commentaire AS dc ON di.id_observation = dc.ce_observation AND dc.nom_sel IS NOT NULL'.
288
		// ' LEFT JOIN del_commentaire AS dc ON di.id_observation = dc.ce_observation AND dc.nom_sel IS NOT NULL'.
283
						 ' WHERE id_observation IN (%s)',
289
		' WHERE id_observation IN (%s)',
284
						 implode(',', $select_fields),
290
		implode(',', $select_fields),
285
						 implode(',', $idobs));
291
		implode(',', $idobs));
286
		return $db->recupererTous($req_s);
292
		return $db->recupererTous($req_s);
287
	}
293
	}
Line 288... Line 294...
288
 
294
 
Line 319... Line 325...
319
			if(is_numeric($p['masque.auteur'])) {
325
			if(is_numeric($p['masque.auteur'])) {
320
				$req['where'][] = sprintf('(du.id_utilisateur = %1$d OR vdi.id_utilisateur = %1$d )', $p['masque.auteur']);
326
				$req['where'][] = sprintf('(du.id_utilisateur = %1$d OR vdi.id_utilisateur = %1$d )', $p['masque.auteur']);
321
			}
327
			}
322
			elseif(preg_match(';^.{5,}@[a-z0-9-.]{5,}$;i', $p['masque.auteur'])) {
328
			elseif(preg_match(';^.{5,}@[a-z0-9-.]{5,}$;i', $p['masque.auteur'])) {
323
				$req['where'][] = sprintf('(du.courriel LIKE %1$s OR vdi.courriel LIKE %1$s )',
329
				$req['where'][] = sprintf('(du.courriel LIKE %1$s OR vdi.courriel LIKE %1$s )',
324
										  $db->proteger($p['masque.auteur'] . '%'));
330
				$db->proteger($p['masque.auteur'] . '%'));
325
			}
331
			}
326
			else {
332
			else {
327
				self::addAuteursConstraint($p['masque.auteur'], $db, $req['where']);
333
				self::addAuteursConstraint($p['masque.auteur'], $db, $req['where']);
328
			}
334
			}
329
		}
335
		}
Line 332... Line 338...
332
			if(is_integer($p['masque.date']) && $p['masque.date'] < 2030 && $p['masque.date'] > 1600) {
338
			if(is_integer($p['masque.date']) && $p['masque.date'] < 2030 && $p['masque.date'] > 1600) {
333
				$req['where'][] = sprintf("YEAR(vdi.date_observation) = %d", $p['masque.date']);
339
				$req['where'][] = sprintf("YEAR(vdi.date_observation) = %d", $p['masque.date']);
334
			}
340
			}
335
			else {
341
			else {
336
				$req['where'][] = sprintf("DATE_FORMAT(vdi.date_observation, '%%Y-%%m-%%d') = %s",
342
				$req['where'][] = sprintf("DATE_FORMAT(vdi.date_observation, '%%Y-%%m-%%d') = %s",
337
										  $db->proteger(strftime('%Y-%m-%d', $p['masque.date'])));
343
				$db->proteger(strftime('%Y-%m-%d', $p['masque.date'])));
338
			}
344
			}
339
		}
345
		}
Line 340... Line 346...
340
 
346
 
341
		// TODO: avoir des champs d'entrée distinct
347
		// TODO: avoir des champs d'entrée distinct
Line 362... Line 368...
362
		}
368
		}
363
		if(!empty($p['masque.commune'])) {
369
		if(!empty($p['masque.commune'])) {
364
			$req['where'][] = 'vdi.zone_geo LIKE '.$db->proteger($p['masque.commune'].'%');
370
			$req['where'][] = 'vdi.zone_geo LIKE '.$db->proteger($p['masque.commune'].'%');
365
		}
371
		}
366
		if(!empty($p['masque.tag'])) {
372
		if(!empty($p['masque.tag'])) {
367
			// i_mots_cles_texte provient de la VIEW v_del_image
-
 
368
			// TODO: remove LOWER() lorsqu'on est sur que les tags sont uniformés en minuscule
373
			// TODO: remove LOWER() lorsqu'on est sur que les tags sont uniformés en minuscule
-
 
374
			// i_mots_cles_texte provient de la VIEW v_del_image
-
 
375
			if(isset($p['masque.tag']['AND'])) {
-
 
376
                /* Lorsque nous interprêtons la chaîne provenant du masque général (cf: buildTagsAST($p['masque'], 'OR', ' ') dans sqlAddMasqueConstraint()),
-
 
377
                   nous sommes splittés par espace. Cependant, assurons que si une virgule à été saisie, nous n'aurons pas le motif
-
 
378
                   " AND CONCAT(mots_cles_texte, i_mots_cles_texte) REGEXP ',' " dans notre requête.
-
 
379
                   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 */
-
 
380
				$subwhere = array();
-
 
381
				foreach($p['masque.tag']['AND'] as $tag) {
-
 
382
                    if(trim($tag) == ',') continue;
-
 
383
 
-
 
384
					$subwhere[] = sprintf(
369
			$req['where'][] = sprintf('LOWER(CONCAT(%s)) REGEXP %s',
385
						'LOWER(CONCAT(%s)) REGEXP %s',
370
									  self::sqlAddIfNullPourConcat(array('vdi.mots_cles_texte', 'vdi.i_mots_cles_texte')),
386
						self::sqlAddIfNullPourConcat(array('vdi.mots_cles_texte', 'vdi.i_mots_cles_texte')),
371
									  $db->proteger(strtolower($p['masque.tag'])));
387
						$db->proteger(strtolower($tag)));
-
 
388
				}
-
 
389
				$req['where'][] = '(' . implode(' AND ', $subwhere) . ')';
-
 
390
			}
-
 
391
			else {
-
 
392
				$req['where'][] = sprintf(
-
 
393
					'LOWER(CONCAT(%s)) REGEXP %s',
-
 
394
					self::sqlAddIfNullPourConcat(array('vdi.mots_cles_texte', 'vdi.i_mots_cles_texte')),
-
 
395
					$db->proteger(strtolower(implode('|', $p['masque.tag']['OR']))));
-
 
396
			}
372
		}
397
		}
Line 373... Line 398...
373
 
398
 
374
		if(!empty($p['masque.type'])) {
399
		if(!empty($p['masque.type'])) {
375
			self::addTypeConstraints($p['masque.type'], $db, $req, $c);
400
			self::addTypeConstraints($p['masque.type'], $db, $req, $c);
Line 381... Line 406...
381
	   récursivement. À la seule différence que nous n'utiliserons que $or_req['where']
406
	   récursivement. À la seule différence que nous n'utiliserons que $or_req['where']
382
	   imploded par des " OR ". */
407
	   imploded par des " OR ". */
383
	static function sqlAddMasqueConstraint($p, $db, &$req, Conteneur $c = NULL) {
408
	static function sqlAddMasqueConstraint($p, $db, &$req, Conteneur $c = NULL) {
384
		if(!empty($p['masque'])) {
409
		if(!empty($p['masque'])) {
385
			$or_params = array('masque.auteur' => $p['masque'],
410
			$or_params = array('masque.auteur' => $p['masque'],
386
							   'masque.departement' => $p['masque'],
411
			'masque.departement' => $p['masque'],
387
							   'masque.id_zone_geo' => $p['masque'],
412
			'masque.id_zone_geo' => $p['masque'],
388
							   'masque.tag' => $p['masque'],
413
			'masque.tag' => $p['masque'],
389
							   'masque.ns' => $p['masque'],
414
			'masque.ns' => $p['masque'],
390
							   'masque.famille' => $p['masque'],
415
			'masque.famille' => $p['masque'],
391
							   'masque.date' => $p['masque'],
416
			'masque.date' => $p['masque'],
392
							   'masque.genre' => $p['masque'],
417
			'masque.genre' => $p['masque'],
393
							   /* milieu: TODO ? */ );
418
			/* milieu: TODO ? */ );
394
			$or_masque = self::requestFilterParams($or_params, array_keys($or_params), $c);
419
			$or_masque = self::requestFilterParams($or_params, array_keys($or_params), $c);
-
 
420
			$or_masque['masque.tag'] = ListeImages2::buildTagsAST($p['masque'], 'OR', ' ');
395
			// $or_req = array('select' => array(), 'join' => array(), 'where' => array(), 'groupby' => array(), 'having' => array());
421
			// $or_req = array('select' => array(), 'join' => array(), 'where' => array(), 'groupby' => array(), 'having' => array());
396
			$or_req = array('join' => array(), 'where' => array());
422
			$or_req = array('join' => array(), 'where' => array());
397
			self::sqlAddConstraint($or_masque, $db, $or_req);
423
			self::sqlAddConstraint($or_masque, $db, $or_req);
Line 398... Line 424...
398
 
424
 
Line 428... Line 454...
428
	*/
454
	*/
429
	static function addAuteursConstraint($val, $db, &$where) {
455
	static function addAuteursConstraint($val, $db, &$where) {
430
		@list($a, $b) = explode(' ', $val, 2);
456
		@list($a, $b) = explode(' ', $val, 2);
431
		// un seul terme
457
		// un seul terme
432
		$champs_n = array('du.prenom', // info user authentifié de l'obs depuis l'annuaire
458
		$champs_n = array('du.prenom', // info user authentifié de l'obs depuis l'annuaire
433
						  'vdi.prenom_utilisateur', // info user anonyme de l'obs
459
		'vdi.prenom_utilisateur', // info user anonyme de l'obs
434
						  /* 'vdi.i_prenom_utilisateur' */ ); // info user anonyme de l'image
460
		/* 'vdi.i_prenom_utilisateur' */ ); // info user anonyme de l'image
435
		$champs_p = array('du.nom', // idem pour le nom
461
		$champs_p = array('du.nom', // idem pour le nom
436
						  'vdi.nom_utilisateur',
462
		'vdi.nom_utilisateur',
437
						  /* 'vdi.i_nom_utilisateur' */ );
463
		/* 'vdi.i_nom_utilisateur' */ );
Line 438... Line 464...
438
 
464
 
439
		/*
465
		/*
440
		  Note: pour l'heure, étant donnés:
466
		  Note: pour l'heure, étant donnés:
441
		  - les CONVERT() de la VIEW del_utilisateur
467
		  - les CONVERT() de la VIEW del_utilisateur
442
		  - DEFAULT CHARSET=latin1 pour tela_prod_v4.annuaire_tela
468
		  - DEFAULT CHARSET=latin1 pour tela_prod_v4.annuaire_tela
443
		  - DEFAULT CHARSET=utf8 pour tb_cel.cel_obs
469
		  - DEFAULT CHARSET=utf8 pour tb_cel.cel_obs
444
		  et l'âge du capitaine...
470
		  et l'âge du capitaine...
445
		  - REGEXP est case-sensitive, et collate les caractères accentués
471
		  - REGEXP est case-sensitive, et collate les caractères accentués
446
		  - LIKE est case-insensitive, et collate les caractères accentués
472
		  - LIKE est case-insensitive, et collate les caractères accentués
447
		 */
473
		*/
448
		if(! $b) {
474
		if(! $b) {
449
			$where[] = sprintf('CONCAT(%s,%s) LIKE %s',
475
			$where[] = sprintf('CONCAT(%s,%s) LIKE %s',
450
							   self::sqlAddIfNullPourConcat($champs_n),
476
			self::sqlAddIfNullPourConcat($champs_n),
451
							   self::sqlAddIfNullPourConcat($champs_p),
477
			self::sqlAddIfNullPourConcat($champs_p),
452
							   $db->proteger("%".$val."%"));
478
			$db->proteger("%".$val."%"));
453
		}
479
		}
454
		else {
480
		else {
455
			$where[] = sprintf('(CONCAT(%1$s,%2$s) LIKE %3$s AND CONCAT(%1$s,%2$s) LIKE %4$s)',
481
			$where[] = sprintf('(CONCAT(%1$s,%2$s) LIKE %3$s AND CONCAT(%1$s,%2$s) LIKE %4$s)',
456
							   self::sqlAddIfNullPourConcat($champs_n),
482
			self::sqlAddIfNullPourConcat($champs_n),
457
							   self::sqlAddIfNullPourConcat($champs_p),
483
			self::sqlAddIfNullPourConcat($champs_p),
458
							   $db->proteger("%" . $a . "%"), $db->proteger("%" . $b . "%"));
484
			$db->proteger("%" . $a . "%"), $db->proteger("%" . $b . "%"));
459
		}
485
		}
Line 460... Line 486...
460
	}
486
	}
461
 
487
 
Line 500... Line 526...
500
		}
526
		}
501
	}
527
	}
Line 502... Line 528...
502
 
528
 
503
 
529
 
504
	/**
530
	/**
505
	* Récupérer toutes les déterminations et le nombre de commentaire au total
531
	 * Récupérer toutes les déterminations et le nombre de commentaire au total
506
	* @param array $observations la liste des observations à mettre à jour
532
	 * @param array $observations la liste des observations à mettre à jour
507
	* */
533
	 * */
508
	private function chargerDeterminations(&$observations) {
534
	private function chargerDeterminations(&$observations) {
509
		$idObs = array_values(array_map(create_function('$a', 'return $a["id_observation"];'),
535
		$idObs = array_values(array_map(create_function('$a', 'return $a["id_observation"];'),
510
									$observations));
536
		$observations));
511
		$r = sprintf('SELECT * FROM del_commentaire AS dc WHERE dc.nom_sel IS NOT NULL AND ce_observation IN (%s) -- %s',
537
		$r = sprintf('SELECT * FROM del_commentaire AS dc WHERE dc.nom_sel IS NOT NULL AND ce_observation IN (%s) -- %s',
512
					 implode(',',$idObs),
538
		implode(',',$idObs),
513
					 __FILE__ . ':' . __LINE__);
539
		__FILE__ . ':' . __LINE__);
514
		$propositions = $this->bdd->recupererTous($r);
540
		$propositions = $this->bdd->recupererTous($r);
515
		if(!$propositions) return;
541
		if(!$propositions) return;
516
		foreach ($propositions as $proposition) {
542
		foreach ($propositions as $proposition) {
Line 553... Line 579...
553
				// TODO/debug: id_commentaire_parent != $commentId ??
579
				// TODO/debug: id_commentaire_parent != $commentId ??
554
				// reprendre la "logique" du code... moins de boucles, moins de requêtes, ...
580
				// reprendre la "logique" du code... moins de boucles, moins de requêtes, ...
555
				if($ligneProposition['ce_commentaire_parent'] != $commentId) {
581
				if($ligneProposition['ce_commentaire_parent'] != $commentId) {
556
					// restore_error_handler();
582
					// restore_error_handler();
557
					error_log(sprintf("possible error: nb_commentaires = %s: comment = %d, parent = %d, %s",
583
					error_log(sprintf("possible error: nb_commentaires = %s: comment = %d, parent = %d, %s",
558
									  $ligneProposition['nb'], $commentId, $ligneProposition['ce_commentaire_parent'], __FILE__));
584
					$ligneProposition['nb'], $commentId, $ligneProposition['ce_commentaire_parent'], __FILE__));
559
				}
585
				}
560
				$proposition_formatee['nb_commentaires'] = $ligneProposition['nb'];
586
				$proposition_formatee['nb_commentaires'] = $ligneProposition['nb'];
561
			} else {
587
			} else {
562
				$proposition_formatee['observation']['nb_commentaires'] = $ligneProposition['nb'];
588
				$proposition_formatee['observation']['nb_commentaires'] = $ligneProposition['nb'];
563
			}
589
			}
Line 565... Line 591...
565
 
591
 
566
		return $proposition_formatee;
592
		return $proposition_formatee;
Line 567... Line 593...
567
	}
593
	}
568
 
594
 
569
	/**
595
	/**
570
	*  Formater un vote en fonction du fichier de configuration config_votes.ini
596
	 *	Formater un vote en fonction du fichier de configuration config_votes.ini
571
	*  @param $votes array()
597
	 *	@param $votes array()
572
	* */
598
	 * */
573
	private function formaterVote($vote) {
599
	private function formaterVote($vote) {
574
		$retour = array();
600
		$retour = array();
575
		foreach ($vote as $param=>$valeur) {
601
		foreach ($vote as $param=>$valeur) {
Line 609... Line 635...
609
		$p['masque.referentiel'] = self::unsetIfInvalid($params, 'masque.referentiel', array('bdtfx','bdtxa','isfan'));
635
		$p['masque.referentiel'] = self::unsetIfInvalid($params, 'masque.referentiel', array('bdtfx','bdtxa','isfan'));
Line 610... Line 636...
610
 
636
 
611
		// TODO: use filter_input(INPUT_GET);
637
		// TODO: use filter_input(INPUT_GET);
612
		// renvoie FALSE ou NULL si absent ou invalide
638
		// renvoie FALSE ou NULL si absent ou invalide
613
		$p['navigation.limite'] = filter_var(@$params['navigation.limite'],
639
		$p['navigation.limite'] = filter_var(@$params['navigation.limite'],
614
											 FILTER_VALIDATE_INT,
640
		FILTER_VALIDATE_INT,
615
											 array('options' => array('default' => NULL,
641
		array('options' => array('default' => NULL,
616
																	  'min_range' => 1,
642
		'min_range' => 1,
617
																	  'max_range' => _LISTE_OBS_MAX_RESULT_LIMIT)));
643
		'max_range' => _LISTE_OBS_MAX_RESULT_LIMIT)));
618
		$p['navigation.depart'] = filter_var(@$params['navigation.depart'],
644
		$p['navigation.depart'] = filter_var(@$params['navigation.depart'],
619
											 FILTER_VALIDATE_INT,
645
		FILTER_VALIDATE_INT,
620
											 array('options' => array('default' => NULL,
646
		array('options' => array('default' => NULL,
621
																	  'min_range' => 0,
647
		'min_range' => 0,
622
																	  'max_range' => _LISTE_OBS_MAX_ID_OBS)));
648
		'max_range' => _LISTE_OBS_MAX_ID_OBS)));
623
		if(isset($params['masque.departement'])) {
649
		if(isset($params['masque.departement'])) {
624
			// STRING: 0 -> 95, 971 -> 976, 2A + 2B (./services/configurations/config_departements_bruts.ini)
650
			// STRING: 0 -> 95, 971 -> 976, 2A + 2B (./services/configurations/config_departements_bruts.ini)
625
			// accept leading 0 ?
651
			// accept leading 0 ?
626
			// TODO; filter patterns like 555.
652
			// TODO; filter patterns like 555.
Line 639... Line 665...
639
			// une année, TODO: masque.annee
665
			// une année, TODO: masque.annee
640
			if(is_numeric($params['masque.date'])) {
666
			if(is_numeric($params['masque.date'])) {
641
				$p['masque.date'] = $params['masque.date'];
667
				$p['masque.date'] = $params['masque.date'];
642
			}
668
			}
643
			elseif(strpos($params['masque.date'], '/' !== false) &&
669
			elseif(strpos($params['masque.date'], '/' !== false) &&
644
				   ($x = strtotime(str_replace('/','-',$params['masque.date'])))) {
670
			($x = strtotime(str_replace('/','-',$params['masque.date'])))) {
645
				$p['masque.date'] = $x;
671
				$p['masque.date'] = $x;
646
			}
672
			}
647
			elseif(strpos($params['masque.date'], '-' !== false) &&
673
			elseif(strpos($params['masque.date'], '-' !== false) &&
648
				   ($x = strtotime($params['masque.date'])) ) {
674
			($x = strtotime($params['masque.date'])) ) {
649
				$p['masque.date'] = $x;
675
				$p['masque.date'] = $x;
650
			}
676
			}
651
		}
677
		}
Line 652... Line 678...
652
 
678
 
653
		$p['masque.nn'] = filter_var(@$params['masque.nn'],
679
		$p['masque.nn'] = filter_var(@$params['masque.nn'],
654
									 FILTER_VALIDATE_INT,
680
		FILTER_VALIDATE_INT,
655
									 array('options' => array('default' => NULL,
681
		array('options' => array('default' => NULL,
656
															  'min_range' => 0,
682
		'min_range' => 0,
Line 657... Line 683...
657
															  'max_range' => _LISTE_OBS_MAX_BDTFX_NN)));
683
		'max_range' => _LISTE_OBS_MAX_BDTFX_NN)));
658
 
684
 
659
		$p['masque.nt'] = filter_var(@$params['masque.nt'],
685
		$p['masque.nt'] = filter_var(@$params['masque.nt'],
660
									 FILTER_VALIDATE_INT,
686
		FILTER_VALIDATE_INT,
661
									 array('options' => array('default' => NULL,
687
		array('options' => array('default' => NULL,
Line 662... Line 688...
662
															  'min_range' => 0,
688
		'min_range' => 0,
Line 663... Line 689...
663
															  'max_range' => _LISTE_OBS_MAX_BDTFX_NT)));
689
		'max_range' => _LISTE_OBS_MAX_BDTFX_NT)));
664
 
690
 
Line 665... Line 691...
665
 
691
 
666
		// TODO: should we really trim() ?
692
		// TODO: should we really trim() ?
667
 
693
 
668
		if(isset($params['masque.ns'])) $p['masque.ns'] = trim($params['masque.ns']);
694
		if(isset($params['masque.ns'])) $p['masque.ns'] = trim($params['masque.ns']);
669
		// if(isset($params['masque.texte'])) $p['masque.texte'] = trim($params['masque.texte']);
695
		// if(isset($params['masque.texte'])) $p['masque.texte'] = trim($params['masque.texte']);
670
 
696
 
Line 671... Line 697...
671
		if(isset($params['masque.famille'])) {
697
		if(isset($params['masque.famille'])) {
672
			// mysql -N<<<"SELECT DISTINCT famille FROM bdtfx_v1_02;"|sed -r "s/(.)/\1\n/g"|sort -u|tr -d "\n"
698
			// mysql -N<<<"SELECT DISTINCT famille FROM bdtfx_v1_02;"|sed -r "s/(.)/\1\n/g"|sort -u|tr -d "\n"
673
			$p['masque.famille'] = preg_replace('/[^a-zA-Z %_]/', '', iconv("UTF-8",
699
			$p['masque.famille'] = preg_replace('/[^a-zA-Z %_]/', '', iconv("UTF-8",
Line 707... Line 733...
707
		}
733
		}
Line 708... Line 734...
708
 
734
 
709
		// masque.type: ['adeterminer', 'aconfirmer', 'endiscussion', 'validees']
735
		// masque.type: ['adeterminer', 'aconfirmer', 'endiscussion', 'validees']
710
		if(isset($params['masque.type'])) {
736
		if(isset($params['masque.type'])) {
711
			$p['masque.type'] = array_flip(array_intersect(array_filter(explode(';', $params['masque.type'])),
737
			$p['masque.type'] = array_flip(array_intersect(array_filter(explode(';', $params['masque.type'])),
712
														   array('adeterminer', 'aconfirmer', 'endiscussion', 'validees')));
738
			array('adeterminer', 'aconfirmer', 'endiscussion', 'validees')));
Line 713... Line 739...
713
		}
739
		}