Subversion Repositories eFlore/Applications.cel

Rev

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