Subversion Repositories eFlore/Applications.cel

Rev

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