Subversion Repositories eFlore/Applications.cel

Rev

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

Rev Author Line No. Line
1654 aurelien 1
<?php
2461 jpm 2
// declare(encoding='UTF-8');
1656 raphael 3
/**
2461 jpm 4
 * Classe métier de mise en forme des groupes de colonnes pour les exports.
5
 *
6
 * @internal   Mininum PHP version : 5.2
7
 * @category   CEL
8
 * @package    Services
9
 * @subpackage Bibliothèques
10
 * @version    0.1
11
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
12
 * @author     Raphaël Droz <raphael@tela-botania.org>
13
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
14
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
15
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
16
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
17
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
18
 */
19
define('SEPARATEUR_IMAGES', ' / ');
20
define('PREFIX_CHAMPS_ETENDUS', 'ext:');
1835 raphael 21
// utilisé par formaterUrlUser() [ nécessaire pour le widget d'export)
22
define('USER_BASEURL', 'http://www.tela-botanica.org/profil:%d');
1656 raphael 23
 
2461 jpm 24
class FormateurGroupeColonne {
1656 raphael 25
 
1702 raphael 26
	// cache pour les données des fonctions
1656 raphael 27
	static $cache = Array();
28
 
1702 raphael 29
	// test sur la table cel_references, mis à TRUE si la table existe
30
	static $is_table = false;
31
 
1714 raphael 32
	// les groupes de champs utilisables
33
	static $fieldGroups = array(
34
		'standard',
3498 delphine 35
	    'standardexport',
36
	    'auteur',
1714 raphael 37
		'avance',
38
		'etendu',
3498 delphine 39
		'baseflor'
1714 raphael 40
	);
41
 
1702 raphael 42
	// les données baseflor à récupérer: colonnes présentes dans cel_references
43
	// et intitulés associés
44
	static $baseflor_col = array(
2461 jpm 45
		've_lumiere' => 'Lumière',
46
		've_temperature' => 'Température',
47
		've_continentalite' => 'Continentalité',
48
		've_humidite_atmos' => 'Humidité Atmosphérique',
49
		've_humidite_edaph' => 'Humidité',
50
		've_reaction_sol' => 'Réaction (pH)',
51
		've_nutriments_sol' => 'Nutriments',
52
		've_salinite' => 'Salinité',
53
		've_texture_sol' => 'Texture' ,
54
		've_mat_org_sol' => 'Matière Organique',
55
		'catminat_code' => 'Code Catminat',
56
		'syntaxon' => 'Syntaxon',
1702 raphael 57
	);
58
 
1741 raphael 59
	// TODO: dirty, ordre des champs étendus... souhaité pour florilèges:
60
	static $ordre_champ_etendus_Florileges = array(
2461 jpm 61
		'personneStructure',
62
		'personneService',
63
		'personneFonction',
64
		'adresse',
65
		'latitudeDebutRue',
66
		'longitudeDebutRue',
67
		'latitudeFinRue',
68
		'longitudeFinRue',
69
		'typoUrbaine',
70
		'revetementSol',
71
		'presenceZoneVegetalise',
72
		'hauteurBatimentAvoisinant',
73
		'intensiteGestion',
74
		'periodiciteTraitementPhyto',
75
		'dateArretTraitementPhyto',
76
		'itineraireGestion',
77
		'dateDerniereIntervention',
78
		'hauteurPlante',
79
		'resistanceTraitementPhyto',
80
		'vitesseCroissance',
81
		'perceptionTechnicien',
82
		'perceptionRiverainMauvaise',
1741 raphael 83
	);
84
 
3134 delphine 85
	static function colGroupsValidation($groupe_de_champs = 'standard,avance', $programme = "") {
2461 jpm 86
		if (! $groupe_de_champs) return FALSE;
87
		if (is_string($groupe_de_champs)) {
1714 raphael 88
			$groupe_de_champs = array_flip(explode(',', $groupe_de_champs));
2461 jpm 89
		} elseif(is_array($groupe_de_champs)) {
1714 raphael 90
			$groupe_de_champs = array_flip($groupe_de_champs);
2461 jpm 91
		} else {
92
			return null;
1714 raphael 93
		}
2461 jpm 94
		$groupe_de_champs = array_intersect_key(array_flip(self::$fieldGroups), $groupe_de_champs);
95
		if (!$groupe_de_champs) {
96
			return false;
1714 raphael 97
		}
3134 delphine 98
		if ($programme != "") {
99
			$groupe_de_champs['avance'] = true;
100
			$groupe_de_champs['etendu'] = true;
101
		}
1714 raphael 102
		// toujours ajouter standard
2461 jpm 103
		$groupe_de_champs['standard'] = true;
1714 raphael 104
		return implode(',', array_keys($groupe_de_champs));
105
	}
106
 
1654 aurelien 107
	/*
108
	* @param $fieldSets: un liste de noms de colonnes ou de sets de colonnes
109
	*		séparés par des virgules
110
	* 		eg: "espece" ou "champs-etendus", ...
111
	*
112
	* @return: un tableau associatif déjà ordonné
113
	* 		clé: abbrev [machine-name] de la colonne (eg: "espece" ou "mot-clef")
114
	* 		valeur: des données relative à cette colonne, cf GenColInfo
115
	*
1757 raphael 116
	* Si la colonne n'utilise pas de fonction de récupération particulière
117
	* (ie: si le champ exportés [ou importé] correspond exactement au champ dans la base de donnée)
118
	* Alors 'abbrev' doit avoir la même valeur que le nom de la colonne dans la table mysql `cel_obs`.
1654 aurelien 119
	*/
120
	static function nomEnsembleVersListeColonnes($groupe_de_champs = 'standard') {
2461 jpm 121
		if (! $groupe_de_champs) {
122
			$groupe_de_champs = 'standard';
123
		}
124
		if (is_string($groupe_de_champs)) {
1711 raphael 125
			$groupe_de_champs = array_flip(explode(',', $groupe_de_champs));
2461 jpm 126
		} elseif(is_array($groupe_de_champs)) {
1711 raphael 127
			$groupe_de_champs = array_flip($groupe_de_champs);
2461 jpm 128
		} else {
129
			return null;
1711 raphael 130
		}
2461 jpm 131
		$groupe_de_champs = array_intersect_key(array_flip(self::$fieldGroups), $groupe_de_champs);
132
		if (!$groupe_de_champs) {
133
			return null;
1711 raphael 134
		}
135
 
2461 jpm 136
		$colonnes = array();
3134 delphine 137
		if (isset($groupe_de_champs['standardexport'])) {
1654 aurelien 138
			$colonnes += Array(
3134 delphine 139
				'guid'			=> self::GenColInfo(Array('abbrev' => 'guid',
140
																'nom' => 'Identifiant unique')),
3467 delphine 141
			    'id_observation'	=> self::GenColInfo(Array('abbrev' => 'id_observation',
142
                                            			        'nom' => 'Identifiant',
143
                                            			        'extra' => 1,
144
                                            			        'importable' => FALSE)),
1757 raphael 145
				'nom_sel'			=> self::GenColInfo(Array('abbrev' => 'nom_sel',
146
															  'nom' => 'Espèce')),
147
				'nom_sel_nn'		=> self::GenColInfo(Array('abbrev' => 'nom_sel_nn',
148
															  'nom' => 'Numéro nomenclatural',
149
															  'importable' => FALSE)),
150
				'nom_ret'			=> self::GenColInfo(Array('abbrev' => 'nom_ret',
151
															  'nom' => 'Nom retenu',
152
															  'importable' => FALSE)),
153
				'nom_ret_nn'		=> self::GenColInfo(Array('abbrev' => 'nom_ret_nn',
154
															  'nom' => 'Numéro nomenclatural nom retenu',
155
															  'importable' => FALSE)),
156
				'famille'			=> self::GenColInfo(Array('abbrev' => 'famille',
157
															  'nom' => 'Famille',
158
															  'importable' => FALSE)),
159
				'nom_referentiel'	=> self::GenColInfo(Array('abbrev' => 'nom_referentiel',
3480 delphine 160
															  'nom' => 'Référentiel taxonomique')),
3467 delphine 161
			    'certitude'			=> self::GenColInfo(Array('abbrev' => 'certitude',
162
			                                                 'nom' => 'Certitude')),
163
			    'type_donnees'		=> self::GenColInfo(Array('abbrev' => 'type_donnees',
164
			                                                 'nom' => 'Type d\'observation')),
165
			    'source'			=> self::GenColInfo(Array('abbrev' => 'source',
166
			                                                 'nom' => 'Source de la saisie')),
167
			    'spontaneite'			=> self::GenColInfo(Array('abbrev' => 'spontaneite',
168
			                                                 'nom' => 'Spontanéité')),
169
			    'latitude'			=> self::GenColInfo(Array('abbrev' => 'latitude',
170
			        'nom' => 'Latitude',
171
			        'extra' => 1)),
172
			    'longitude'			=> self::GenColInfo(Array('abbrev' => 'longitude',
173
			        'nom' => 'Longitude',
174
			        'extra' => 1)),
175
 
176
			    'geodatum'			=> self::GenColInfo(Array('abbrev' => 'geodatum',
177
			        'nom' => 'Référentiel Géographique',
178
			        'extra' => 1,
179
			        'importable' => FALSE)),
180
 
181
			    'pays'				=> self::GenColInfo(Array('abbrev' => 'pays',
2538 aurelien 182
															  'nom' => 'Pays')),
1757 raphael 183
				'zone_geo'			=> self::GenColInfo(Array('abbrev' => 'zone_geo',
184
															  'nom' => 'Commune')),
185
				'ce_zone_geo'		=> self::GenColInfo(Array('abbrev' => 'ce_zone_geo',
3467 delphine 186
															  'nom' => 'Identifiant Commune')),
187
			    'localisation_floutage'	=> self::GenColInfo(Array('abbrev' => 'localisation_floutage',
188
			                                                 'nom' => 'Floutage (niveau de localisation diffusé)')),
189
			    'altitude'			=> self::GenColInfo(Array('abbrev' => 'altitude',
190
                                        			        'nom' => 'Altitude',
191
                                        			        'extra' => 1)), // pas de trim0 car INT(5) en DB
192
			    'lieudit'			=> self::GenColInfo(Array('abbrev' => 'lieudit',
1757 raphael 193
															  'nom' => 'Lieu-dit')),
194
				'milieu'			=> self::GenColInfo(Array('abbrev' => 'milieu',
195
															  'nom' => 'Milieu')),
3467 delphine 196
			    'date_observation'	=> self::GenColInfo(Array('abbrev' => 'date_observation',
197
			                                                 'nom' => 'Date',
198
			                                                 'fonction' => 'formaterDate')),
199
			    'commentaire'		=> self::GenColInfo(Array('abbrev' => 'commentaire',
1757 raphael 200
															  'nom' => 'Notes')),
3134 delphine 201
				'programme'			=> self::GenColInfo(Array('abbrev' => 'programme',
3142 delphine 202
																'nom' => 'Programme de sciences participatives ou observatoire citoyen',
203
																'importable' => FALSE)),
204
				'mots_cles_texte'	=> self::GenColInfo(Array('abbrev' => 'mots_cles_texte',
205
																'nom' => 'Mots Clés',
206
																'importable' => FALSE)),
207
				'url_identiplante'			=> self::GenColInfo(Array('abbrev' => 'url_identiplante',
208
															'nom' => "Lien vers l'observation sur IdentiPlante",
209
															'importable' => FALSE)),
3482 delphine 210
			    'images'			=> self::GenColInfo(Array('abbrev' => 'images',
3467 delphine 211
			        'nom' => 'Image(s)',
212
			        'extra' => 1)),
213
 
214
			    );
3134 delphine 215
		} elseif (isset($groupe_de_champs['standard'])) {
216
			$colonnes += Array(
3467 delphine 217
			    'guid'			=> self::GenColInfo(Array('abbrev' => 'guid',
218
			        'nom' => 'Identifiant unique')),
219
			    'id_observation'	=> self::GenColInfo(Array('abbrev' => 'id_observation',
220
			        'nom' => 'Identifiant',
221
			        'extra' => 1,
222
			        'importable' => FALSE)),
223
			    'nom_sel'			=> self::GenColInfo(Array('abbrev' => 'nom_sel',
224
			        'nom' => 'Espèce')),
225
			    'nom_sel_nn'		=> self::GenColInfo(Array('abbrev' => 'nom_sel_nn',
226
			        'nom' => 'Numéro nomenclatural',
227
			        'importable' => FALSE)),
228
			    'nom_ret'			=> self::GenColInfo(Array('abbrev' => 'nom_ret',
229
			        'nom' => 'Nom retenu',
230
			        'importable' => FALSE)),
231
			    'nom_ret_nn'		=> self::GenColInfo(Array('abbrev' => 'nom_ret_nn',
232
			        'nom' => 'Numéro nomenclatural nom retenu',
233
			        'importable' => FALSE)),
234
			    'famille'			=> self::GenColInfo(Array('abbrev' => 'famille',
235
			        'nom' => 'Famille',
236
			        'importable' => FALSE)),
237
			    'nom_referentiel'	=> self::GenColInfo(Array('abbrev' => 'nom_referentiel',
3481 delphine 238
			        'nom' => 'Référentiel taxonomique')),
3467 delphine 239
			    'certitude'			=> self::GenColInfo(Array('abbrev' => 'certitude',
240
			        'nom' => 'Certitude')),
241
			    'type_donnees'		=> self::GenColInfo(Array('abbrev' => 'type_donnees',
242
			        'nom' => 'Type d\'observation')),
243
			    'source'			=> self::GenColInfo(Array('abbrev' => 'source',
244
			        'nom' => 'Source de la saisie')),
245
			    'spontaneite'			=> self::GenColInfo(Array('abbrev' => 'spontaneite',
246
			        'nom' => 'Spontanéité')),
247
			    'latitude'			=> self::GenColInfo(Array('abbrev' => 'latitude',
248
			        'nom' => 'Latitude',
249
			        'extra' => 1)),
250
			    'longitude'			=> self::GenColInfo(Array('abbrev' => 'longitude',
251
			        'nom' => 'Longitude',
252
			        'extra' => 1)),
253
 
254
			    'geodatum'			=> self::GenColInfo(Array('abbrev' => 'geodatum',
255
			        'nom' => 'Référentiel Géographique',
256
			        'extra' => 1,
257
			        'importable' => FALSE)),
258
 
259
			    'pays'				=> self::GenColInfo(Array('abbrev' => 'pays',
260
			        'nom' => 'Pays')),
261
			    'zone_geo'			=> self::GenColInfo(Array('abbrev' => 'zone_geo',
262
			        'nom' => 'Commune')),
263
			    'ce_zone_geo'		=> self::GenColInfo(Array('abbrev' => 'ce_zone_geo',
264
			        'nom' => 'Identifiant Commune')),
265
			    'localisation_floutage'	=> self::GenColInfo(Array('abbrev' => 'localisation_floutage',
266
			        'nom' => 'Floutage (niveau de localisation diffusé)')),
267
			    'altitude'			=> self::GenColInfo(Array('abbrev' => 'altitude',
268
			        'nom' => 'Altitude',
269
			        'extra' => 1)), // pas de trim0 car INT(5) en DB
270
			    'lieudit'			=> self::GenColInfo(Array('abbrev' => 'lieudit',
271
			        'nom' => 'Lieu-dit')),
272
			    'milieu'			=> self::GenColInfo(Array('abbrev' => 'milieu',
273
			        'nom' => 'Milieu')),
274
			    'date_observation'	=> self::GenColInfo(Array('abbrev' => 'date_observation',
275
			        'nom' => 'Date',
276
			        'fonction' => 'formaterDate')),
277
			    'commentaire'		=> self::GenColInfo(Array('abbrev' => 'commentaire',
278
			        'nom' => 'Notes')),
279
			    'programme'			=> self::GenColInfo(Array('abbrev' => 'programme',
280
			        'nom' => 'Programme de sciences participatives ou observatoire citoyen',
281
			        'importable' => FALSE)),
282
			    'mots_cles_texte'	=> self::GenColInfo(Array('abbrev' => 'mots_cles_texte',
283
			        'nom' => 'Mots Clés',
284
			        'importable' => FALSE)),
285
 
3482 delphine 286
			    'images'			=> self::GenColInfo(Array('abbrev' => 'images',
3467 delphine 287
			        'nom' => 'Image(s)',
288
			        'extra' => 1)),
289
			    'url_identiplante'			=> self::GenColInfo(Array('abbrev' => 'url_identiplante',
290
			        'nom' => "Lien vers l'observation sur IdentiPlante",
291
			        'importable' => FALSE)),
292
 
3134 delphine 293
					);
1654 aurelien 294
		}
2143 jpm 295
 
3498 delphine 296
		if (isset($groupe_de_champs['auteur'])) {
297
		    $colonnes += array(
298
		        'auteur' => self::GenColInfo(array(
299
		            'abbrev' => 'pseudo_utilisateur',
300
		            'nom' => 'Auteur',
301
		            'extra' => 1,
302
		            'fonction_data' => 'formaterUrlUser',
303
		            'importable' => false)),
304
		    );
305
		}
306
 
1654 aurelien 307
		if(isset($groupe_de_champs['avance'])) {
1656 raphael 308
			$colonnes += array(
3467 delphine 309
			    'localisation_coherence' => self::GenColInfo(Array('abbrev' => 'localisation_coherence',
310
			        'nom' => 'Cohérence entre la localité et les coordonnées GPS')),
311
			    'localisation_precision' => self::GenColInfo(Array('abbrev' => 'localisation_precision',
312
			        'nom' => 'Précision de la localisation')),
313
			    'station'			=> self::GenColInfo(Array('abbrev' => 'station',
314
			        'nom' => 'Station')),
3742 delphine 315
			    'grade'			=> self::GenColInfo(Array('abbrev' => 'grade',
316
			        'nom' => 'Indicateur de fiabilité',
317
			        'importable' => FALSE)),
3467 delphine 318
			    'validation_identiplante'			=> self::GenColInfo(Array('abbrev' => 'validation_identiplante',
319
			        'nom' => 'Détermination validée sur IdentiPlante',
320
			        'importable' => FALSE)),
321
			    'score_identiplante'			=> self::GenColInfo(Array('abbrev' => 'score_identiplante',
3497 delphine 322
			        'nom' => 'Score IdentiPlante',
3467 delphine 323
			        'importable' => FALSE)),
324
			    'abondance'			=> self::GenColInfo(Array('abbrev' => 'abondance',
325
			        'nom' => 'Abondance',
326
			        'extra' => 1)),
327
			    'phenologie'		=> self::GenColInfo(Array('abbrev' => 'phenologie',
328
			        'nom' => 'Phénologie',
329
			        'extra' => 1)),
330
			    'herbier'			=> self::GenColInfo(Array('abbrev' => 'herbier',
331
			        'nom' => 'Présence d\'un échantillon d\'herbier',
332
			        'extra' => 1)),
333
 
1757 raphael 334
				// TODO: importable = FALSE car pas de merge de données importées
335
				'date_creation'		=> self::GenColInfo(Array('abbrev' => 'date_creation',
336
															  'nom' => 'Date Création',
337
															  'extra' => 1,
338
															  'importable' => FALSE)),
339
				'date_modification'	=> self::GenColInfo(Array('abbrev' => 'date_modification',
340
															  'nom' => 'Date Modification',
341
															  'extra' => 1,
342
															  'importable' => FALSE)),
1656 raphael 343
 
1757 raphael 344
				// rappel transmission = 1, signifie simplement "public"
345
				// des données importées peuvent être d'emblée "publiques"
346
				// "importable" = TRUE
347
				'transmission'		=> self::GenColInfo(Array('abbrev' => 'transmission',
348
															  'nom' => 'Transmis',
349
															  'extra' => 1,
350
															  'fonction' => 'boolOuiNon')),
351
				'date_transmission'	=> self::GenColInfo(Array('abbrev' => 'date_transmission',
352
															  'nom' => 'Date Transmission',
353
															  'extra' => 1,
354
															  'importable' => FALSE)),
3497 delphine 355
			    'observateur'		=> self::GenColInfo(Array('abbrev' => 'observateur',
356
                                            			        'nom' => 'Observateur',
357
                                            			        'extra' => 1)),
358
			    'observateur_structure'	=> self::GenColInfo(Array('abbrev' => 'observateur_structure',
359
                                            			        'nom' => 'Structure de l\'observateur',
360
                                            			        'extra' => 1)),
361
			    'determinateur'		=> self::GenColInfo(Array('abbrev' => 'determinateur',
362
                                            			        'nom' => 'Déterminateur',
363
                                            			        'extra' => 1)),
364
			    'biblio'	=> self::GenColInfo(Array('abbrev' => 'biblio',
365
                                            			        'nom' => 'Source bibliographique',
366
                                            			        'extra' => 1)),
2143 jpm 367
 
1656 raphael 368
 
1757 raphael 369
				/* 'nom_commun'			=> self::GenColInfo(Array('abbrev' => 'nom_commun',
370
				   'nom' => 'Nom Commun',
371
				   'extra' => 1,
372
				   'fonction_data' => 'getNomCommun',
373
				   'importable' => FALSE),
1685 raphael 374
 
1757 raphael 375
				   'nom-commun'			=> self::GenColInfo(Array('abbrev' => 'nom-commun',
376
				   'nom' => 'Nom Commun',
377
				   'extra' => 1,
378
				   'fonction_data' => 'getNomCommun_v2'),
379
 
380
				   'nom-commun'			=> self::GenColInfo(Array('abbrev' => 'nom-commun',
381
				   'nom' => 'Nom Commun',
382
				   'extra' => 1,
383
				   'fonction_data' => 'getNomCommun_v3'),
3467 delphine 384
				   'importable' => FALSE), */ /* cas particu 'getNomCommun_v4' */
385
				/*'nom-commun' => self::GenColInfo(array(
2461 jpm 386
					'abbrev' => 'nom-commun',
387
					'nom' => 'Nom Commun',
388
					'extra' => 1,
3467 delphine 389
					'fonction_data' => null ,
390
					'preload' => array(__CLASS__, 'getNomCommun_preload')))*/
1702 raphael 391
			);
392
		}
1685 raphael 393
 
3498 delphine 394
		if (isset($groupe_de_champs['etendu'])) {
395
		    $colonnes += array(
396
		        // champ dynamique
397
		        'etendu' => self::GenColInfo(array(
398
		            'abbrev' => 'etendu',
399
		            'nom' => '',
400
		            'extra' => 1,
401
		            'importable' => false,
402
		            'preload' => array(__CLASS__, 'champsEtendus_preload'),
403
		            'dyna' => array(__CLASS__, 'champsEtendus_ligne'))),
404
		    );
405
		}
406
 
1702 raphael 407
		if(isset($groupe_de_champs['baseflor'])) {
408
			$colonnes += array(
409
				// champ dynamique
2461 jpm 410
				'baseflor' => self::GenColInfo(array(
411
					'abbrev' => 'baseflor',
412
					'nom' => '',
413
					'extra' => 1,
414
					'importable' => false,
415
					'preload' => array(__CLASS__, 'baseflor_preload'),
416
					'dyna' => array(__CLASS__, 'baseflor_ligne'))),
1654 aurelien 417
			);
1702 raphael 418
		}
1656 raphael 419
 
3498 delphine 420
 
1835 raphael 421
 
3498 delphine 422
 
1654 aurelien 423
		return $colonnes;
424
	}
1694 raphael 425
 
426
	static function preload($colonnes, $cel, $ids) {
427
		$result = array();
2461 jpm 428
		foreach ($colonnes as $abbrev => $colonne) {
429
			if (!$colonne['preload']) {
430
				continue;
431
			}
1702 raphael 432
			$result[$abbrev] = call_user_func($colonne['preload'], $cel, $ids);
1694 raphael 433
		}
434
		return $result;
435
	}
2143 jpm 436
 
1656 raphael 437
	public static function getIntitulesColonnes($colonnes) {
1702 raphael 438
		// array_filter pour supprimer les colonnes "dynamique" n'ayant pas défini $nom (cf GenColInfo())
439
		return array_filter(array_map(array('FormateurGroupeColonne', 'retournerNomItem'), $colonnes));
1654 aurelien 440
	}
2143 jpm 441
 
1671 aurelien 442
	public static function retournerNomItem(&$item) {
443
		return $item['nom'];
444
	}
1694 raphael 445
 
1656 raphael 446
	public static function getLigneObservation(&$obs, &$colonnes, $cel = false) {
1654 aurelien 447
		$ligne_formatee = array();
448
		foreach($colonnes as $abbrev => $colonne) {
449
			$valeur = null;
2461 jpm 450
			if ($colonne['extra'] == 2 || ! is_null($colonne['dyna'])) {
451
				continue;
452
			}
2143 jpm 453
 
1835 raphael 454
			// valeur directe depuis cel_obs ?
2461 jpm 455
			if (isset($obs[$abbrev])) {
456
				$valeur = $obs[$abbrev];
457
			}
2143 jpm 458
 
1835 raphael 459
			// pré-processeur des champs
2461 jpm 460
			if (function_exists($colonne['fonction'])) {
1654 aurelien 461
				$valeur = $colonne['fonction']($valeur);
2461 jpm 462
			} else if(method_exists(__CLASS__, $colonne['fonction'])) {
1654 aurelien 463
				$valeur = call_user_func(array(__CLASS__, $colonne['fonction']), $valeur);
2461 jpm 464
			} else if($colonne['fonction']) {
1654 aurelien 465
				die("méthode {$colonne['fonction']} introuvable");
2461 jpm 466
			} else if(function_exists($colonne['fonction_data'])) {// fonction pour obtenir des champs (étendus)
1654 aurelien 467
				$valeur = $colonne['fonction_data']($obs);
2461 jpm 468
			} else if(method_exists(__CLASS__, $colonne['fonction_data'])) {
1654 aurelien 469
				$valeur = call_user_func(array(__CLASS__, $colonne['fonction_data']), $obs);
470
			}
2143 jpm 471
 
3467 delphine 472
 
1765 raphael 473
			// ici à cause du passage de $cel ($this->utilisateur)
3467 delphine 474
 
2461 jpm 475
			if ($abbrev == 'nom-commun') {
1765 raphael 476
				$valeur = FormateurGroupeColonne::getNomCommun_v4($obs);
1685 raphael 477
			}
2143 jpm 478
 
2461 jpm 479
			if ($valeur == null) {
480
				$valeur = '';
1654 aurelien 481
			}
2143 jpm 482
 
2461 jpm 483
			// fin de section "cas particuliers"
1654 aurelien 484
			$ligne_formatee[] = $valeur;
485
		}
1694 raphael 486
 
1835 raphael 487
		// uniquement les champs dynamiques
1702 raphael 488
		foreach($colonnes as $abbrev => $colonne) {
489
			$valeur = null;
2461 jpm 490
			if (is_null($colonne['dyna'])) {
491
				continue;
492
			}
493
			call_user_func_array($colonne['dyna'], array($obs, &$ligne_formatee));
1702 raphael 494
		}
1654 aurelien 495
		return $ligne_formatee;
496
	}
2143 jpm 497
 
1654 aurelien 498
	/*
499
	* Wrapper générant un tableau associatif:
1694 raphael 500
	* Ne pas changer les valeurs par défaut du prototype sans réflexion sur l'implication pour nomEnsembleVersListeColonnes()
2143 jpm 501
 
1654 aurelien 502
	* @param $abbrev (obligatoire): nom court de colonne, largement utilisé lors de l'import.
503
	*		  En effet chaque ligne importée est accessible à l'aide du `define` de $abbrev en majuscule, préfixé de "C_"
504
	*		  Exemple: $ligne[C_LONGITUDE] pour "longitude".
505
	*		  cf: ImportXLS::detectionEntete()
2143 jpm 506
 
1654 aurelien 507
	* @param $nom (obligatoire): nom complet de colonne (utilisé pour la ligne d'en-tête)
1702 raphael 508
	*		  Les définition de champs dynamique (correspondant à de multiples colonnes) doivent laisser cette valeur
509
	*		  vide afin de ne pas créer une colonne supplémentaire erronée.
2143 jpm 510
 
1654 aurelien 511
	* @param $is_extra:
512
	* Si 0, la colonne est une colonne standard
513
	* Si 1, la colonne est extra [le plus souvent générée automatiquement]
514
	*		 (auquel cas une bordure bleue entoure son nom dans la ligne d'entête)
515
	* Si 2, la colonne n'est pas traité à l'export, mais une définition peut lui être donnée
516
	*		 qui pourra être utilisée à l'import, exemple: "image"
2143 jpm 517
 
1654 aurelien 518
	* @param $fonction (optionnel): un nom d'un fonction de préprocessing
519
	* 		  $fonction doit prendre comme seul argument la valeur d'origine et retourner la valeur transformée
2143 jpm 520
 
1654 aurelien 521
	* @param $fonction_data (optionnel): une *méthode* d'obtention de donnée
522
	* 		  $fonction_data doit prendre comme premier argument le tableau des champs de l'enregistrement existant
523
	*		  $fonction_data doit retourner une valeur
2143 jpm 524
 
1654 aurelien 525
	* @param $importable (optionnel): défini si la colonne est traitée (ou absolument ignorée par PHPExcel) lors de
526
	*		  l'import.
1694 raphael 527
 
528
	* @param $preload (optionnel): défini une fonction de préchargement massif de donnée potentiellement utilisable par $fonction_data.
529
	*		  Utile, notamment, dans le cadre de l'export
1702 raphael 530
 
531
	* @param $fonction_dynamique (optionnel): défini une fonction ajoutant un nombre arbitraire de colonnes à une ligne donnée
532
	*		  Utile, notamment, dans le cadre de l'export des champs étendus ou des données baseflor
533
	*		  La fonction doit TOUJOURS alterer la ligne en lui ajoutant une nombre CONSTANT d'éléments (NULL ou non)
1765 raphael 534
	*		  La fonction doit prendre comme arguments ($obs, &$ligne_formatee)
1654 aurelien 535
	*/
1757 raphael 536
	static function GenColInfo($args) {
2461 jpm 537
		$default = array(
538
			'abbrev' => null,
539
			'nom' => null,
540
			'extra' => 0,
541
			'fonction' => null,
542
			'fonction_data' => null,
543
			'importable' => true,
544
			'preload' => null,
545
			'dyna' => null);
1757 raphael 546
		$ret = array_intersect_key($args, $default);
547
		return array_merge($default, $ret);
1654 aurelien 548
	}
2143 jpm 549
 
1656 raphael 550
	static function formaterDate($date_heure_mysql) {
1671 aurelien 551
		//return "";
2461 jpm 552
		if (!$date_heure_mysql || $date_heure_mysql == "0000-00-00 00:00:00") {
553
			return null;
554
		}
1671 aurelien 555
		// malheureusement pas disponible en php < 5.3
556
		//$date_format = DateTime::createFromFormat("Y-m-d H:i:s", $date_heure_mysql);
557
		$val = explode(' ', $date_heure_mysql);
558
		$date = explode('-', $val[0]);
559
		$heure = explode(':', $val[1]);
560
		$timestamp = mktime((int) $heure[0], (int) $heure[1], (int) $heure[2], (int) $date[1], (int) $date[2], (int) $date[0]);
2461 jpm 561
		if (!$timestamp) {
562
			return null;
563
		}
1656 raphael 564
		// TODO: les widgets ne font malheureusement pas usage de l'heure dans le CEL
565
		// TODO: si modification, ne pas oublier de modifier le format d'import correspondant
1698 raphael 566
		//	dans ImportXLS, traiterDateObs() (actuellement: "Y/m/d" car utilisation de strtotime() qui ne lit pas tout)
567
		// $date_formatee = strftime('%d/%m/%Y', $timestamp);
568
		$date_formatee = strftime('%Y/%m/%d', $timestamp);
2461 jpm 569
		if (!$date_formatee) {
570
			return '00/00/0000';
571
		}
1654 aurelien 572
		return $date_formatee;
573
	}
1757 raphael 574
 
1835 raphael 575
 
1759 raphael 576
 
577
 
2143 jpm 578
 
2730 mathias 579
	/**
580
	 * Enlève les zéros excédentaires (devenus nomades) au début et à la fin d'une
581
	 * latitude ou longitude, en prenant garde à ne pas foirer les nombres 0.xyz
582
	 */
1757 raphael 583
	public static function trim0($lonlat) {
2730 mathias 584
		$retour = trim($lonlat, "0");
585
		// si on a trop enlevé de zéros à gauche, on en remet un (mode synthobois)
586
		if (substr($retour, 0, 1) == ".") {
587
			$retour = "0" . $retour;
588
		}
589
		return $retour;
1757 raphael 590
	}
591
 
592
	public static function boolOuiNon($transmission) {
593
		return $transmission ? 'oui' : '';
594
	}
2143 jpm 595
 
3497 delphine 596
	static function formaterUrlUser($obs) {
597
	    $is_id = is_numeric($obs['ce_utilisateur']);
598
	    return sprintf("%s %s",
599
	        $obs['pseudo_utilisateur'],
600
	        $is_id ? sprintf(' (' . USER_BASEURL . ')', $obs['ce_utilisateur']) : '');
601
	}
2143 jpm 602
 
1654 aurelien 603
	// TODO: référentiel ne devrait pas être généré au moment d'un Config::get,
604
	// comme dans Config::get('nomsVernaRechercheLimiteeTpl')
605
	// Par exemple, la variable pour "nva" ?
606
	function getNomCommun($obs) {
607
		$langue = 'fra';
608
		list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
609
		if($referentiel == 'bdtfx') $referentiel = 'nvjfl';
610
		else return '';
2143 jpm 611
 
1654 aurelien 612
		$cache_id = $referentiel . '-' . $obs['nt'] . '-' . $langue;
1657 raphael 613
		if(isset(self::$cache['getNomCommun'][$cache_id])) {
1656 raphael 614
			//debug: error_log("require url_service_nom_attribution: OK ! (pour \"{$obs['nom_ret']}\")");
1657 raphael 615
			return self::$cache['getNomCommun'][$cache_id];
1654 aurelien 616
		}
617
		// pas de cache:
618
		//debug: error_log("require url_service_nom_attribution pour \"{$obs['nom_ret']}\"");
2143 jpm 619
 
1654 aurelien 620
		// pour bdtfx:
621
		// /service:eflore:0.1/nvjfl/noms-vernaculaires/attributions?masque.nt=X&masque.lg=fra&retour.champs=num_statut
622
		// /projet/services/modules/0.1/nvjfl/NomsVernaculaires.php
623
		$url = str_replace(Array('{referentiel}', '{valeur}', '{langue}'),
1656 raphael 624
						   Array($referentiel, $obs['nt'], $langue),
1657 raphael 625
						   self::$config['eflore']['url_service_nom_attribution']) . // TODO !
1656 raphael 626
			"&retour.champs=num_statut";
1654 aurelien 627
		$noms = @json_decode(file_get_contents($url));
628
		if(! $noms) return '';
1673 raphael 629
		$noms = array_filter((array)($noms->resultat), array($this, retournerNumStatutUn)); // XXX: php 5.3
1654 aurelien 630
		$nom = array_pop($noms)->nom_vernaculaire;
2143 jpm 631
 
1654 aurelien 632
		// cache
1657 raphael 633
		self::$cache['getNomCommun'][$cache_id] = $nom;
1654 aurelien 634
		return $nom;
635
	}
2143 jpm 636
 
1671 aurelien 637
	private function retournerNumStatutUn(&$item) {
638
		return ($item->num_statut == 1);
639
	}
1673 raphael 640
 
641
	private function retournerNumStatutUnArr(&$item) {
642
		return ($item['num_statut'] == 1);
643
	}
2143 jpm 644
 
1656 raphael 645
	// si getNomCommun_v2 ou getNomCommun_v3 sont utilisés
646
	/* require_once('/home/raphael/eflore/framework/framework/Framework.php');
647
	Framework::setCheminAppli("/home/raphael/eflore/projets/services/index.php");
648
	Framework::setInfoAppli(Config::get('info'));
649
	require_once('/home/raphael/eflore/projets/services/modules/0.1/Projets.php');*/
2143 jpm 650
 
1654 aurelien 651
	/* Tente de bootstraper le framework au plus court et d'initialiser une instance de
1656 raphael 652
	   NomsVernaculaires pour obtenir le nom commun */
1654 aurelien 653
	function getNomCommun_v2($obs) {
654
		static $service;
1656 raphael 655
		$service = new Projets();
2143 jpm 656
 
1654 aurelien 657
		$langue = 'fra';
658
		list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
659
		if($referentiel == 'bdtfx') $referentiel = 'nvjfl';
660
		else return '';
2143 jpm 661
 
1654 aurelien 662
		$cache_id = $referentiel . '-' . $obs['nt'] . '-' . $langue;
1657 raphael 663
		if(isset(self::$cache['getNomCommun'][$cache_id])) {
1656 raphael 664
			error_log("require NomsVernaculaires.php: OK ! (pour \"{$obs['nom_ret']}\")");
1657 raphael 665
			return self::$cache['getNomCommun'][$cache_id];
1654 aurelien 666
		}
667
		// pas de cache:
668
		error_log("require NomsVernaculaires.php pour \"{$obs['nom_ret']}\"");
2143 jpm 669
 
1656 raphael 670
		$donnees = Array('masque.nt' => $obs['nt'],
671
						 'masque.lg' => $langue,
672
						 'retour.champs' => 'num_statut');
1654 aurelien 673
		$noms = $service->consulter(Array('nvjfl', 'noms-vernaculaires'), $donnees);
2143 jpm 674
 
1654 aurelien 675
		if(! $noms) return '';
1673 raphael 676
		$noms = array_filter((array)($noms->resultat), array($this, retournerNumStatutUn)); // XXX: php 5.3
1654 aurelien 677
		$nom = array_pop($noms)->nom_vernaculaire;
2143 jpm 678
 
1656 raphael 679
		// cache
1657 raphael 680
		self::$cache['getNomCommun'][$cache_id] = $nom;
1654 aurelien 681
		return $nom;
682
	}
2143 jpm 683
 
684
 
1654 aurelien 685
	/* Effectue un bootstraping plus sage que ci-dessus, mais le gain d'efficacité
1656 raphael 686
	   n'est pas aussi retentissant qu'espéré */
1654 aurelien 687
	static $service;
688
	function getNomCommun_v3($obs) {
689
		if(! $this->service) $this->service = new Projets();
2143 jpm 690
 
1654 aurelien 691
		$langue = 'fra';
692
		list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
693
		if($referentiel == 'bdtfx') $referentiel = 'nvjfl';
694
		else return '';
2143 jpm 695
 
1654 aurelien 696
		$cache_id = $referentiel . '-' . $obs['nt'] . '-' . $langue;
1657 raphael 697
		if(isset(self::$cache['getNomCommun'][$cache_id])) {
1656 raphael 698
			error_log("require NomsVernaculaires.php: OK ! (pour \"{$obs['nom_ret']}\")");
1657 raphael 699
			return self::$cache['getNomCommun'][$cache_id];
1654 aurelien 700
		}
701
		// pas de cache:
1656 raphael 702
		error_log("require NomsVernaculaires.php pour \"{$obs['nom_ret']}\"");
2143 jpm 703
 
1654 aurelien 704
		$donnees = Array('masque.nt' => $obs['nt'],
1656 raphael 705
						 'masque.lg' => $langue,
706
						 'retour.champs' => 'conseil_emploi');
707
		$this->service->initialiserRessourcesEtParametres(Array('nvjfl', 'noms-vernaculaires', 'attributions'), $donnees);
1654 aurelien 708
		try {
1656 raphael 709
			$noms = $this->service->traiterRessources();
2143 jpm 710
		} catch(Exception $e) {
1656 raphael 711
			return '';
1654 aurelien 712
		}
1656 raphael 713
		if(! $noms) return '';
1673 raphael 714
		$noms = array_filter($noms['resultat'], array($this, retournerNumStatutUnArr)); // XXX: php 5.3
1656 raphael 715
		$premier_nom = array_pop($noms);
1654 aurelien 716
		$nom = $premier_nom['nom_vernaculaire'];
2143 jpm 717
 
1654 aurelien 718
		// cache
1657 raphael 719
		self::$cache['getNomCommun'][$cache_id] = $nom;
1654 aurelien 720
		return $nom;
721
	}
1685 raphael 722
 
1694 raphael 723
 
1702 raphael 724
 
2143 jpm 725
 
3467 delphine 726
 
1765 raphael 727
	static function getNomCommun_v4($obs) {
2446 jpm 728
		// Attention la fonction suppose que l'on ait fait appel à getNomCommun_preload avant
2281 aurelien 729
		// d'être appelée
1685 raphael 730
		if(! $obs['nt']) return NULL;
1765 raphael 731
		if(! self::referenceTableExiste()) return NULL;
1689 raphael 732
 
1685 raphael 733
		$langue = 'fra';
734
		list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
735
		$cache_id = $referentiel . '-' . $obs['nt'] . '-' . $langue;
736
 
2281 aurelien 737
		$nom = null;
1757 raphael 738
		// cache:
2281 aurelien 739
		if(isset(self::$cache['getNomCommun'])) {
1757 raphael 740
			if(isset(self::$cache['getNomCommun'][$cache_id])) return self::$cache['getNomCommun'][$cache_id];
741
			// XXX: problème de valeurs NULL ?
2281 aurelien 742
			if(array_key_exists($cache_id, self::$cache['getNomCommun'])) {
743
				$nom = self::$cache['getNomCommun'][$cache_id];
744
			}
1757 raphael 745
		}
1685 raphael 746
 
747
		return $nom;
748
	}
1702 raphael 749
 
750
 
751
	/* Cette fonction initialise le cache des données baseflor en 1 fois, sur la liste des observations à exporter.
752
	   Ainsi, les appels successifs à baseflor_ligne() ne sont pas couteux (pas de requête SQL) */
753
	static function baseflor_preload($cel, $obsids) {
754
		if(!$obsids) return;
1765 raphael 755
		if(!self::referenceTableExiste()) return NULL;
1702 raphael 756
 
2254 aurelien 757
		// Attention (en attendant de faire une meilleure table et une meilleure requete) le distinct est très important
758
		$req = sprintf("SELECT DISTINCT referentiel, num_nom_retenu, %s FROM cel_references r" .
2297 mathias 759
						" INNER JOIN cel_obs c ON (r.num_nom_retenu = c.nom_ret_nn)" .
760
						" AND r.referentiel = IF(LOCATE(':', c.nom_referentiel) = 0, c.nom_referentiel, SUBSTR(c.nom_referentiel FROM 1 FOR LOCATE(':', c.nom_referentiel) - 1))" .
761
						" WHERE c.id_observation IN (%s)",
762
						//" AND catminat_code IS NOT NULL", // TODO: suppression des NULL ici signifie que le cache sera partiel...
763
						implode(',', array_keys(self::$baseflor_col)),
764
						implode(',', $obsids));
1765 raphael 765
		$res = Cel::db()->requeter($req);
1706 raphael 766
		if(!$res) return NULL;
1702 raphael 767
 
768
		foreach($res as $v) {
769
			$data = $v;
770
			unset($data['referentiel']); // non nécessaire
771
			unset($data['num_nom_retenu']); // non nécessaire
2446 jpm 772
 
2244 aurelien 773
			// Des fois les synonymes ont des valeurs pour baseflor et pas le nom retenu et vice versa
2446 jpm 774
			// on les fusionne pour avoir le maximum d'infos, en attendant de repenser la table référence
2244 aurelien 775
			if(isset(self::$cache['getBaseflor'][$v['referentiel'] . '-' . $v['num_nom_retenu']])) {
2446 jpm 776
				$orig  = array_filter(self::$cache['getBaseflor'][$v['referentiel'] . '-' . $v['num_nom_retenu']], 'strlen');
777
				$data  = array_filter($data , 'strlen');
2244 aurelien 778
				$data = array_merge($orig, $data);
779
			}
2446 jpm 780
 
1702 raphael 781
			self::$cache['getBaseflor'][$v['referentiel'] . '-' . $v['num_nom_retenu']] = $data;
782
		}
783
 
784
		return NULL;
785
	}
1685 raphael 786
 
2446 jpm 787
	/**
2312 mathias 788
	 * Attention la fonction suppose que l'on ait fait appel à baseflor_preload avant
789
	 * d'être appelée
790
	 * @CASSECOUILLES elle pourrait le détecter et le faire elle-même
791
	 */
1765 raphael 792
	static function baseflor_ligne($obs, &$ligne) {
2312 mathias 793
		$clefsBF = array_keys(self::$baseflor_col);
794
		// par défaut des colonnes vides pour ne pas décaler le bousin
795
		$donneesBF = array_fill_keys($clefsBF, "");
1702 raphael 796
 
2312 mathias 797
		// s'il y a des données baseflor
798
		if ($obs['nom_ret_nn'] && self::referenceTableExiste() && count(self::$cache['getBaseflor']) > 0) {
799
			// l'astuce à un franc vingt
800
			list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
801
			$cache_id = $referentiel . '-' . $obs['nom_ret_nn'];
1702 raphael 802
 
2312 mathias 803
			// si les données baseflor existent dans le cache pour ce nom_ret_nn
804
			if (array_key_exists($cache_id, self::$cache['getBaseflor'])) {
805
				$donneesBFATrous = self::$cache['getBaseflor'][$cache_id];
806
				foreach($clefsBF as $colbf) { // remplit les trous tout en préservant l'ordre
807
					if(array_key_exists($colbf, $donneesBFATrous)) {
808
						$donneesBF[$colbf] = $donneesBFATrous[$colbf];
809
					} else {
810
						$donneesBF[$colbf] = "";
811
					}
812
				}
813
			}
1702 raphael 814
		}
2312 mathias 815
 
816
		// Quand les données sont prêtes, on les fusionne
817
		$ligne = array_merge($ligne, $donneesBF);
1702 raphael 818
	}
2446 jpm 819
 
1715 raphael 820
	static function champsEtendus_preload($cel, $obsids) {
3478 delphine 821
		// obs étendues
822
	    $gestion_obs_etendus = new GestionChampsEtendus($cel->config);
823
	    // champs étendus
3479 delphine 824
	    $gestion_champs_etendus = new GestionChampsEtendus2($cel->config);
3478 delphine 825
		$colonnes_champs_supp_par_obs = $gestion_obs_etendus->consulterClesParLots($obsids);
2446 jpm 826
 
827
		// Supprime les champs étendus considérés comme privés dans le cas de l'export public en chargeant
2403 aurelien 828
		// le catalogue et en excluant ceux qui sont explicitement privés
829
		if(!$cel->export_prive) {
830
			$indices_a_supprimer = array();
831
			$catalogue_champs_etendus = $gestion_champs_etendus->consulterCatalogueChampsEtendusPredefinis();
832
			foreach($catalogue_champs_etendus as $champ_catalogue) {
833
				if($champ_catalogue['options']['prive'] == 1) {
2446 jpm 834
					// Les champs étendus peuvent avoir des variantes lorsqu'ils apparaissent de multiples fois.
2407 aurelien 835
					// Vont donc matcher monChamp mais aussi monChamp:1, monChamp:2 ou bien monChamp1, monChamp: etc...
836
					// pour plus de sécurité (ce filtra n'est affectué qu'une fois au début de l'export donc on ne s'en prive pas)
837
					$entrees = preg_grep("/".$champ_catalogue['cle']."(?::?\d*)?$/", $colonnes_champs_supp_par_obs);
2403 aurelien 838
					$indices_a_supprimer = array_merge($indices_a_supprimer, array_keys($entrees));
839
				}
840
			}
841
			// les champs étendus sont renvoyés dans l'export suivant les colonnes présentes dans ce tableau
842
			// les éliminer de la liste des colonnes suffit à les faire ignorer par l'export
2446 jpm 843
			foreach($indices_a_supprimer as $indice_supp) {
844
				unset($colonnes_champs_supp_par_obs[$indice_supp]);
2403 aurelien 845
			}
846
		}
2446 jpm 847
 
1741 raphael 848
		// ces deux lignes réordonnent l'ordre des colonnes des champs étendus en fonction de l'ordre (très spécifique)
849
		// de self::$ordre_champ_etendus_Florileges, les champs non-mentionnés sont ajoutés à la fin.
850
		$colonnes_champs_supp_par_obs = self::sortArrayByArray(array_flip($colonnes_champs_supp_par_obs),
851
															   self::$ordre_champ_etendus_Florileges);
852
		$colonnes_champs_supp_par_obs = array_keys($colonnes_champs_supp_par_obs);
853
 
1718 raphael 854
		// si le SELECT des clefs ne retourne rien, une autre requêtes est inutile
855
		// TODO: optimize, 1 seule requête
856
		if(!$colonnes_champs_supp_par_obs) return Array('header' => array(), 'data' => array());
857
 
3478 delphine 858
		$champs_supp_par_obs = $gestion_obs_etendus->consulterParLots($obsids);
1741 raphael 859
 
1791 raphael 860
		self::$cache['champsEtendus']['header'] = self::champsEtendus_prefixHeader($colonnes_champs_supp_par_obs);
861
 
1715 raphael 862
		foreach($champs_supp_par_obs as &$v) {
863
			$v = self::champsEtendus_aplatir($v);
864
		}
865
		self::$cache['champsEtendus']['data'] = $champs_supp_par_obs;
866
		// ce return est temporaire,
867
		// le temps que toutes les fonctions bougent ici et utilise plutôt le cache statique
1716 raphael 868
		// encore utilisé pour les entêtes (self::$cache['champsEtendus']['header'])
1715 raphael 869
		return self::$cache['champsEtendus'];
870
	}
871
 
872
	// XXX: PHP-5.3, fonction anonyme + array_map
1791 raphael 873
	static function champsEtendus_prefixHeader($array) {
874
		return array_map(create_function('$v', 'return "' . PREFIX_CHAMPS_ETENDUS . '".$v;'), $array);
875
	}
876
 
877
	// XXX: PHP-5.3, fonction anonyme + array_map
1715 raphael 878
	static function champsEtendus_aplatir($ligne_champs_etendus) {
879
		$champs_etendus_fmt = array();
880
		if(!$ligne_champs_etendus) return $champs_etendus_fmt;
881
		foreach($ligne_champs_etendus as $champ) {
1791 raphael 882
			$champs_etendus_fmt[PREFIX_CHAMPS_ETENDUS . $champ->cle] = $champ->valeur;
1715 raphael 883
		}
884
		return $champs_etendus_fmt;
885
	}
1716 raphael 886
 
1765 raphael 887
	static function champsEtendus_ligne($obs, &$ligne) {
1716 raphael 888
		// si header n'est pas défini, aucune observation ne possède de champ étendu
889
		// et nous n'ajoutons ni colonnes, ni valeurs.
890
		if(! isset(self::$cache['champsEtendus']['header'])) return;
1736 raphael 891
		$ligne_etendue_aplatie = @self::$cache['champsEtendus']['data'][$obs['id_observation']];
1716 raphael 892
 
893
		$ligne_supp = array_fill(0, count(self::$cache['champsEtendus']['header']), '');
894
		$ligne_etendue_fmt = array();
895
 
896
		// si, cependant cette seule observation n'a pas de champs étendus,
897
		// nous devons rajouter des blancs (notamment dans le cas ou d'autres
898
		// champs viennent à être ajoutés en aval à l'avenir
899
		// cf: $fonction_dynamique dans FormateurGroupeColonne::GenColInfo()
900
		if(! $ligne_etendue_aplatie) {
901
			$ligne = array_merge($ligne, $ligne_supp);
902
			return;
903
		}
904
 
905
		foreach(self::$cache['champsEtendus']['header'] as $colonne) {
906
			if(!isset($ligne_etendue_aplatie[$colonne])) {
2143 jpm 907
				$ligne_etendue_fmt[$colonne] = '';
1716 raphael 908
			} else {
909
				$ligne_etendue_fmt[$colonne] = $ligne_etendue_aplatie[$colonne];
910
			}
911
		}
912
 
913
		// XXX/ array_merge() ?
914
		$ligne += $ligne_etendue_fmt;
915
	}
1741 raphael 916
 
917
	/* HELPERS */
918
 
919
	// http://stackoverflow.com/questions/348410/sort-an-array-based-on-another-array
920
	// XXX; redéfinition, utilisé aussi par ExportXLS
921
	static function sortArrayByArray($array, $orderArray) {
922
		$ordered = array();
923
		foreach($orderArray as $key) {
924
			if(array_key_exists($key, $array)) {
925
				$ordered[$key] = $array[$key];
926
				unset($array[$key]);
927
			}
928
		}
929
		return $ordered + $array;
930
	}
2461 jpm 931
}